crc16 unterschiedliche Werte bei Python/Arduino

Guten Abend zusammen,

ich will die Prüfsumme von empfangenen Daten berechnen. Die Daten kommen in HEX an und werden von einem Python-Script versendet. Leider sind die beiden Prüfsummen nicht identisch.
Es liegt sehr wahrscheinlich daran, dass ich in Arduino nicht die ASCII Ansicht habe bzw. damit nicht gerechnet werden kann und somit ist die Berechnung unterschiedlich. Oder? Gibt es dazu eine Lösung?

byte wert[] = {0xA2, 0x30};  -> 0x4D4F
byte wert[] = "A230;             -> 0xD578

Ob das ASCII, Hex, Dezimal oder sonst was ist liegt nur an dir. Du musst das nur richtig machen.

Deine zwei Arrays sind nicht gleich. Da kommt klar was anderes raus

Wie kriege ich die zwei Arrays gleich? Das ist mein Problem. Ich weiß nicht wie man es richtig macht...

Hallo,

ich verstehe Dein Problem nicht ganz.

byte wert[] = {0xA2, 0x30}; -> 0x4D4F
byte wert[] = "A230; -> 0xD578

die erste Zeile ist ein Array mit zwei Hex Zahlen

wert[0]=0xA2
wert[1]=0x30

die Zweite Zeile sieht nach einer Zeichenkette Text aus mit den 4 Zeichen "A230"

wert[0]='A'
wert[1]='2'
Wert[2]='3'
wert[3]='0'

wie Du unschwer erkenne kannst ist das was völlig anderes.

Heinz

Das versuchen wir ihm seit gefühlt 1000 Postings in mehreren Threads zu erklären, er ist aber völlig lernresistent.
Deshalb habe ich es aufgegeben, ihm weiterhin etwas zu erklären.
Die CRC war vor gefühlt 100 Postings irgendwo auch schon mal dran.

Gruß Tommy

Wie wandel ich:

wert[0]=0xA2
wert[1]=0x30

in

wert[0]='A'
wert[1]='2'
Wert[2]='3'
wert[3]='0'

um?

  byte wert[] = {0xA2, 0x34};
  byte zeichen[] = "A234";
  byte wandeln[4];

  byte buf[2];
  for(int i=0;i<2;i++) {
    wandeln[i] = wert[i] >> 4;
    buf[i] = wert[i] << 4;
    wandeln[i+1] = buf[i] >> 4;
    Serial.println(wandeln[i], HEX);
    Serial.println(wandeln[i+1],HEX);
  }

Das klappt leider nicht. Ist das überhaupt so möglich?

Dir ist der Unterschied zwischen den beiden "Varianten" weiterhin nicht klar - das wir schwierig bis aussichtslos :confused:

Wenn Wandeln, dann ist es viel einfacher in die andere Richtung. Aber wie gesagt musst du generell mal den Unterschied verstehen. z.B. mal eine ASCII Tabelle anschauen

Wie wird es anders umgewandelt? Gibt es dazu eine Bibliothek oder sonstiges?

 byte wert[] = {0xA2, 0x34};
 byte wandeln[5];
 const char zeichen[] = "A234"; // 5 Byte mit einem Text, zum Vergleich
void test1() {
  int i = 0; 
  for (byte einzelwert:wert) { // beide Elemente von wert
    wandeln[i++] = einzelwert >> 4;
    wandeln[i++] = einzelwert & 0x0F;
  }
  wandeln[i] = 0; // Endekennung
  // wandeln[] ist jetzt {0xA, 0x2, 0x3, 0x4, 0 }
} 
char* toText(byte* w , byte size) {
  // w in einen Text umwandeln (und als solchen zurückliefern)
  // w[size] wird noch mit einer mit einer 0 beschrieben! 
  char* retval = (char*)w;
  while (size--) {
    switch (*w) {
      case 0 ... 9: *w = *w+'0'; break;
      case 10 ... 15: *w = *w-10 + 'A'; break;
      default: *w = '?'; break; 
    }
    w++;
  }
  *w = 0; // Endekennung
  return retval;
}
void setup() {
  Serial.begin(9600);
  test1(); // wandeln füllen (binär)
  for(byte b:wandeln) Serial.println(b, HEX); // 5 Hex-Zahlen anzeigen
  Serial.println(toText(wandeln,4)); // in Text wandeln und anzeigen
  if (strcmp((char*)wandeln, zeichen) == 0) Serial.println("Gleich !");
}

void loop() {}

Die ASCII Tabelle muss man übrigens nicht auswendig können, es reicht zu wissen:

  1. Die Zeichen '0' ... '9' , 'A' ... 'Z' (und 'a' ... 'z' -hier egal-) sind jeweils fortlaufend hintereinander
  2. Man kann damit rechnen: ( '0' + 1 ergibt '1' ), aber '9' + 1 ergibt leider nicht 'A'
  3. jedes Zeichen ist 1 byte groß, in unserer einfachen Welt.

Hier bei Arduino (und anderen "LittleEndian" Maschinen) ist bei zwei Byte das erste übrigens das niederwertige,

byte wert[] = {0xA2, 0x34};

würde also eher der Zahl 0x34A2 entsprechen. Das Beispiel ist also "möglich aber sinnlos" oder zumindest was solch eine Zahl mit dem Text "A234" und der Frage nach CRC16 zu tun hat, ist mir eher unklar.

Ich werde es morgen Abend testen und mich dann nochmal melden.

MauFau:
Wie wandel ich:

wert[0]=0xA2
wert[1]=0x30

in

wert[0]='A'
wert[1]='2'
Wert[2]='3'
wert[3]='0'

um?

Das klappt leider nicht. Ist das überhaupt so möglich?

Du kannst aus 2 Äpfeln keine 4 Birnen machen , vergleichen geht also nicht

Heinz

Hi

Naja ... man kann schon die Nibble eines Byte in zwei Zeichen 'aufblasen' - warum man Das aber machen will ...
(da diverse Zeichenketten-'Befehle' des Arduino sogar HEX-Zahlen ausgeben können, sollte Das sogar komplett ohne Handarbeit hinzubekommen sein - sinnlos, ok, aber recht sicher machbar)

MfG

Ob und warum es erforderlich sein mag, zwei Bytes in eine vier (eigentlich) fünf Byte lange Zeichenkette zu verwandeln will ich gar nicht beurteilen. Wir alle machen manchmal Sachen...
Aber es ist trivial - wirklich. Bitte verzeiht die altmodische Art der Arraydefinitionen und Zuweisungen.

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

  byte wert[2];
  char wandeln[5];

  wert[0] = 0xA2;
  wert[1] = 0x30;

  memset(wandeln, 0, 5);
  snprintf(wandeln, 5, "%2.2X%2.2X", wert[0], wert[1]);

  Serial.print("wert   : ");
  Serial.print(wert[0], HEX);
  Serial.print(' ');
  Serial.println(wert[1], HEX);

  Serial.print("wandeln: ");
  Serial.println(wandeln);

  Serial.print("einzeln: ");
  for (byte count = 0; count < 4; count++)
  {
    Serial.print(wandeln[count]);
    Serial.print(' ');
  }
  Serial.println();

}

void loop() {
  // put your main code here, to run repeatedly:

}

Dieser (nicht wirklich schöne) Sketch erzeugt diese Ausgabe:

Umwandlung
wert   : A2 30
wandeln: A230
einzeln: A 2 3 0

Bitte verstehen und dann auf das CRC-Problem sachgerecht anwenden.

wno158:
Bitte verstehen und dann auf das CRC-Problem sachgerecht anwenden.

Danke, ich habe es jetzt in mein Programm eingebunden und es funktioniert. Und jetzt versuche ich es noch zu verstehen. :slight_smile: