Serielles Reverse-Engineer-Signal

Dies ist ein langer Beitrag, da ich Sie durch all die Arbeit führen möchte, die ich geleistet habe. Die TL;DR-Version lautet Ich habe einen unbekannten Controller für eine mechanische Wärmepumpe und ich versuche, das Signal und die Daten zurückzuentwickeln .... also, wenn Sie glauben, dass Sie helfen können, dann lesen Sie bitte weiter.

Vorweg, ich bin kein Elektrotechniker. Ich bin ein Software-Ingenieur, der etwas überfordert ist.

Ich habe eine ITS-Wärmepumpe und einen Controller, den ich zurückentwickeln möchte, um Daten von den Sensoren zu lesen und einige Parameter in der Software einzustellen. Ich habe nach technischen Spezifikationen gesucht und den Hersteller gefragt, aber sie sagten mir zu GTFO. Am Ende schien Reverse Engineering der einzige Weg zu sein, um das zu bekommen, was ich wollte.

Zwischen dem Gerät und dem Bedienfeld befindet sich eine 3-adrige Verbindung. Aus dem, was ich ableiten konnte, handelt es sich um GND, + 12 V (zum Stromversorgungspanel) und ein Signalkabel.

Dann besorgte ich mir einen Saleae-Protokollanalysator, um zu sehen, was ich sehen konnte. Ich habe bestätigt, dass das einzelne Datenkabel für RX/TX verwendet wird. Ich dachte, der einfachste Punkt ist das Bedienfeld und trennte das Signalkabel, damit ich nur lesen konnte, was das Bedienfeld überträgt. Ein Beispiel finden Sie unter http://tinyurl.com/ppuemv7 . Ich verwende die Beta-Version 1.1.24 zum Decodieren. Es scheint mit Async Serial 8N1 Autobaud gut zu decodieren. Ich habe eine Reihe anderer Decoder und Parameter ausprobiert, aber bei allen treten Framing- oder andere Fehler auf.

Ich habe dann angefangen, die Werte auf dem Controller systematisch zu ändern, um zu sehen, wie sich der Bytestrom ändert. Ich habe Parameter 1 mit den Werten [51-55] geändert, und dies war das Ergebnis (mit absichtlichem Abstand, um Unterschiede leichter erkennen zu können) der Byte-Streams.

Format <Param>-<value>:<decoded byte string in hex>
01-51:8055DD555555555555555555555555555575577557F58075757757 DD 757577577755DD55555D7777775577755D 55 5D 77 FD
01-52:8055DD555555555555555555555555555575577557F58075757757 D5 DD7577577755DD55555D7777775577755D 55 77 77 F5
01-53:8055DD555555555555555555555555555575577557F58075757757 5D DD7577577755DD55555D7777775577755D 55 75 77 FD
01-54:8055DD555555555555555555555555555575577557F58075757757 75 DD7577577755DD55555D7777775577755D 55 D7 77 F5
01-55:8055DD555555555555555555555555555575577557F58075757757 DD D757DD5D7755D757555D75DD7755DDD575 57 D5 77 57

Daher war das Muster nicht offensichtlich, also entschied ich mich, einen anderen Parameter zu ändern (param:0 von 15 auf 16 geändert) und Parameter 01 auf 52 zu belassen, und das ist, was ich bekam.

Format <Param>-<value>:<decoded byte string in hex>
00-15:8055DD555555555555555555555555555575577557F5807575 7757 D5 DD7577577755DD55555D7777775577755D 55 77 77 F5 
00-16:8055DD555555555555555555555555555575577557F5807575 5555 D7 57DD5D7755D757555D75DD7755DDD57557 55 77 F5 

Diejenigen unter Ihnen, die schnell bei der Auslosung sind, werden feststellen, dass die 00-16-Erfassung 1 Byte kürzer ist. Meine einzige Schlussfolgerung ist, dass ich entweder die falsche Dekodierung verwende oder das Panel etwas komprimiert.

Ich brauche einen Rat, was ich als nächstes versuchen soll, da ich mich ziemlich festgefahren fühle.

Ist es plausibel, dass der Hersteller das Reverse Engineering der Kommunikation absichtlich erschwert? Ich wäre versucht, ein kleines Stück Software zu schreiben, um die Daten zu filtern und alles zu unterdrücken, was sich nicht ändert, um mir zu helfen, die Muster zu erkennen. Ist es konsistent, dh wenn Sie zurückgehen und frühere Parameter wiederherstellen, werden die gleichen Werte erzeugt?
Es gibt eine Reihe häufig verwendeter 1-Wire- (oder Pseudo-1-Wire-) Protokolle. Haben Sie eines davon ausprobiert? Können Sie den Controller öffnen und einen Blick auf die Treiberhardware werfen, da dies möglicherweise einen Hinweis darauf gibt, was sie verwendet oder worauf sie basiert. Haben Sie die Spannung und Frequenz / das Timing des Signals gemessen, da dies zumindest beginnen würde, es ein wenig zu kategorisieren? Es ist möglich, dass der Controller Junk-Daten (oder für Sie nicht nützliche Daten) sendet, wenn er von seinem Ziel getrennt wird. Denken Sie also daran, dass die Nachrichten möglicherweise nur fehlgeschlagene Handshakes sind. Schauen Sie sich auch den BusPirate von Dangerousprototypes an, sehr nützlich.
Es ist schwer zu verstehen, warum ein kleiner Unterschied im Wert eines Steuerelements (so wenig wie ein Bit) das Paket so stark verändern würde, wenn alles andere gleich ist. Vielleicht ist alles andere nicht gleich. Könnten die Pakete Zeitstempel oder Sequenznummern und dergleichen enthalten? Wenn Sie denselben Parameter auf denselben Wert setzen, erhalten Sie immer dasselbe Paket? Wenn nicht, ist es hilfreich, zahlreiche Pakete mit der gleichen Parameternummer und dem gleichen Wert aufzulisten, um nur diese Unterschiede zu betrachten.
Ich bin sehr neugierig zu erfahren, wie Sie in dieser Sache vorangekommen sind. Ich habe gerade die gleiche Wärmepumpe und möchte genau das tun, was Sie beschreiben. Ich versuche auch, dasselbe mit der Deron-Einheit zu tun.
Hallo Will. Ich habe es am Ende tatsächlich verstanden, bin aber nie dazu gekommen, es aufzuschreiben oder es als Open Source zu veröffentlichen. Ich habe ein Arduino verwendet, um die Dekodierung durchzuführen. Ich habe auch eine ziemlich gute Vorstellung davon, wie man kodiert und überträgt. Wo Sie ansässig sind.

Antworten (2)

Mein erster Gedanke (nur basierend auf den asynchron decodierten Daten) war, dass dies ein Manchester-codiertes Signal sein könnte, anstatt asynchron seriell. Jetzt denke ich, dass die Daten codiert werden, indem abwechselnde Taktimpulse unterdrückt werden.

Hier ist der Grund:

Mit Ausnahme von 0x80 (das ein "Startbyte" sein kann) behauptet die asynchrone serielle 8N1, dass die Nachrichten aus nur 10 verschiedenen Symbolbytes bestehen:

0x55 01010101 (139 occurrence) 
0x57 01010111 (32 occurrence) 
0x5d 01011101 (16 occurrence) 
0x75 01110101 (45 occurrence) 
0x77 01110111 (49 occurrence) 
0xd5 11010101 (5 occurrence) 
0xd7 11010111 (5 occurrence) 
0xdd 11011101 (24 occurrence) 
0xf5 11110101 (11 occurrence, only at end of message) 
0xfd 11111101 (2 occurrence, only at end of message) 

Wenn man sich die Binärdatei ansieht, sieht es so aus, als ob der Nachrichten-Bitstrom aus langen und kurzen Impulsen besteht und möglicherweise nicht korrekt mit den Start- und Stoppbits der asynchronen Serie synchronisiert ist. Die einzigen Bitmuster, die mehr als drei Einsen hintereinander haben, sind 0xFD und 0xF5, aber das tritt nur am Ende einer Nachricht auf – und denken Sie daran, asynchron seriell ist LSB-first. Diese längeren Folgen von Einsen im MSB können also nach dem Ende des zugrunde liegenden Manchester-codierten Signals liegen. In ähnlicher Weise kann das 0x80 am Anfang jeder Nachricht dem zugrunde liegenden Signal vorangehen.

Atmels Einführung in Manchester Coding Basics gibt einen guten Überblick über Kodierung und Dekodierung: http://www.atmel.com/images/atmel-9164-manchester-coding-basics_application-note.pdf

Wellenformerfassungsbild

Jetzt, wo ich die Wellenform sehe, ist es definitiv keine Manchester-Codierung ... Sieht aus wie Idle-High, mit einem langen Impuls als Header, gefolgt von einer sehr langen Folge von Taktimpulsen - mit gelegentlich fehlenden Taktimpulsen. An diesem Punkt würde ich vermuten, dass die Impulse zwischen Taktimpulsen und Datenimpulsen wechseln. Eine 0 wird also als zwei Taktimpulse codiert, und eine 1 wird als ein Taktimpuls und ein "fehlender" Impuls codiert. Ich bin mir nicht sicher, wie das heißt, aber ich glaube, ich habe es schon einmal gesehen, vor langer Zeit ...

Ich habe eine Stunde damit verbracht, es zu entschlüsseln, und ich glaube nicht, dass es Manchester ist. Soweit ich weiß, können die Tastverhältnisse bei Manchester nur 1/3 oder 1/2 betragen, und die erfasste Wellenform zeigt Tastverhältnisse von 1/4. Gedanken?
Die Bitlänge von Datlink auf Manchester beträgt maximal 2 aufeinanderfolgende Einsen oder Nullen. Möglicherweise ist dieses Signal zweiphasig oder eine andere Variante. Können Sie Ihren Beitrag so bearbeiten, dass er einige Oszilloskopaufnahmen (Wellenformerfassung) des Signals enthält?
Hallo Mark. Es gibt eine Wellenformerfassung im ursprünglichen Beitrag; die Daten sind @ tinyurl.com/ppuemv7 und die Software zum Anzeigen ist @ support.saleae.com/hc/en-us/articles/…
Hallo Markus, danke für dein Update. Je mehr ich es betrachte, desto mehr sieht es aus wie ein 1-Draht / PWM-Schema. Saleae hat ein SDK zum Decodieren, also könnte ich versuchen, Code zu schreiben, um es zu entschlüsseln.

Es gibt definitiv ein Muster in den Daten, dass sie aus Gruppen von Bits bestehen, die an Nibble-Grenzen ausgerichtet sind.

Die einzigen auftretenden Nibbles sind 0, 5, 7, 8, Dund F. Außerdem treten Fund 8nur in der oberen Hälfte eines Bytes auf. 8kommt immer mit 0als vor 80. Ftritt mit einem 5, 7oder Dniedrigeren Nibble auf.

Die 5, 7und DNibbles entsprechen 0101, 0111, 1101. Grundsätzlich sind fast alle möglichen Wiederholungen zulässige Kombinationen von 01und 11, außer 1111denen, die entsprechen F. Offensichtlich ist hier eine Sprache im Gange, die aus den Symbolen 01und besteht 11. Und beachten Sie, wie die 80er-Sequenz gegen dieses Muster verstößt: 10, 00, 00, 00.

Dies deutet darauf hin, dass die Daten in eine Zwei-Bit-Eingabe verschoben werden können, nennen wir sie XY, wobei ein 1-Wert von Y bedeutet, etwas mit X zu tun, wie das Bit in ein Register zu verschieben.

Angenommen, die D- und F-Nibbles sind Signale und 5 und 7 sind Daten.

Warum gruppieren wir die Daten auf dieser Grundlage nicht irgendwie neu:

                 
00-15:80 55DD555555555555555555555555555575577557F5 80 7575 7 757D 5DD757757 7755D D55 555D7 777 7755 77755D 557 7 77F5
00-16:80 55DD555555555555555555555555555575577557F5 80 7575 5555D 757D D5D 7755D 757 555D7 5DD 7755 DDD57 557 55 77F5

Eine andere Gruppierung, schau dir das an: Angenommen, das DDByte ist ein Trennzeichen/Terminator:

00-15:80 55 DD 555555555555555555555555555575577557 F5 80 75757757D5 DD 7577577755 DD 55555D7777775577755D557777 F5
00-16:80 55 DD 555555555555555555555555555575577557 F5 80 75755555D757 DD 5D7755D757555D75DD7755D DD 575575577 F5

Schau dir das an; Jetzt haben wir die gleiche Anzahl von Feldern. Nicht nur das, die Felder sind alle byte-ausgerichtet, nicht nybble-ausgerichtet.

Die anderen Daten unterstützen diese Feldteilungshypothese, mit Ausnahme der letzten:

01-51:80 55 DD 555555555555555555555555555575577557 F5 80 75757757 DD 757577577755 DD 55555D7777775577755D555D77 FD
01-52:80 55 DD 555555555555555555555555555575577557 F5 80 75757757D5 DD 7577577755 DD 55555D7777775577755D557777 F5
01-53:80 55 DD 555555555555555555555555555575577557 F5 80 757577575D DD 7577577755 DD 55555D7777775577755D557577 FD
01-54:80 55 DD 555555555555555555555555555575577557 F5 80 7575775775 DD 7577577755 DD 55555D7777775577755D55D777 F5

01-55:80 55 DD 555555555555555555555555555575577557 F5 80 75757757 DD D757 DD5D7755D757555D75 DD 7755 DD D57557D57757

Aber auch der letzte ist nicht Fxbeendet; es könnte eine schlechte Aufnahme sein.

Die Codierung der Felder muss eine Art Escape-Konvention enthalten, denn was passiert, wenn sie DDnatürlicherweise in den Daten vorkommt? Es würde als Trennzeichen missinterpretiert werden. Es könnte ein Schema geben, bei dem ein DNibble irgendwie als Escape-Code überladen wird.

Es ist möglicherweise keine binäre Codierung; Vielleicht treiben die Nibbles eine Zustandsmaschine an, die irgendwie die Registerwerte basierend auf einigen Inkrementoperationen in Kombination mit Verschiebungen oder was auch immer erzeugt.