Pomoc lub wskazówki dotyczące dekodowania protokołu IR

10

Jakiś czas temu kupiłem prosty i tani mały zabawkowy helikopter sterowany na podczerwień (taki sam jak ten - nazywa się „Diamond Gyro” lub „Diamond Force”). Dla zabawy próbowałem kontrolować to za pomocą Arduino.

Aktualizacja: zrozumiał protokół; Zobacz odpowiedź

Inni już podzielili się swoimi wynikami na temat zhakowania innego zabawkowego śmigłowca IR i odkodowania jego protokołu IR. Naprawdę fajnie, ale niestety mój helikopter używa innego protokołu. Taki, którego nie potrafię zrozumieć. (Powinienem dodać, że elektronika jest dla mnie czysto hobby, więc mogłem przeoczyć coś oczywistego).

Podobnie jak w drugim linku powyżej, rozłożyłem kontroler, zlokalizowałem pin IC kontrolujący diody LED (oznaczenia IC zostały skasowane, nawiasem mówiąc) i podłączyłem analizator logiczny.

Mam dużo dobrych danych, ale wciąż nie mogę ustalić protokołu. Ta strona jest świetnym zasobem, ale żaden z wymienionych protokołów nie wydaje się pasować. I nic innego, co znalazłem, również nie wydaje się pasować do przechwyconego przeze mnie sygnału. Muszę sobie jednak wyobrazić, że jest to prosty, gotowy protokół, tylko dlatego, że jest tanią małą zabawką.

Byłbym wdzięczny za wszelkie twoje pomysły. Może po prostu źle to patrzę.
(Więcej informacji pod obrazem)

Próbki z kanału A

Charakterystyka sygnału / protokołu

Zrobiłem to przy 16 MHz z kontrolerem ustawionym na kanał A; powinien być dokładny pod względem czasowym. (Istnieją 3 kanały IR, z których można wybierać, ale użycie dwóch pozostałych kanałów nie zmienia właściwości, a jedynie części samego pakietu.) Czasy są bardzo spójne (maks. +/- 10µs). Pakiety są powtarzane w różnych odstępach czasu, ale co najmniej w odległości około 100 ms.

Nośnik: 38 kHz przy 50% cyklu pracy


Minusy : - Krótkie: 285µs
- Długie: 795µs


Wzloty : - Krótki: 275µs
- Długi: 855µs

Zawsze 17 szczytów w pakiecie.

Sterowanie / wejścia

Heli ma 3 elementy sterujące: „Przepustnica” (tj. Prędkość podnoszenia / wirnika), pochylenie (do przodu / do tyłu) i odchylenie (obrót wokół osi wirnika), wszystkie kontrolowane za pomocą 2 drążków. Wszystkie mają pewien zasięg (nie tylko włączanie / wyłączanie) i, o ile wiem, wszystkie są przesyłane w jednym pakiecie. Wejścia lewo / prawo są wysyłane tylko wtedy, gdy wysyłane jest coś innego, więc zastosowałem maksymalne otwarcie przepustnicy podczas próbkowania. Sygnał przepustnicy i skoku wysyłany do własnych pakietów wyzwalających jest wysyłany, gdy tylko przesuniesz pałeczki poza próg / strefę nieczułości (na wykresie poniżej etykieta „min” oznacza pierwszy pakiet wysyłany, gdy powoli przesuwasz kontrolę poza strefę nieczułości).

Ma również przyciski do przycinania w lewo i w prawo, ponieważ heli nie jest precyzyjnym instrumentem ( w ogóle ) i zwykle obraca się powoli. Lewy / prawy przycisk przycinania niestety nie wydaje sygnału, który zwiększa / zmniejsza wartość dla każdego naciśnięcia (co byłoby przydatne do ustalenia protokołu); wydaje się, że jest to jedno polecenie, nakazujące helikopterowi przycięcie w lewo / prawo, a następnie śledzi to.

Flambino
źródło
Dlaczego nie skorzystać ze śladów sygnału, które już musisz wypisać na surowo?
Ignacio Vazquez-Abrams
@ IgnacioVazquez-Abrams Masz na myśli po prostu odtwarzanie nagranych sygnałów do helikoptera?
Flambino,
Pewnie. To nie tak, że helikopter będzie w stanie odróżnić ...
Ignacio Vazquez-Abrams,
@ IgnacioVazquez-Abrams To prawda, ale o ile wiem, pakiet zawiera wszystkie 3 elementy sterujące (przepustnica / skok / odchylenie) i elementy sterujące heli, ale żadne z nich nie są po prostu włączone / wyłączone. Aby sterować odtwarzaniem, musiałbym przechwycić każdą konfigurację ... Poza tym chcę zrozumieć protokół
Flambino
@ IgnacioVazquez-Abrams Ups, jakoś zniekształciłem mój ostatni komentarz. Chcę powiedzieć: „... pakiet zawiera wszystkie 3 elementy sterujące (przepustnica / skok / odchylenie) i żaden z nich nie jest tylko włączony / wyłączony”.
Flambino,

Odpowiedzi:

8

Pozwolę sobie odpowiedzieć na własne pytanie, ponieważ większość z nich zrozumiałem, i jest to dobry sposób na podzielenie się swoimi odkryciami. Dziękuję Olinowi Lathropowi za umożliwienie mi rozpoczęcia i pomysłów do wypróbowania, ale ostatecznie protokół okazał się zupełnie inny niż przypuszczenia Olina, dlatego opublikowałem tę odpowiedź.


Aktualizacja: Wysłałem pytanie uzupełniające dotyczące ostatnich 8 bitów, które nie do końca zrozumiałem, i Dave Tweed to rozgryzł . Podam tutaj szczegóły, więc ta odpowiedź może działać jako pełna specyfikacja protokołu, ale idź sprawdzić odpowiedź Dave'a.


Musiałem spróbować różnych rzeczy, aby to rozgryźć, ale jestem całkiem pewien, że to rozumiem. Co dziwne, nie znalazłem niczego podobnego do tego protokołu w innym miejscu, ale równie dobrze może to być wspólny protokół, o którym po prostu nie wiem.

W każdym razie oto, co znalazłem:

Protokół / kodowanie

Zarówno impulsy, jak i spacje pomiędzy nimi służą do kodowania danych. Długi impuls / spacja jest binarna (1), a krótki impuls / spacja jest binarna zero (0). Impulsy są wysyłane przy użyciu standardowej modulacji w podczerwieni konsumenta 38 kHz przy 50% cyklu pracy.

Czasy impulsu / przestrzeni są w pierwotnym pytaniu, ale powtórzę je tutaj dla kompletności:

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

Wszystkie maks. ± 10 µs, ± 5 µs typ. Jest to oparte na próbkach zarejestrowanych za pomocą analizatora logicznego przy 16 MHz; Nie mam oscyloskopu, więc nie znam dokładnego profilu (tj. Czasów narastania / opadania).

Pakiety są powtarzane, dopóki stosowane są wejścia sterujące i wydają się być rozmieszczone w odległości co najmniej 100 ms od siebie.

Transmisja pakietowa rozpoczyna się od preambuły „impuls 1”, która jest stała i nie stanowi części danych. Następująca przestrzeń koduje pierwszy bit danych pakietu, a ostatni impuls koduje ostatni bit.

Każdy pakiet ma długość 32 bitów i zawiera wszystkie dane wejściowe, które może zapewnić pilot zdalnego sterowania. Wartości są odczytywane jako mały endian, tj. Najpierw MSB.

Struktura danych

Poniżej znajduje się podstawowa struktura poszczególnych pakietów. Ostatnie 8 bitów wprawiło mnie w zakłopotanie, ale zostało to już wymyślone (patrz poniżej).

 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

Uwaga: zakresy oparte są na najwyższych odczytach, jakie otrzymałem. Protokół ma większe zakresy - do 255 dla przepustnicy, 63 dla skoku / odchylenia - ale ogranicza się o około połowę.
Wydaje się, że wartość tonu ma strefę nieczułości od 14 do 21 (włącznie); tylko wartości powyżej lub poniżej faktycznie powodują reakcję śmigłowca. Nie wiem, czy to samo dotyczy odchylenia (trudno powiedzieć, ponieważ helikopter i tak jest niestabilny i może po prostu lekko się obrócić).

Tutaj jest w kategoriach graficznych (porównaj z grafiką w pierwotnym pytaniu)

struktura pakietu

6 bitów kontrolnych jest obliczanych przez XOR'ing wszystkich poprzednich wartości. Każda wartość jest traktowana jako 6 bitów. Oznacza to, że 2 MSB 8-bitowej wartości przepustnicy są po prostu ignorowane. To znaczy

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

Wskazówki praktyczne

Czasy sygnału i modulacja nie muszą być bardzo dokładne. Nawet niezbyt dokładne taktowanie mojego Arduino działa dobrze, pomimo podejrzanej modulacji i odrobiny trafień w czas trwania impulsu / przestrzeni w porównaniu do prawdziwego pilota.

Wierzę - ale nie przetestowałem - że helikopter po prostu zatrzaśnie się w kanale pierwszego znalezionego sygnału. Jeśli pozostanie bez sygnału przez zbyt długi czas (kilka sekund), wydaje się, że wraca do trybu „wyszukiwania”, aż ponownie uzyska sygnał.

Śmigłowiec zignoruje wartości pochylenia i odchylenia, jeśli przepustnica wynosi zero.

Polecenia przycinania są wysyłane tylko raz na jedno naciśnięcie przycisku na pilocie zdalnego sterowania. Przypuszczalnie wartość trymowania po prostu zwiększa / zmniejsza wartość we własnym sterowniku śmigłowca; to nie jest coś, czego pilnuje pilot. Tak więc każda implementacja tego powinna prawdopodobnie trzymać się tego schematu i wysyłać tylko okazjonalne przycinanie lewej / prawej wartości, ale w przeciwnym razie domyślnie przyjmuje zerową wartość przycinania w pakietach.

Polecam mieć przełącznik zabijania, który po prostu ustawia przepustnicę na zero. Spowoduje to, że helikopter spadnie z nieba, ale odniesie mniejsze obrażenia, gdy nie będzie obracał silników. Więc jeśli masz zamiar upaść lub uderzyć, naciśnij przycisk zabijania, aby uniknąć zrzucania biegów lub łamania ostrzy.

Wydaje się, że diody IR oryginalnego pilota mają długość fali> 900 nm, ale nie mam problemów z użyciem diody LED ~ 850 nm.

Odbiornik podczerwieni śmigłowca jest w porządku, ale nie jest bardzo czuły, więc im jaśniejsze źródło podczerwieni, tym lepiej. Pilot wykorzystuje szereg 3 diod LED, umieszczonych na szynie 9V zamiast na szynie 5V stosowanej przez układ logiczny. Nie sprawdziłem bardzo dokładnie ich aktualnego losowania, ale postawiłbym 50mA.

Przykładowe dane

Oto kilka pakietów dla wszystkich zainteresowanych (tak, napisałem skrypt dekodera; nie zdekodowałem tego wszystkiego ręcznie). Pakiety kanału A pochodzą z tych samych rejestrów, co wykresy w pierwotnym pytaniu.

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

Jak wspomniano powyżej, opracowano ostatnie 8 bitów, ale tylko dla potomności, oto moje oryginalne myśli. Zapraszam do całkowitego zignorowania tego, ponieważ prawie się myliłem.

Ostatnie 8 bitów

Ostatnie 8 bitów pakietu wciąż jest nieco tajemnicą.

Wszystkie 4 bity od bitu 23 do 26 wydają się być całkowicie zdeterminowane przez ustawienie kanału pilota. Zmiana kanału na pilocie zdalnego sterowania w żaden sposób nie zmienia protokołu ani modulacji; zmienia tylko te 4 bity.

Ale 4 bity to dwa razy tyle, ile faktycznie potrzeba do zakodowania ustawienia kanału; są tylko trzy kanały, więc 2 bity to dużo. Dlatego w powyższym opisie struktury oznaczyłem tylko pierwsze 2 bity jako „Kanał”, a pozostałe dwa oznaczyłem jako „X”, ale jest to przypuszczenie.

Poniżej znajduje się próbka odpowiednich bitów dla każdego ustawienia kanału.

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

Zasadniczo są 2 bity więcej, niż trzeba do przesłania ustawienia kanału. Być może protokół ma 4 bity odłożone na później, aby pozwolić na więcej kanałów, a więc protokół może być używany w zupełnie innych zabawkach, ale po prostu nie wiem. W przypadku większych wartości protokół używa dodatkowych bitów, które można pominąć (odchylenie / przepustnica / skok mogłyby dać sobie nieco mniej), ale w przypadku trymowania - który również ma 3 stany - używane są tylko 2 bity. Można więc podejrzewać, że kanał ma również tylko 2 bity, ale to nie uwzględnia kolejnych 2.

Inną możliwością jest to, że suma kontrolna pakietu ma długość 8 bitów, zaczynając od „bitów X” i - dzięki magii sumowania - po prostu zawsze w jakiś sposób odzwierciedlają ustawienie kanału. Ale znowu: nie wiem.

Mówiąc o tym: nie mam pojęcia, jak powstają te bity kontrolne. Są to bity kontrolne, ponieważ nie odpowiadają one żadnemu pojedynczemu wejściowi sterującemu, a helikopter wydaje się nie reagować, jeśli będę się z nimi bawił. Zgaduję, że to jakiś CRC, ale nie byłem w stanie tego rozgryźć. Test ma długość 6-8 bitów, w zależności od sposobu interpretacji „bitów X”, więc istnieje wiele sposobów, które można połączyć.

Flambino
źródło
6

To nie wygląda tak źle. Najpierw zauważ, że wszystkie wiadomości zawierają dokładnie 17 impulsów. To natychmiast daje nam silną wskazówkę, że krótkie spacje w wiadomości nie mają znaczenia. Wygląda na to, że dane są kodowane przez krótkie lub długie impulsy oraz że pewien zakres odstępów między tymi impulsami jest dopuszczalny.

Oczywiście każda wiadomość zaczyna się długim impulsem jako bitem początkowym. To pozostawia 16 bitów danych. Prawdopodobnie kilka wczesnych bitów to kod operacji, prawdopodobnie o zmiennej długości. Gdybym to robił, kilka bitów końcowych byłoby sumą kontrolną. Wyobraź sobie, że inżynierowie, którzy napisali oprogramowanie, chcieli uprościć sobie sprawę, więc możesz zacząć od założenia, że ​​gdzieś jest 8 bitów danych. Teraz sprawdź, czy któryś z komunikatów ma sens.

Nazwijmy długi 1, a krótki 0. Może być na odwrót, ale musimy gdzieś zacząć. Ściąganie bitów startowych pozostawia:

1010001101011010 min przepustnica
1010011101011000 maksymalna przepustnica
1010000001011111 min do przodu
1010000000011110 maks. Do przodu
1010000011011101 maks. Z powrotem
1010000100011010 min z powrotem
000001010101111100 maks. W lewo + maks. Przepustnica
0100010101011110 maks. W prawo + maks. Przepustnica
1010000101111111 wykończenie lewe
1010000101011011 wykończenie z prawej

Kilka rzeczy wyskakuje od razu. Oczywiście bit 0 jest bitem parzystości. W przeciwnym razie wydaje się, że istnieje 3-bitowe pole <15:13>, 8-bitowa wartość danych <12: 5> i kolejne 4-bitowe pole <4: 1>.

Wygląda na to, że wartość danych jest wysyłana w kolejności od niskiej do wysokiej, więc prawdopodobnie bardziej sensowne jest interpretowanie całych 16 bitów odwróconych od tego, co pokazuję.

Nie mam ochoty spędzać na tym więcej czasu, ale mam nadzieję, że dało to początek. Kontynuowałbym od nowa zapisując powyższą listę z pozbawionym bitu parzystości, liczbą całkowitą odwrócił LSB do MSB, a każde założone pole pokazano osobno ze spacją między nim a polem przylegającym. To może pozwolić, by więcej cię wyskoczyło. Pamiętaj również, że możemy mieć wyczucie 1/0 każdego bitu do tyłu. Być może wypisz nową tabelę w każdy sposób i sprawdź, czy coś ma sens w jedną stronę.

Olin Lathrop
źródło
Dziękuję, to świetnie! Zaraz się nad tym zastanowię i zobaczę, co znajdę. Po przyjrzeniu się innym protokołom zacząłem myśleć, że być może przestrzenie były nieistotne, ale ponieważ miały dwa bardzo spójne czasy, nie byłem pewien. Uznałem, że różnią się bardziej, jeśli nie są ważne. W każdym razie spróbuję.
Jeszcze
Huh ... o ile wiem, przestrzenie mają znaczenie. Skoncentrowałem się na przepustnicy i zarejestrowałem kilka próbek w 10 różnych pozycjach przepustnicy. Wykluczenie spacji nie dało mi żadnych znaczących liczb, niezależnie od tego, jak zrobiłem konwersje. Ale uwzględnienie ich jako długich = 1, krótkie = 0 daje płynny postęp wartości przepustnicy od 1 do 134 (mały endian). Nadal pracuję nad innymi parametrami
Flambino,
Protokół prawie w pełni rozgryzłem, ale wciąż jest trochę tajemnicy. Dodano mnóstwo rzeczy do mojego pytania, jeśli chcesz się na to rzucić. Tak czy inaczej, dziękuję za pomoc do tej pory! Sprawił, że pracowałem we właściwym kierunku.
Flambino,
@Flambino: Wygląda na to, że jesteś daleko przed tym, co zrobiłem na początku, co okazało się w większości błędne domysły z perspektywy czasu. Przeczytałem zaktualizowane pytanie, ale nadal nie rozumiem, jak dokładnie używana jest długość spacji. Czy to tylko przypadek, że wszystkie pokazane wzory miały dokładnie 17 impulsów, a ostatni przypadek wskazywał parzystość, jeśli tylko impulsy są przyjmowane jako 0 lub 1?
Olin Lathrop,
Szczerze mówiąc, z mojej strony były to głównie próby i błędy. Ponieważ 2 taktowania zastosowane dla spacji są tak samo dokładne jak czasy taktowania, pomyślałem, że mogą mieć znaczenie. I kiedy ignorowanie spacji nie dało użytecznych danych binarnych, po prostu założyłem długi puls = 1 i długą spację = 1 (i krótką spację / impuls = 0), co natychmiast dało mi bardzo przydatne dane. Tak więc pierwsza spacja po impulsie preambuły jest pierwszym bitem (wykres maksymalnego prawa + maksymalnego przepustnicy pokazuje „spację 1” jako pierwszy bit), a następnie 16 impulsów, z 15 dodatkowymi spacjami między nimi; 32 bity.
Flambino,