Hallo Zusammen,
ich habe folgenden funktionierenden Code zusammengehackt, um eine
Checksumme für ebenfalls folgend beschriebenes Protokoll zu überprüfen.
Es geht dabei um einen RFID-Reader, welcher die gelesenen Tag-IDs auf
eine serielle Schnittstelle ausgibt. Wie beschrieben kommt die Nachricht
in einzelnen Bytes rein, ich suche nach Start- und Stoppbyte und
sortiere alle empfangenen Bytes dann in einen Buffer (auf welchen
matches_checksum() wiederum zugreift).
Nun zur Frage: Mein Ansatz erscheint mir ziemlich "roh". Gibt es einen
eleganteren Weg die Checksumme zu berechnen? Ist es tatsächlich nötig
alle Bytes wieder nach Hex zu konvertieren oder gibt es auch eine
Berechnung ohne Konvertierung?
Wie geschrieben funktioniert der Code, mir geht es eher um Best
Practices, den "richtigen Weg" und ganz generell darum meine Kenntnisse
zu verbessern.
Bei interesse poste ich auch den gesamten Code, der die ID vom
RFID-Reader empfängt, in ein neues Format bringt und auf der Seriellen
wieder ausspuckt. Läuft auf einem Arduino.
Dank & Gruß,
der tinkerer
1 | /*
|
2 | Protocol of RFR101A1M (seeedstudio.com RFID 125khz module)
|
3 | | Start | ID | CHECKSUM | STOP |
|
4 | | 1 Byte | 10 Bytes | 2 Bytes | 1 Byte |
|
5 | | 2 | 50 | 67 | 48 | 48 | 52 | 54 | 56 | 69 | 51 | 70 | 68 | 66 | 3 |
|
6 |
|
7 | Example ID is 2C00468E3F, every digit in ID and CHECKSUM will be transmitted as
|
8 | single bytes.
|
9 |
|
10 | Original ID: | 0x2C | 0x00 | 0x46 | 0x8E | 0x3F |
|
11 | to digits: | 2 | C | 0 | 0 | 4 | 6 | 8 | E | 3 | F |
|
12 | Transmitted as byte: | 50 | 67 | 48 | 48 | 52 | 54 | 56 | 69 | 51 | 70 |
|
13 |
|
14 | Checksum is XOR of HEX values of ID (2 Bytes form 1 HEX).
|
15 | 0x2C (XOR) 0x00 (XOR) 0x46 (XOR) 0x8E (XOR) 0x3F = 0xDB (sent as 68, 66)
|
16 |
|
17 | Complete message as put on serial port (inserted spaces for easier reading):
|
18 | 2 50 67 48 48 52 54 56 69 51 70 68 66 3
|
19 | */
|
20 |
|
21 | uint8_t ASCII2int(char data){
|
22 | data -= '0';
|
23 | if (data > 9)
|
24 | data -= 7;
|
25 | return data;
|
26 | }
|
27 |
|
28 |
|
29 | boolean matches_checksum( void )
|
30 | {
|
31 | byte hex_1;
|
32 | byte hex_2;
|
33 | byte hex_3;
|
34 | byte hex_4;
|
35 | byte hex_5;
|
36 | byte hex_calc;
|
37 | byte hex_check;
|
38 |
|
39 |
|
40 | // msg.msg.id[n] and msg.msg.check[n] point to matching byte in buffer
|
41 | hex_1 = ASCII2int(msg.msg.id[0])*16 + ASCII2int(msg.msg.id[1]);
|
42 | hex_2 = ASCII2int(msg.msg.id[2])*16 + ASCII2int(msg.msg.id[3]);
|
43 | hex_3 = ASCII2int(msg.msg.id[4])*16 + ASCII2int(msg.msg.id[5]);
|
44 | hex_4 = ASCII2int(msg.msg.id[6])*16 + ASCII2int(msg.msg.id[7]);
|
45 | hex_5 = ASCII2int(msg.msg.id[8])*16 + ASCII2int(msg.msg.id[9]);
|
46 | hex_check = ASCII2int(msg.msg.check[0])*16 + ASCII2int(msg.msg.check[1]);
|
47 |
|
48 | hex_calc = hex_1 ^ hex_2 ^ hex_3 ^ hex_4 ^ hex_5;
|
49 | if ( hex_calc == hex_check )
|
50 | {
|
51 | return true;
|
52 | } else {
|
53 | return false;
|
54 | }
|
55 | }
|