Ich habe jetzt dem Signal erstmal zur Bestimmung der Baudrate mittels einem Logic-Analyzer auf den Zahn gefühlt. Hier habe ich nach dem LIN-Transceiver (ich habe einen TJA1020 verwendet, den "Klassiker"):
Mit 2M/s aufgezeichnet ergibt sich eine Bit-Zeit von 104,5 µs, was nach der Formel Baudrate = 1 / Bit-Zeit in s eine Baudrate von 9.600 ergibt. Das ist schon etwas ungewöhnlich, da LIN standardmäßig 19.200 Baud benutzt, gut das ich nachgemessen habe! LIN nutzt 8N1, also 8 Daten-Bits (das LSB zuerst), kein Parity-Bit und 1 Stopp-Bit. Nie mit angegeben aber immer enthalten ist auch ein Start-Bit. Ein LIN-Frame, die kleinste Informationseinheit also, besteht aus insgesamt 10 Bits.
So habe ich den Protocol-Interpreter vom Logic-Analyzer eingestellt und sehe damit dann auch diese Frame-Daten in Form von Bytes.
Wie schon erwähnt gibt es auf einem LIN-Bus einen Master und mehrere (bis zu 63) Slaves. Auf unserem Batteriesensor-Bus zum glück nur diesen einen Slave. Die senden nur wenn sie vom Master dazu aufgefordert werden. Die Kommunikation läuft immer so ab das der Master einen Request (Header) auf den Bus legt. Dieser besteht aus einem BREAK, einem SYNC und einem PID.
Das BREAK ist (mind.) 13 Bits lang und besteht als 0-Bits (Leitung wird auf LOW gezogen). Im gemessenen Signal ist es 1,352 ms lang (13 * 104 µs):
Das BREAK gibt den Slaves auf dem Bus Zeit aufzuwachen, falls diese sich im Tiefschlaf befinden. Dann folgt das SYNC, welches aus einer Folge von 0 und 1 im Wechsel besteht (daraus resultiert der Hex Bytewert 0x55). Dies verwenden die Slaves um sich auf die Baudrate und Phase des Masters einstellen zu können.
Als letztes überträgt der Master das PID, quasi die Adresse des Slaves der angesprochen wird. Die eigentliche ID ist dabei 6 Bit lang, wodurch sich eine maximale Anzahl von 63 Nodes ergibt. Weil die ID wichtig ist wird sie mit zwei Paritäts-Bits gesichert (die höchstwertigen Bits). Der Wert des Partitäts-Bits P0 ergibt sich aus einem XOR von ID0 ^ ID1, sowie einem ID2 ^ ID4 und einem XOR beider Ergebnisse. Das Parity Bit P1 verwendet ID1, ID3, ID4 und ID5 zur Berechnung. Im obigen Datagramm ist 0x20 die LIN-Bus Adresse. Bei dieser Adresse sind beide Paritäts-Bits "0" wodurch sich keine Werteänderung ergibt. Die Adresse ist auch gleichzeitig sowas wie ein Befehl. Ein LIN-Slave kann auf mehreren Adressen reagieren um damit unterschiedliche Daten zu senden.
Im Anschluß an dieses Anforderungs-Signal vom Master sendet der sich angesprochene Slave dann seine Daten. Das ist aus dem obigen Beispiel:
0x84 0x80 0x00 0x00
Wieviele Bytes das sind, bestimmt allein der Slave, es dürfen aber maximal 8 sein. Dem folgt dann ein CHECKSUM Byte (ob im Beispiel 0xFA).
So sieht dann eine solche Datensalve aus:
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x84 0x80 0x00 0x00 0xFA
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x09 0xB6
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x50 0x00 0x0A 0xF5
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x09 0xB6
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x84 0x80 0x01 0x00 0xF9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x08 0xB7
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x0D 0xDE 0x1F 0xD4 0xE0 0x4C
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x84 0x80 0x01 0x00 0xF9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x8E 0x00 0xB2 0x06 0xFF 0x47
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x84 0x80 0x01 0x00 0xF9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0xCF 0x9E 0x8B 0xB3 0xFF 0x22
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x94 0x80 0x01 0x00 0xE9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x8E 0x00 0xB2 0x06 0xFF 0x47
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x94 0x80 0x01 0x00 0xE9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x0D 0x75 0x1E 0xD0 0xE0 0xBA
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x94 0x80 0x01 0x00 0xE9
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x08
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x94 0x82 0x03 0x00 0xE5
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x8E 0x00 0xB2 0x06 0xFF 0x47
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x06 0x00 0x00 0xFF
0x00 0x55 0x20 0x94 0x82 0x03 0x00 0xE5
0x00 0x55 0x85 0x40 0x02 0xBD
0x00 0x55 0x50 0x00 0x4A 0xB5
0x00 0x55 0x2B 0x02 0x41 0x47 0x39 0x4E
0x00 0x00 0x00 0xED
0x00 0x55 0x6A 0xFF 0xFF 0xFF 0xFF 0xFF
Alles anzeigen
Als nächstes versuche ich dann mittels meines Selbstbau LIN-Sniffers, bestehend aus dem TJA1020 und einem ESP32 die reinen Nutzdaten zu extrahieren und daraus schlau zu werden.