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)
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ć.