Hilfe oder Hinweise zum Dekodieren eines IR-Protokolls

10

Vor einiger Zeit habe ich einen einfachen und billigen kleinen IR-gesteuerten Spielzeughubschrauber gekauft (genau wie dieser - er heißt "Diamond Gyro" oder "Diamond Force"). Zum Spaß habe ich versucht, es über ein Arduino zu steuern.

Update: Habe das Protokoll herausgefunden; siehe Antwort

Andere haben bereits geteilt ihre Ergebnisse auf einen anderen IR - Spielzeughubschrauber Hacking und sein IR - Protokoll dekodieren. Wirklich cool, aber leider verwendet mein Hubschrauber ein anderes Protokoll. Eine, die ich nicht ganz herausfinden kann. (Ich sollte hinzufügen, dass Elektronik für mich nur ein Hobby ist, also habe ich vielleicht etwas Offensichtliches übersehen).

Ähnlich wie im zweiten Link oben habe ich den Controller auseinander genommen, den IC-Pin gefunden, der die LEDs steuert (die Markierungen des IC wurden übrigens gelöscht), und einen Logikanalysator angeschlossen.

Ich habe viele gute Daten, aber ich kann das Protokoll immer noch nicht herausfinden. Diese Seite ist eine großartige Ressource, aber keines der aufgeführten Protokolle scheint zu passen. Und nichts anderes, was ich gefunden habe, scheint zu dem Signal zu passen, das ich auch aufgenommen habe. Ich muss mir allerdings vorstellen, dass es sich um ein einfaches Standardprotokoll handelt, nur weil es ein billiges kleines Spielzeug ist.

Ich würde mich über Ihre Ideen freuen. Vielleicht sehe ich es nur falsch.
(Mehr Infos unter dem Bild)

Proben von Kanal A.

Signal- / Protokolleigenschaften

Ich habe dies bei 16 MHz aufgenommen, wobei der Controller auf Kanal A eingestellt war. sollte zeitlich genau sein. (Es gibt 3 IR-Kanäle, aus denen Sie auswählen können, aber die Verwendung der beiden anderen Kanäle ändert nicht die Eigenschaften, sondern nur Teile des Pakets selbst.) Die Timings sind sehr konsistent (+/- 10µs max). Pakete werden in unterschiedlichen Intervallen wiederholt, aber mindestens 100 ms voneinander entfernt.

Träger: 38 kHz bei 50% Einschaltdauer

Tiefs:
- Kurz: 285µs
- Lang: 795µs

Höhen:
- Kurz: 275µs
- Lang: 855µs

Immer 17 Höhen pro Paket.

Bedienelemente / Eingänge

Der Heli hat 3 Bedienelemente: "Gas" (dh Hub / Rotordrehzahl), Neigung (vorwärts / rückwärts) und Gieren (Drehung um die Rotorachse), die alle mit 2 Daumenstiften gesteuert werden. Sie haben alle eine Reichweite (nicht nur ein / aus) und werden, soweit ich das beurteilen kann, alle in einem einzigen Paket übertragen. Die linken / rechten Eingänge werden nur gesendet, wenn etwas anderes gesendet wird, also habe ich beim Abtasten das maximale Gas gegeben. Gas- und Tonhöheneingabe für eigene Triggerpakete, die gesendet werden, sobald Sie die Daumenstifte über einen bestimmten Schwellenwert / Totband hinaus schieben (in der Grafik unter dem Etikett "min" wird das erste Paket angezeigt, das gesendet wird, wenn ein Steuerelement langsam über sein Totband hinausgeschoben wird).

Es hat auch Tasten zum Trimmen von links und rechts, da der Heli ( überhaupt ) kein Präzisionsinstrument ist und sich sonst langsam dreht. Die linken / rechten Trimmtasten scheinen leider kein Signal zu senden, das bei jedem Drücken etwas inkrementiert / dekrementiert (was für die Ermittlung des Protokolls nützlich wäre). Es scheint nur ein einziger Befehl zu sein, der dem Hubschrauber sagt, er solle nach links / rechts trimmen, und dann verfolgt er ihn.

Flambino
quelle
Warum nicht einfach die Signalspuren verwenden, die Sie bereits benötigen, um die Pakete roh zu schreiben?
Ignacio Vazquez-Abrams
@ IgnacioVazquez-Abrams Du meinst nur die aufgezeichneten Signale an den Hubschrauber abzuspielen?
Flambino
Sicher. Es ist nicht so, dass der Hubschrauber den Unterschied erkennen kann ...
Ignacio Vazquez-Abrams
@ IgnacioVazquez-Abrams Stimmt, aber soweit ich das beurteilen kann, enthält das Paket alle 3 Steuerelemente (Gas / Pitch / Yaw) und die Steuerelemente des Helis, keine sind nur ein / aus. Um das Ding durch Wiedergabe zu steuern, müsste ich jede einzelne Konfiguration erfassen ... Außerdem möchte ich das Protokoll verstehen
Flambino
@ IgnacioVazquez-Abrams Ups, ich habe irgendwie meinen letzten Kommentar verstümmelt. Gemeint zu sagen: "... das Paket enthält alle 3 Steuerelemente (Gas / Pitch / Gieren) und keines von ihnen ist nur ein / aus".
Flambino

Antworten:

8

Ich erlaube mir, meine eigene Frage zu beantworten, da ich das meiste herausgefunden habe, und dies ist eine gute Möglichkeit, meine Erkenntnisse zu teilen. Mein Dank geht an Olin Lathrop, der mir einen Startplatz und einige Ideen zum Ausprobieren gegeben hat, aber letztendlich hat sich das Protokoll als ganz anders herausgestellt als Olins Vermutung, weshalb ich diese Antwort gepostet habe.


Update: Ich habe eine Folgefrage zu den letzten 8 Bits gepostet , die ich nicht vollständig verstanden habe, und Dave Tweed hat es herausgefunden . Ich werde die Details hier einfügen, damit diese Antwort als vollständige Protokollspezifikation funktionieren kann, aber schauen Sie sich Daves Antwort an.


Ich musste einige verschiedene Dinge ausprobieren, um das herauszufinden, aber ich bin ziemlich zuversichtlich, dass ich es verstanden habe. Seltsamerweise habe ich an keiner anderen Stelle etwas gefunden, das diesem Protokoll ähnelt, aber es kann durchaus ein allgemeines Protokoll sein, von dem ich einfach nichts weiß.

Wie auch immer, hier ist was ich gefunden habe:

Protokoll / Codierung

Beide Impulse und die Zwischenräume werden zum Codieren der Daten verwendet. Ein langer Impuls / Raum ist eine binäre Eins (1) und ein kurzer Impuls / Raum ist eine binäre Null (0). Die Impulse werden unter Verwendung einer Standard-Consumer-Infrarot-38-kHz-Modulation bei einem Tastverhältnis von 50% gesendet.

Die Puls- / Raum-Timings sind in der ursprünglichen Frage enthalten, aber ich werde sie hier der Vollständigkeit halber wiederholen:

 Bit    Pulse     Space
-----+---------+---------
  0  |  275µs  |  285µs
  1  |  855µs  |  795µs

Alle ± 10µs max., ± 5µs typ. Dies basiert auf Proben, die mit einem Logikanalysator bei 16 MHz aufgenommen wurden; Ich habe kein Oszilloskop, daher kenne ich das genaue Profil nicht (dh Anstiegs- / Abfallzeiten).

Pakete werden wiederholt, solange die Steuereingaben angewendet werden und einen Abstand von mindestens 100 ms zu haben scheinen.

Die Paketübertragung beginnt mit einer Präambel "Impuls 1", die fest und nicht Teil der Daten ist. Der folgende Raum codiert das erste Datenbit des Pakets und der letzte Impuls codiert das letzte Bit.

Jedes Paket ist 32 Bit lang und enthält jeden Eingang, den die Fernbedienung bereitstellen kann. Die Werte werden als Little Endian gelesen, dh zuerst als MSB.

Datenstruktur

Nachfolgend finden Sie die Grundstruktur der einzelnen Pakete. Die letzten 8 Bits hatten mich verwirrt, aber das wurde jetzt herausgefunden (siehe unten).

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
--+---------------------------+-----------+---+-------+-----------
 P|    Yaw    |   Throttle    |   Pitch   | T | Chan. |   Check

P: Preamble (always a pulse-1), T: Trim, Chan.: Channel

Bit    Length    Description (see note below)
-----------------------------------------------
0      1         Preamble. High 1
1-6    6         Yaw. Range 0-36 for left-right, 17 being neutral
7-14   8         Throttle. Range 0-134
15-20  6         Pitch. Range 0-38 for forward-back, 17 being neutral
21-22  2         Trim. Left = 1, right = 2, no trim = 0
23-26  4         Channel. A = 5, B = 2, C = 8
27-32  6         Check bits

Hinweis: Die Bereiche basieren auf den höchsten Messwerten, die ich erhalten habe. Das Protokoll ist in der Lage, größere Bereiche zu erreichen - bis zu 255 für Gas, 63 für Pitch / Yaw -, aber bei etwa der Hälfte.
Der Tonhöhenwert scheint eine Totzone von 14-21 (einschließlich) zu haben; Nur Werte von oben oder unten lassen den Hubschrauber tatsächlich reagieren. Ich weiß nicht, ob es beim Gieren dasselbe ist (schwer zu sagen, da der Hubschrauber sowieso instabil ist und sich von selbst nur leicht drehen kann).

Hier ist es grafisch (vergleiche mit der Grafik in der ursprünglichen Frage)

Paketstruktur

Die 6 Prüfbits werden durch XOR-Verknüpfung aller vorhergehenden Werte berechnet. Jeder Wert wird als 6 Bit behandelt. Dies bedeutet, dass die 2 MSBs des 8-Bit-Drosselklappenwerts einfach ignoriert werden. Dh

check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel

Praktische Hinweise

Die Signalzeiten und die Modulation müssen nicht sehr genau sein. Sogar das ungenaue Timing meines Arduino funktioniert trotz zwielichtiger Modulation und ein bisschen Hit and Miss bei der Puls- / Raumdauer im Vergleich zur echten Fernbedienung einwandfrei.

Ich glaube - aber noch nicht getestet -, dass der Hubschrauber einfach am Kanal des ersten Signals einrastet, das er findet. Wenn es zu lange (einige Sekunden) ohne Signal bleibt, scheint es in den "Such" -Modus zurückzukehren, bis es wieder ein Signal empfängt.

Der Hubschrauber ignoriert Nick- und Gierwerte, wenn der Gashebel Null ist.

Die Trimmbefehle werden nur einmal pro Tastendruck auf der Fernbedienung gesendet. Vermutlich erhöht / verringert der Trimmwert einfach einen Wert in der Steuerung des Hubschraubers; Es ist nicht etwas, was die Fernbedienung verfolgt. Daher sollte sich jede Implementierung davon wahrscheinlich an dieses Schema halten und nur gelegentlich den linken / rechten Trimmwert senden, andernfalls wird standardmäßig ein Trimmwert von Null in den Paketen verwendet.

Ich empfehle einen Kill-Schalter, der einfach den Gashebel auf Null stellt. Dadurch fällt der Hubschrauber vom Himmel, erleidet jedoch weniger Schaden, wenn er seine Motoren nicht dreht. Wenn Sie also kurz vor dem Absturz stehen oder etwas treffen, drücken Sie den Kill-Schalter, um zu vermeiden, dass Sie die Zahnräder abisolieren oder die Klingen brechen.

Die IR-LEDs der Originalfernbedienung scheinen eine Wellenlänge von> 900 nm zu haben, aber ich habe keine Probleme mit der Verwendung einer ~ 850 nm-LED.

Der IR-Empfänger des Hubschraubers ist in Ordnung, aber nicht sehr empfindlich. Je heller Ihre IR-Quelle, desto besser. Die Fernbedienung verwendet 3 in Reihe geschaltete LEDs, die auf der 9-V-Schiene anstelle der von der Logik verwendeten 5-V-Schiene sitzen. Ich habe ihre aktuelle Auslosung nicht sehr genau überprüft, aber ich würde wetten, dass es 50 mA sind.

Beispieldaten

Hier sind ein paar Pakete für alle Interessierten (ja, ich habe einen Decoder geschrieben; ich habe das alles nicht von Hand dekodiert). Die Kanal-A-Pakete stammen aus denselben Erfassungen wie die Diagramme in der ursprünglichen Frage.

Channel A                                                       
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000100  10000100  000000  00  0101  000101    Left Mid + Throttle
000000  10000110  010001  00  0101  010010    Left Max + Throttle 
100001  10000110  000000  00  0101  100010    Right Mid + Throttle 
100100  10000100  010001  00  0101  110100    Right Max + Throttle
010001  00000000  001011  00  0101  011111    Forward Min 
010001  00000000  000000  00  0101  010100    Forward Max 
010001  00000000  011000  00  0101  001100    Back Min 
010001  00000000  100101  00  0101  110001    Back Max
010001  00000000  010001  01  0101  010101    Left Trim 
010001  00000000  010001  10  0101  100101    Right Trim 
010001  00000011  010001  00  0101  000110    Throttle 01 (min)
010001  00010110  010001  00  0101  010011    Throttle 02
010001  00011111  010001  00  0101  011010    Throttle 03
010001  00101111  010001  00  0101  101010    Throttle 04
010001  00111110  010001  00  0101  111011    Throttle 05
010001  01010101  010001  00  0101  010000    Throttle 06
010001  01011111  010001  00  0101  011010    Throttle 07
010001  01101100  010001  00  0101  101001    Throttle 08
010001  01111010  010001  00  0101  111111    Throttle 09
010001  10000101  010001  00  0101  000000    Throttle 10 (max)

Channel B
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000000  10000110  010001  00  0010  010101    Left Max + Throttle 
100100  10000110  010001  00  0010  110001    Right Max + Throttle 
010001  00000000  001001  00  0010  011010    Forward Min 
010001  00000000  000000  00  0010  010011    Forward Max 
010001  00000000  010111  00  0010  000100    Back Min 
010001  00000000  100110  00  0010  110101    Back Max
010001  00000000  010001  01  0010  010010    Left Trim 
010001  00000000  010001  10  0010  100010    Right Trim 
010001  00000001  010001  00  0010  000011    Throttle Min 
010001  00110100  010001  00  0010  110110    Throttle Mid 
010001  01100111  010001  00  0010  100101    Throttle High 
010001  10001111  010001  00  0010  001101    Throttle Max 

Channel C
Yaw     Throttle  Pitch   Tr  Chan  Check     Description
-----------------------------------------------------------
000000  10000101  010001  00  1000  011100    Left Max + Throttle 
100100  10000101  010001  00  1000  111000    Right Max + Throttle 
010001  00000000  001010  00  1000  010011    Forward Min 
010001  00000000  000000  00  1000  011001    Forward Max 
010001  00000000  010111  00  1000  001110    Back Min 
010001  00000000  100110  00  1000  111111    Back Max
010001  00000000  010001  01  1000  011000    Left Trim 
010001  00000000  010001  10  1000  101000    Right Trim 
010001  00000001  010001  00  1000  001001    Throttle Min 
010001  00110100  010001  00  1000  111100    Throttle Mid 
010001  01100110  010001  00  1000  101110    Throttle High 
010001  10000101  010001  00  1000  001101    Throttle Max

Wie oben erwähnt, wurden die letzten 8 Bits herausgefunden, aber nur für die Nachwelt, hier sind meine ursprünglichen Gedanken. Fühlen Sie sich frei, es vollständig zu ignorieren, da ich in meinen Vermutungen ziemlich falsch lag.

Die letzten 8 Bits

Die letzten 8 Bits des Pakets sind immer noch ein bisschen rätselhaft.

Die 4 Bits von Bit 23 bis 26 scheinen alle vollständig durch die Kanaleinstellung der Fernbedienung bestimmt zu sein. Durch Ändern des Kanals auf der Fernbedienung wird das Protokoll oder die Modulation in keiner Weise geändert. es ändert nur diese 4 Bits.

Aber 4 Bits sind doppelt so viel, wie tatsächlich zum Codieren der Kanaleinstellung benötigt wird. Es gibt nur drei Kanäle, also sind 2 Bits ausreichend. Daher habe ich in der obigen Strukturbeschreibung nur die ersten 2 Bits als "Kanal" bezeichnet und die anderen beiden als "X" bezeichnet, aber dies ist eine Vermutung.

Unten finden Sie ein Beispiel der relevanten Bits für jede Kanaleinstellung.

Chan.   Bits 23-26
-----+-------------
  A  |  0  1  0  1
  B  |  0  0  1  0
  C  |  1  0  0  0

Grundsätzlich gibt es 2 Bits mehr als nötig, um die Kanaleinstellung zu übertragen. Vielleicht hat das Protokoll 4 Bits beiseite gelegt, um später mehr Kanäle zu ermöglichen, oder so kann das Protokoll in ganz anderen Spielzeugen verwendet werden, aber ich weiß es einfach nicht. Für die größeren Werte verwendet das Protokoll zusätzliche Bits, die weggelassen werden könnten (Gieren / Gas / Pitch könnte mit jeweils etwas weniger auskommen), aber für das Trimmen - das ebenfalls 3 Zustände hat - werden nur 2 Bits verwendet. Man könnte also vermuten, dass der Kanal auch nur 2 Bits ist, aber die nächsten 2 bleiben unberücksichtigt.

Die andere Möglichkeit besteht darin, dass die Prüfsumme des Pakets, beginnend mit den "X-Bits", 8 Bit lang ist und - durch die Magie der Prüfsumme - zufällig immer die Kanaleinstellung widerspiegelt. Aber nochmal: Ich weiß es nicht.

Apropos: Ich habe keine Ahnung, wie diese Prüfbits gebildet werden. Ich meine, es handelt sich um Prüfbits, da sie keinem einzelnen Steuereingang entsprechen und der Hubschrauber nicht zu reagieren scheint, wenn ich mit ihnen herumspiele. Ich vermute, es ist eine Art CRC, aber ich konnte es nicht herausfinden. Die Prüfung dauert 6 bis 8 Bit, je nachdem, wie Sie die "X-Bits" interpretieren. Es gibt also viele Möglichkeiten, die zusammengestellt werden können.

Flambino
quelle
6

Das sieht nicht so schlecht aus. Beachten Sie zunächst, dass alle Nachrichten genau 17 Impulse enthalten. Dies gibt uns sofort einen starken Hinweis darauf, dass kurze Leerzeichen innerhalb einer Nachricht irrelevant sind. Es scheint, dass Daten durch kurze oder lange Impulse codiert werden und dass ein gewisser Abstand zwischen diesen Impulsen akzeptabel ist.

Offensichtlich beginnt jede Nachricht mit einem langen Impuls als Startbit. Damit bleiben 16 Datenbits übrig. Wahrscheinlich sind einige der frühen Bits ein Opcode, möglicherweise eine variable Länge. Wenn ich das tun würde, wären einige der Endbits eine Prüfsumme. Stellen Sie sich vor, die Ingenieure, die die Firmware geschrieben haben, wollten die Dinge für sich einfach halten. Sie können also zunächst davon ausgehen, dass sich irgendwo 8 Datenbits befinden. Überprüfen Sie nun, ob eine der Nachrichten sinnvoll ist.

Nennen wir eine lange a 1 und eine kurze a 0. Es könnte umgekehrt sein, aber wir müssen irgendwo anfangen. Das Startbit abziehen lässt:

1010001101011010 min Gas
1010011101011000 max Gas
1010000001011111 min vorwärts
1010000000011110 max vorwärts
1010000011011101 max zurück
1010000100011010 min zurück
0000010101011100 max links + max Gas
0100010101011110 max rechts + max Gas
1010000101111111 links trimmen
1010000101011011 rechts zuschneiden

Ein paar Dinge tauchen sofort auf. Offensichtlich ist Bit 0 ein Paritätsbit. Andernfalls scheint es ein 3-Bit-Feld <15:13>, einen 8-Bit-Datenwert <12: 5> und ein weiteres 4-Bit-Feld <4: 1> zu geben.

Es sieht so aus, als würde der Datenwert in niedriger bis hoher Bitreihenfolge gesendet, daher ist es wahrscheinlich sinnvoller, die gesamten 16 Bits zu interpretieren, die von dem, was ich zeige, gespiegelt wurden.

Ich habe keine Lust, mehr Zeit damit zu verbringen, aber hoffentlich hat Ihnen das einen Anfang gegeben. Ich würde fortfahren, indem ich die obige Liste mit entferntem Paritätsbit neu schreibe, die ganze Zahl LSB auf MSB kippte und jedes angenommene Feld separat mit einem Leerzeichen zwischen ihm und dem angrenzenden Feld angezeigt wurde. Das kann dazu führen, dass mehr auf Sie herausspringt. Denken Sie auch daran, dass wir möglicherweise den 1/0 Sinn jedes Bits rückwärts haben. Schreiben Sie vielleicht die neue Tabelle in jede Richtung und prüfen Sie, ob etwas in eine Richtung sinnvoller ist.

Olin Lathrop
quelle
Danke, das ist ausgezeichnet! Ich werde gleich loslegen und sehen, was ich finde. Nachdem ich mir andere Protokolle angesehen hatte, begann ich zu denken, dass die Leerzeichen möglicherweise irrelevant waren, aber da sie zwei sehr konsistente Timings hatten, war ich mir nicht so sicher. Ich dachte, sie würden mehr variieren, wenn sie nicht wichtig wären. Wie auch immer, ich werde es ausprobieren.
Nochmals vielen
Huh ... soweit ich das beurteilen kann, die Räume zu tun Materie. Ich konzentrierte mich auf den Gashebel und nahm weitere Proben an 10 verschiedenen Gaspedalpositionen auf. Das Ausschließen von Leerzeichen gab mir keine aussagekräftigen Zahlen, unabhängig davon, wie ich die Konvertierungen durchgeführt habe. Wenn Sie sie jedoch als long = 1, short = 0 einschließen, ergibt sich ein sanfter Verlauf des Drosselklappenwerts von 1 auf 134 (Little Endian).
Ich
Ich habe das Protokoll fast vollständig herausgefunden, aber es gibt noch ein bisschen Rätsel. Ich habe meiner Frage eine Menge Dinge hinzugefügt, wenn Sie es versuchen wollen. Wie auch immer, danke für deine bisherige Hilfe! Ich muss in die richtige Richtung arbeiten.
Flambino
@Flambino: Sieht so aus, als wären Sie dem, was ich getan habe, weit voraus, was sich im Nachhinein als größtenteils falsche Vermutung herausstellte. Ich habe Ihre aktualisierte Frage gelesen, verstehe aber immer noch nicht, wie genau die Länge der Leerzeichen verwendet wird. War es nur Zufall, dass alle von Ihnen gezeigten Muster genau 17 Impulse hatten und dass das letzte zufällig Parität anzeigte, wenn nur die Impulse als 0 oder 1 angenommen wurden?
Olin Lathrop
Ehrlich gesagt war es meistens Versuch und Irrtum von meiner Seite. Da die beiden für Leerzeichen verwendeten Timings genauso genau sind wie die Puls-Timings, dachte ich, dass sie möglicherweise sinnvoll sind. Und wenn das Ignorieren der Leerzeichen keine nützlichen Binärdaten ergab, nahm ich einfach einen langen Impuls = 1 und einen langen Raum = 1 (und einen kurzen Raum / Impuls = 0) an, was mir sofort sehr nützliche Daten lieferte. Das erste Leerzeichen nach dem Präambelimpuls ist also das erste Bit (das Diagramm für max. Rechts + max. Drossel zeigt ein "Leerzeichen 1" als erstes Bit), gefolgt von 16 Impulsen mit 15 weiteren Leerzeichen dazwischen. 32 Bit.
Flambino