Forum: Mikrocontroller und Digitale Elektronik Fletchers Checksum implementieren


von Math (Gast)


Lesenswert?

Ich will gerade für die Kommunikation mit einem GPS-Modul den 
verwendeten Prüfsummenalgorithmus implementieren. Hier auf Seite 86 
steht wie das ganze laufen soll:
https://www.u-blox.com/sites/default/files/products/documents/u-blox6_ReceiverDescrProtSpec_%28GPS.G6-SW-10018%29_Public.pdf
(Die Prüfsumme wird ab dem 3 byte berechnet)
Ich habe eine Nachricht von der Ich weiss dass sie funktioniert (Die 
Prüfsumme stimmt) und versuche jetzt die Prüfsumme nachzurechnen. Leider 
kommt etwas anderes raus als das was stimmt. Hier der Code:
1
int messageLength = 44;
2
byte message[messageLength]= {181, 98, 6, 36, 36, 0, 255, 255, 7, 2, 0, 0, 0, 0, 16, 39, 0, 0, 5, 0, 250, 0, 250, 0, 100, 0, 44, 1, 0,  0, 0, 0, 16, 39, 0, 0, 0, 0, 0, 0, 0, 0, 77, 220};
3
4
int calc_ck_a = 0;
5
long calc_ck_b = 0;
6
7
int n = 42;
8
9
for(int i=2; i<n; i++){
10
  calc_ck_a = calc_ck_a + message[i];
11
  calc_ck_b = calc_ck_b + calc_ck_a;
12
}
13
byte ck_a = calc_ck_a % 255;
14
byte ck_b = calc_ck_b % 255;
15
Serial.print(ck_a);
16
Serial.print(" ");
17
Serial.println(ck_b);
Wenn Ich das ganze ausführe kommt statt 77 und 220 leider 82 und 107 
raus.
Wo liegt der Fehler?

: Verschoben durch User
von Waldo (Gast)


Lesenswert?

x % 255 ????????

von Math (Gast)


Lesenswert?

Es soll ja ein Byte rauskommen also muss Ich den Long ja kürzen oder?

von Waldo (Gast)


Lesenswert?

x & 255 !!!

von Waldo (Gast)


Lesenswert?

x % 256 !!!!!

von Math (Gast)


Lesenswert?

Mit & stimmt zwar ck_a aber ck_b ist 143 was auch nicht stimmt. Was ist 
falsch?

von Waldo (Gast)


Lesenswert?

calc_ck_a = 1357
1357 % 256 = 77
1357 & 255 = 77
1357 % 255 = 82

von Math (Gast)


Lesenswert?

auch mit % 256 ist ck_b 143

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

"The two CK_ values are 8-Bit unsigned integers, only! If implementing 
with larger-sized integer values, make sure to mask both CK_A and CK_B 
with 0xFF after both operations in the loop."

versus
1
int calc_ck_a = 0;
2
long calc_ck_b = 0;

von Math (Gast)


Lesenswert?

Stimmt, habe ich durch bytes ersetzt, aber immernoch 77 und 143...

von Waldo (Gast)


Lesenswert?

Es kommt raus:
77 (4D)
216 (D8)

  0  0
6  6  6
36  42  48
36  78  126
255  333  459
255  588  1047
7  595  1642
2  597  2239
16  613  2852
39  652  3504
5  657  4161
250  907  5068
250  1157  6225
100  1257  7482
44  1301  8783
1  1302  10085
16  1318  11403
39  1357  12760
  77  216
  4D  D8

von Math (Gast)


Lesenswert?

Jetzt läuft es wie es soll:
1
int messageLength = 44;
2
3
byte message[messageLength]= {181, 98, 6, 36, 36, 0, 255, 255, 7, 2, 0, 0, 0, 0, 16, 39, 0, 0, 5, 0, 250, 0, 250, 0, 100, 0, 44, 1, 0,  0, 0, 0, 16, 39, 0, 0, 0, 0, 0, 0, 0, 0, 77, 220};
4
5
byte ck_a = 0;
6
byte ck_b = 0;
7
8
int n = 42;
9
10
for(int i=2; i<n; i++){
11
  ck_a = ck_a + message[i];
12
  ck_b = ck_b + ck_a;
13
}
14
  
15
Serial.print(ck_a);
16
Serial.print(" ");
17
Serial.println(ck_b);
Danke für die Hilfe!

von Waldo (Gast)


Lesenswert?

Falsch! Die Nullen sind für _B wichtig:
_a = 1357
_b = 36572

_a % 256 = 77
_b % 256 = 220

Data  _a  _b
  0  0
6  6  6
36  42  48
36  78  126
0  78  204
255  333  537
255  588  1125
7  595  1720
2  597  2317
0  597  2914
0  597  3511
0  597  4108
0  597  4705
16  613  5318
39  652  5970
0  652  6622
0  652  7274
5  657  7931
0  657  8588
250  907  9495
0  907  10402
250  1157  11559
0  1157  12716
100  1257  13973
0  1257  15230
44  1301  16531
1  1302  17833
0  1302  19135
0  1302  20437
0  1302  21739
0  1302  23041
16  1318  24359
39  1357  25716
0  1357  27073
0  1357  28430
0  1357  29787
0  1357  31144
0  1357  32501
0  1357  33858
0  1357  35215
0  1357  36572
  77  220

von Math (Gast)


Lesenswert?

Was ist denn jetzt falsch? Und welche Nullen meinst du?

von Waldo (Gast)


Lesenswert?

Alles gut.
Mein voriger Beitrag war ohne die Nullen gerechnet, aber auch bei Data=0 
verändert sich _b.

Deswegen musste ich nachbessern.

Der Hauptfehler im ersten C-Code war x % 255. Das ist der Rest bei 
Division durch 255. Das unterste Byte ist aber der Rest bei Division 
durch 256 oder besser x & 255.

Waldo

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.