CAN Paket Daten als einzelene Variable separieren?

Hallo,
Für einen Freund beschäftige ich mich mit einem Projekt in welchem unter anderem
CAN zum EInsatz kommen soll.

Ich habe 2 ESP32 mit CAN über Transceiver verbunden.

Das funktioniert so weit gut.
Davor hatte ich it I²C probiert und war auch ok.
Leider kann ich meine Kenntnisse vom I²C nicht auf den CAN anwenden.

Um was geht es:

Der CAN "Sender" sendet 5 Int Werte

#include <CAN.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("CAN Sender");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}

int  Wert1 = 110;
int  Wert2 = 120;
int  Wert3 = 130;
int  Wert4 = 140;
int  Wert5 = 150;

void loop() {
  
  Serial.println("------------> Senden ------------>");

  CAN.beginPacket(0x12);
  
  CAN.write (Wert1);
  CAN.write (Wert2);
  CAN.write (Wert3);
  CAN.write (Wert4);
  CAN.write (Wert5);
  
  CAN.endPacket();
  
  delay(1000);
  Serial.println(" fertig");


  // send extended packet: id is 29 bits, packet can contain up to 8 bytes of data
  // Serial.print("Sending extended packet ... ");

  // CAN.beginExtendedPacket(0xabcdef);
  // CAN.write('W');
  // CAN.write('o');
  // CAN.write('r');
  // CAN.write('l');
  // CAN.write('d');
  // CAN.endPacket();

  // Serial.println("fertig");
  delay(1000);

Der Empänger bekommt die 5 Werte im Paket und gibt sie hintereinader aus.

#include <CAN.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("CAN Receiver");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}

void loop() {

  int packetSize = CAN.parsePacket();

  if (packetSize) {
 
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
 
      Serial.print("RTR ");
    }

    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);

    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(packetSize);


      while (CAN.available()) {
        Serial.print((int)CAN.read());
      }
      Serial.println();
    }

    Serial.println();
  }
}

Ergebniss im SerialMonitor:
Received packet with id 0x12 and length 5
110120130140150

Nun habe ich viel probiert, mit Array , Schleifen und muss leider passen.
Meine Frage ist, wie bekomme nich diese 5 Werrte nun als einzelne INT Variblen aus
dem Paket ?

Viel probiert, gegoogelt, leider erfolglos bis jetzt.
Damals beim I² hatte ich mit Array gesendet und empfangen, aber jetzt ist der CAN im Stack ( SJA1000 und ich weis nicht wie ich die Zahlen, wieder einzelen verarbeitbar machen könnte.

Vielleicht habt ihr eine gute Idee ?
Beste Grüsse
Rainer

Hast Du stattdessen schon wert[j] = CAN.read()); probiert?

wie meinst du das ?
warum das [j] in Klammer ?
Stehe bischen auf demSchlauch ?
Wi e soll ich aus der zusammenhängen Zeile die einzelnen Werte rausfiltern ?
das muss doch noch was zum [j] fehlen , oder ?
Grüsse

Wenn ich es richtig verstehe, müßte CAN.read() einmal je Wert, also fünf Mal ausgeführt werden. Erster Wert wert[0] = CAN.read());, zweiter Wert wert[1] = CAN.read()); usw. also in einer Schleife mit j als Index des Feldes.

Ich habe eine andere Bibliothek verwendet und derzeit keinen Testaufbau. Probiere es mal aus.

Ich glaube agmue meint sowas:

void loop()
{
  int wert[10] = 0;
  static int zaehler = 0;
  int packetSize = CAN.parsePacket();
  if (packetSize)
  {
    Serial.print("Received ");
    if (CAN.packetExtended())
    {
      Serial.print("extended ");
    }
    if (CAN.packetRtr())
    {
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);
      while (CAN.available())
      {
        wert[zaehler] = (int)CAN.read());
        zaehler++;
      }
    }
  }
  Serial.print(F("Zaehlerstand: "));
  Serial.println(zaehler);
  for (unsigned int i = 0; i <= zaehler; i++)
  {
    Serial.print(F("Wert"));
    Serial.print(i);
    Serial.print(F(" : "));
    Serial.println(wert[i]);
  }
  zaehler = 0;
}

rein aus der Hand ohne das ich weiss, ob das so geht.

Welche lib benutzt Du? -> link

Ja.

Etwas fragwürdig ist der Typ int, weil nur acht Bytes übertragen werden.

Ich glaub die richtige gefunden zu haben.

Da bin ich erstmal von weg.
Ich vermute mal, das jeder Wert mit einem '\0' abgeschlossen wird?
.read() macht ja nur ein Zeichen.

Müsste das ggfls. anders aussehen? (ungetestet aber compiliert)

#include <CAN.h>

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println("CAN Receiver");
  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3))
  {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}
void loop()
{
  char wert[10][10] = {'\0'};
  static int zaehler = 0;
  static int index = 0;
  int packetSize = CAN.parsePacket();
  if (packetSize)
  {
    Serial.print("Received ");
    if (CAN.packetExtended())
    {
      Serial.print("extended ");
    }
    if (CAN.packetRtr())
    {
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);
      while (CAN.available())
      {
        wert[zaehler][index] = CAN.read();
        if (wert[zaehler][index] == '\0')
        {
          zaehler++;
          index = 0;
        }
        else
        {
          index++;
        }
      }
    }
  }
  if (zaehler == packetSize)
  {
    Serial.print(F("Zaehlerstand: "));
    Serial.println(zaehler);
    for (unsigned int i = 0; i <= packetSize; i++)
    {
      Serial.print(F("Wert"));
      Serial.print(i);
      Serial.print(F(" : "));
      Serial.println(atoi(wert[i]));
      zaehler = 0; index = 0;
    }
  }
}

Danke für die ersten Infos,leider geht es nicht.
mit dem letzten Code kommt nur:

Zaehlerstand: 0
Wert0 : 0
Zaehlerstand: 0
Wert0 : 0
Zaehlerstand: 0
Wert0 : 0
Zaehlerstand: 0

Dann mal zurück - und das von Anfang:
ersetze mal loop und zeig mal was auf dem SerMon rauskommt:

void loop()
{
  int packetSize = CAN.parsePacket();
  if (packetSize)
  {
    Serial.print("Received ");
    if (CAN.packetExtended())
    {
      Serial.print("extended ");
    }
    if (CAN.packetRtr())
    {
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);
      Serial.println();
      while (CAN.available())
      {
        char wert = CAN.read();
        Serial.print(wert, HEX);
        Serial.print(' ');
      }
      Serial.println();
    }
  }
}

Hallo, gerne, leider geht dein Code nicht, er bringt Fehler beim comp.

ganz zurück zu meinemersten der geht:

// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <CAN.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("CAN Receiver");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = CAN.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }

    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);

    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(packetSize);

      // only print packet data for non-RTR packets
      while (CAN.available()) {
        Serial.print((char)CAN.read());
      }
      Serial.println();
    }

    Serial.println();
  }
}

Ausgabe auf Serial Monitor:

Received packet with id 0x12 and length 5
110120130140150

Received packet with id 0x12 and length 5
110120130140150

Received packet with id 0x12 and length 5
110120130140150

und ich habe die Lib:
sandeepmistry / arduino-CAN

arduino-CAN-master.zip

Da ich die selbe lib verwende und das hier fehlerfrei geht:

Nur loop() ersetzen, mit dem, was ich da eingehackt habe.

sodele:

Received packet with id 0x12 and length 5

6E 78 82 8C 96
Received packet with id 0x12 and length 5

6E 78 82 8C 96
Received packet with id 0x12 and length 5

6E 78 82 8C 96
Received packet with id 0x12 and length 5

6E 78 82 8C 96

Neuer Code - wieder nur loop ersetzen.

void loop()
{
  unsigned int paket[5] = {0};
  unsigned int index = 0;
  int packetSize = CAN.parsePacket();
  if (packetSize)
  {
    Serial.print("Received ");
    if (CAN.packetExtended())
    {
      Serial.print("extended ");
    }
    if (CAN.packetRtr())
    {
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);
      Serial.println();
      while (CAN.available())
      {
        char wert = CAN.read();
        Serial.print(wert, HEX);
        Serial.print(' ');
        paket[index] = (int)wert;
        index++;
        if (index > packetSize)
        {
          Serial.print(F("gefundene Werte: "));
          for (unsigned int i = 0; i < packetSize; i++)
          {
            Serial.print(paket[i]);
            Serial.print(' ');
          }
        }
        Serial.println();
      }
    }
  }
}

:slight_smile: es kommt bewegung rein..

Received packet with id 0x12 and length 5

6E
78
82
8C
96
Received packet with id 0x12 and length 5

6E
78
82
8C
96

jetzt noch als einzelene Variablen hinbiegen :slight_smile:
Von Hex in Dez. ist dann kein Problem.
Achso und danke Dir für die viele Mühe die du dir hier machst.

Das war die Intention...
Aber irgendwas passt nicht.
Also neu:

void loop()
{
  static unsigned int paket[5] = {0};
  static unsigned int index = 0;
  int packetSize = CAN.parsePacket();
  if (packetSize)
  {
    Serial.print("Received ");
    if (CAN.packetExtended())
    {
      Serial.print("extended ");
    }
    if (CAN.packetRtr())
    {
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);
      Serial.println();
      while (CAN.available())
      {
        char wert = CAN.read();
        Serial.print(wert, HEX);
        Serial.print(' ');
        paket[index] = (int)wert;
        index++;
      }
      if (index > packetSize)
      {
        Serial.println();
        Serial.print(F("gefundene Werte: "));
        for (unsigned int i = 0; i < packetSize; i++)
        {
          Serial.print(paket[i]);
          Serial.print(' ');
        }
        memset(paket, 0, sizeof(paket));
        index = 0;
      }
      Serial.println();
    }
  }
}

Ahctung, da fehlten noch zwei Zeilen!
Hab ich nachgetragen.

ui ?

6E 78 82 8C 96
gefundene Werte: 110 120 130 140 150
Received packet with id 0x12 and length 5

6E Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400e9f69 PS : 0x00060530 A0 : 0x800d0de4 A1 : 0x3ffb1f70
A2 : 0x0000006e A3 : 0x3ffbfe70 A4 : 0x00000010 A5 : 0x00000000
A6 : 0x00000003 A7 : 0x00000000 A8 : 0x00000005 A9 : 0x3ffb1f50
A10 : 0x3ffbfe70 A11 : 0x00000020 A12 : 0x00000010 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x3ffb0060 SAR : 0x0000001b EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000082 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff

ELF file SHA256: 0000000000000000

Backtrace: 0x400e9f69:0x3ffb1f70 0x400d0de1:0x3ffb1f90 0x400d1f19:0x3ffb1fb0 0x400860ed:0x3ffb1fd0

Rebooting...

Ja, da kommt es zum Überlauf - mein Fehler. Hab ich gemerkt und geändert als Du schriebst :wink:

Versuchs mal nochmal mit dem geänderten.

:wink:

6E 78 82 8C 96
Received packet with id 0x12 and length 5

6E 78 82 8C 96
gefundene Werte: 110 120 130 140 150
Received packet with id 0x12 and length 5