Dekodowanie sygnału PPM z odbiornika to podstawowe zadanie, umożliwiające budowę różnych urządzeń wykonawczych, rozszerzających możliwości aparatury RC. Na profesjonalnym poziomie nie jest to zadanie banalne, jednak platforma Arduino umożliwia poradzenie sobie z tym tematem w prosty (choć niekoniecznie wydajny) sposób, co jednak wydaje się wystarczającym rozwiązaniem w niezbyt wymagających zastosowaniach, kiedy procesor nie musi robić zbyt wiele.
Na początek jednak trochę wyjaśnień odnośnie sygnału PPM. Jest to rodzaj modulacji, który stał się najpopularniejszym standardem w aparaturach RC, umożliwiającym chyba pierwszy raz na dużą skalę współpracę nadajników i odbiorników różnych producentów. Skrót PPM pochodzi od angielskiego określenia Pulse Position Modulation - czyli modulacja położenia impulsu.
Jeśli zerkniemy na wykresy czasowe, ilustrujące jak to działa, to w górnej części widzimy sygnał wyjściowy z nadajnika. Tak to mniej więcej wygląda, kiedy podłączymy oscyloskop do portu trenera w aparaturze, przy czym w niektórych nadajnikach ten sygnał jest dodatni w innych ujemny. Odległość pomiędzy kolejnymi „wąskimi” impulsami (opadające lub narastające zbocze) określa roboczą wartość impulsu dla kolejnych kanałów RC (stąd właśnie określenie - modulacja położenia impulsu - dotyczy nadajnika a nie odbiornika). Wartość neutrum dla danego kanału odpowiada szerokości impulsu równej 1,5 milisekundy, minimum to 1msec, maksimum - 2msec. Jeden pełen cykl dla 8 kanałów (1 ramka) to standardowo ok 20msec, co odpowiada częstotliwości 50Hz (tyle razy na sekundę jest przesyłany komplet informacji z nadajnika do odbiornika). Wykres przykładowo pokazuje sytuację, kiedy kan1 jest ustawiony na minimum, kan4 na maksimum, pozostałe kanały w neutrum.
Kolejny wykres pokazuje teoretyczną sytuację, kiedy wszystkie kanały są ustawione na maksimum (2 msec), wtedy przerwa pomiędzy ostatnim impulsem (kanał 8) bieżącej ramki a kolejnym impulsem następnej (kanał 1) staje się dużo krótsza. To tłumaczy, dlaczego modulacja PPM obsługuje maksymalnie 8 kanałów. Taka przerwa jest wymagana, aby dekoder w odbiorniku był w stanie rozpoznać kolejne ramki i musi mieć określoną w standardzie długość. W tej sytuacji 9 kanał w ramce trwającej 20msec już się po prostu „nie mieści”.
Wykresy poniżej to przebiegi zarejestrowane przeze mnie prostym analizatorem stanów logicznych dla kilku typowych odbiorników, często używanych przez modelarzy Pokazują jak standard wygląda w praktyce i mogą pomóc w opracowaniu algorytmu dekodowania dla konkretnego odbiornika. Za wyjątkiem jednego przypadku (Turnigy), we wszystkich pozostałych sygnał pochodził z nadajnika Graupner, gdzie przepustnica jest na kanale 1 i była ustawiona na minimum.
Odbiornik 35Mhz Jeti Rex 5+ to przykład „klasycznej” technologii, w której dekodowanie odbywa się metodą hardware'ową przy pomocy dedykowanego układu scalonego. Tak kiedyś budowano wszystkie odbiorniki, kiedy technologia procesorowa nie była jeszcze dostępna. W tym wypadku, to co się pojawia na wyjściu jest prawie dokładnym odzwierciedleniem tego, co wysyła nadajnik. Widzimy, że szerokość impulsu na kanale 1 wynosi ok.1,1 msec, (gaz na minimum), pozostałe kanały są w neutrum (ok. 1,5msec), zaś czas jednej „ramki” to ok 22msec - taki sygnał odbiornik dostaje z nadajnika.
Bardzo podobnie wyglądają wykresy dla 7-kan. odbiornika 35Mhz Hitec HFD-07RA. Nic w tym dziwnego, bo nadajnik jest ten sam, a oba w/w odbiorniki są zbudowane w podobnej technologii.
Odbiornik 35Mhz Jeti Rex 7 MPD jest już wyposażony w dekoder software'owy na procesorze, w tym wypadku jednak producent tak zaprojektował algorytm, że sygnał na wyjściach odbiornika jest standardowy. Różnica w stosunku do wcześniej opisywanych odbiorników polega na tym, że w tamtych przypadkach przy zaniku sygnału z nadajnika sygnał na wyjściach odbiornika również zaniknie, w tym wypadku mikroprocesor wygeneruje na wyjściach sygnał odpowiadający ostatnio zapamiętanym wartościom.
Inaczej wygląda sytuacja z popularną obecnie aparaturą 2,4Ghz Turnigy T9x i „procesorowym” odbiornikiem T9x8C V2. O ile z punktu widzenia kompatybilności urządzeń (serwa itp) istotnie jest utrzymanie na wyjściach standardu (impuls od 1msec do 2msec co ok. 20msec) to kolejność w jakiej pojawiają się impulsy na wyjściach kanałowych nie jest obowiązkowa, w zasadzie projektant ma wolną rękę i może algorytm zbudować tak jak mu wygodnie lub jak pozwala na to zastosowany procesor. W tym wypadku zaskakujące jest to, że impuls na kanale 3 pojawia się wcześniej niż na kanale 2. Upewniłem się kilka razy, czy dobrze podłączyłem analizator, ale wszystko było OK. Dodatkowym potwierdzeniem była szerokość impulsu na na kanale 3, w tej aparaturze kan3. to przepustnica (kan1 - lotki, kan2 - wysokość), która była ustawiona na minimum. Długość ramki w tym przypadku jest bliska standardowi (prawie 20msec, częstotliwość - 51Hz). jeśli zaś zamienić miejscami przewody pomiarowe (kan2 z kan3), to tak jak na drugim wykresie sygnał („czasówka”) wygląda całkowicie standardowo. Natomiast fakt, że impulsy na kanałach 1 i 2 nie następują bezpośrednio po sobie, można wykorzystać w algorytmie dekodującym te dwa kanały, wrócimy jeszcze do tej kwestii później.
Jeszcze inaczej ma się sytuacja w odbiornikach 2,4Ghz FrSky. W 6-kan odbiorniku D6Fr sygnały na wyjściach pokazują się parami - kan1 z kan2, kan3 z kan4 i kan5 z kan6. Szerokości impulsów są standardowe, jednak (co ciekawe), mimo że moduł nadawczy FrSky jest podłączony do modulatora Graupner (ten sam nadajnik co wcześniej), to długość „ramki” wynosi 18msec (częstotliwość 55Hz). Na wykresie obserwujemy jednak jeden cykl z wielu, nie ma pewności, że to stała wartość. Podejrzewam, że procesor dodaje od czasu do czasu dodatkową ramkę z ostatnio zapamiętanymi wartościami, gdyż informacja z modulatora Graupner jest przesyłana z częstotliwością 45Hz, czyli rzadziej niż informacja wychodzi z odbiornika (51Hz).
Z kolei w odbiorniku D8R-II Plus sygnały na wyjściach pojawiają się „trójkami” dla pierwszych 6 kanałach oraz kan7/8 „w parze”. Taki sposób obsługi wyjść wynika prawdopodobnie z faktu, że odbiornik (podobnie jak D6Fr) jest wyposażony w telemetrię, w związku z czym procesor potrzebuje dodatkowego czasu jej obsługę. Dzięki generowaniu kilku wyjść jednocześnie uzyskuje się dodatkowo 8-9 milisekund na przetwarzanie innych zadań. Między grupami impulsów jest mała przerwa (min.ok. 0,4msec) i ten fakt również można wykorzystać przy projektowaniu własnego dekodowania.
Przejdźmy teraz do konkretnych testów dekodowania przy pomocy platformy Arduino. Opisane poniżej przykłady są bardzo prymitywnym rozwiązaniem i bazują na poleceniu pulseIn(wejscie, HIGH); gdzie wejście oznacza numer pinu na którym badamy czas trwania impulsu, HIGH - stan (HIGH/LOW), który ma być badany. Funkcja oczekuje na pojawienie się na danym wejściu impulsu wysokiego i zwraca jego długość w mikrosekundach. Procesor w tym czasie nic nie robi oczekując na pojawienie się impulsu, nie może więc wykonywać innego kodu użytkowego. Teoretycznie przy obsłudze 8 kanałów przez 90% czasu będzie zajmował się tylko tym. Taka prosta metoda w odniesieniu do detekcji PPM, przypomina trochę wożenie 1kg ziemniaków 3-tonową ciężarówką ze sklepu odległego o 20m od domu, ale mimo niskiej efektywności zabronić tego nie można. Bardziej eleganckie i wyrafinowane rozwiązania, bazujące na obsłudze przerwań i timerów, wymagają znacznie więcej wiedzy i na tym etapie nie są to jeszcze sposoby dla mnie (chodzi o stosowanie ze zrozumieniem), szczególnie że i prymitywne sposoby również się sprawdzają. Czy zastosowałbym tę metodę do obsługi mikserów powierzchni sterowych w szybko latającym modelu? - raczej nie, ale do obsługi urządzeń pomocniczych typu „RC-switch” lub sterowania wolniej jeżdżących lub pływających modeli - jak najbardziej tak.
Pierwsza próba to dekodowanie jednego kanału z odbiornika RC. Odbiornik jest zasilany z Arduino (+5V, GND), a wybrane wyjście (tu kan2.) podłączone do wejścia procesora. Ogólnie przy tego rodzaju detekcji ważny jest moment jej rozpoczęcia, tak aby to nastąpiło jeszcze zanim badane wejście przejdzie w stan wysoki. Spróbowałem to zrobić w ten sposób, że detekcja rozpoczyna się po zbadaniu, że wejście jest w stanie niskim. Program do tego testu to ppm_test1 (pobierz). Długość rozpoznanego impulsu w mikrosekundach (czyli neutrum = 1500) jest przesyłana do programu terminalowego, który w tym przypadku trzeba ustawić na większą prędkość transmisji (tu 57600bps). Poruszamy w nadajniku drążkiem przypisanym do kanału, który dekodujemy, a na ekranie obserwujemy zmieniające się wartości z zakresu 1000-2000. Dla lepszej czytelności na terminal jest posyłana co 10-ta odczytana wartość.
Kolejna próba to detekcja dwóch kanałów. Tutaj sprawy nieco się komplikują. Na podstawie wcześniejszego opisu z wykresami różnych odbiorników widać, że nie wiedząc w jaki sposób impulsy pojawiają się na wejściach odbiornika można napotkać na problemy wynikające z faktu, że wygląda to w rzeczywistości inaczej niż się spodziewamy planując algorytm. Tak było i w moim przypadku, przeprowadziłem trochę nieudanych prób, ale zanim przy pomocy analizatora doszedłem do tego co jest przyczyną, zastosowałem rozwiązanie, które wydaje się pewne. Badane dwa kanały sumuję na prostym sumatorze złożonym z dwóch diod i rezystora, ta suma jest podana na wejście 12, natomiast każdy z kanałów na oddzielne wejścia 8 i 10 odpowiednio. Detekcja rozpoczyna się kiedy suma (czyli każdy z badanych kanałów) jest w stanie niskim i w bieżącej ramce badany jest 2-gi kanał odbiornika, a w kolejnej ramce 3-ci. To oznacza, że czytamy kanały 2 razy rzadziej niż są nadawane (25Hz zamiast 50Hz), mnie to jednak nie przeszkadza, gdyż układ jest przeznaczony do sterowania prostym modelem kołowym (o tym w kolejnym artykule) i sprawdził się w praktyce zarówno z klasycznym odbiornikiem „starego” typu (Jeti 5+) jak i z procesorowym D6FR. Szczegóły w komentarzach programu ppm_test2 (pobierz).
Kolejny test to przykład zaplanowania algorytmu, kiedy zna się wykresy czasowe konkretnego odbiornika - program ppm_test3 (pobierz). Jeśli chciałbym do sterowania dwoma kanałami (lotki i wysokość) użyć aparatury Turnigy9x (czyli kanały 1 i 2), to patrząc na wykresy widzę, że impulsy z tych kanałów nie występują wprost po sobie (są oddzielone impulsem z kanału 3 - gaz). Mając tę pewność używam kanału 8 jako „wyzwalacz” detekcji i kiedy osiągnie on stan wysoki, rozpoczynam oczekiwanie na kan1. Natychmiast po detekcji impulsu z kan1 rozpoczynam oczekiwanie na kan2. Wydaje się, że taki algorytm działa prawidłowo i tym przypadku wartości są czytane przy każdej ramce (czyli 50Hz).
Na zakończenie warto zaznaczyć, że w związku z szybko rozwijającym się rynkiem różnego rodzaju urządzeń elektronicznych wspomagających pilotaż (autopiloty, stabilizatory lotu, sterowniki kopterów itp) coraz popularniejsze staje się dekodowanie sygnału CPPM (combined PPM), czyli dekodowanie pełnych 8-u kanałów PPM z wnętrza odbiornika (sygnał wchodzący na dekoder kanałowy). W przypadku starszych odbiorników modelarze „wyciągają” ten sygnał na zewnątrz, w przypadku nowszych konstrukcji niektórzy producenci - np. FR-Sky, umożliwiają przełączanie odbiornika między generowaniem pojedynczych (zdekodowanych) wyjść kanałowych lub generowaniem „zbiorczego” sygnału CPPM. To drugie rozwiązanie cieszy się sporą popularnością wśród konstruktorów „automatów” m.i. z tego powodu, że informację o 8-u kanałach wyprowadza się jednym przewodem i „zużywa” ono w procesorze 1 wejście, podczas gdy przy detekcji pojedynczych kanałów musi być to 8 przewodów do odbiornika i kilka wejść procesora.
Aktualizacja 30.12.2015
Miałem możliwość przetestować kilka odbiorników FlySky – firmy, która jest jest producentem aparatur również dla innych marek – np. Turnigy. Poniżej diagramy sygnału PPM na wyjściach tych odbiorników.
6-kanałowy odbiornik FS-RB6, pracujący w systemie modulacji AFHSD jest przeznaczony zarówno do starszych aparatur (np. TH9X) jak i do nowszych – 6-kanałaowej FS-i6 oraz 10-kanałowej FS-i10 (po ustawieniu odpowiedniego trybu modulacji). Mimo że to odbiornik systemu 2,4GHz, to w przeciwieństwie do opisanych wyżej, daje na wyjściach klasyczny (jak w teorii) sygnał PPM, przypominający „nieprocesorowe” odbiorniki 35Mhz. Moim zdaniem dobra propozycja do różnych eksperymentów elektronicznych, szczególnie że to bardzo tani sprzęt.
FS-iA6 to 6-kanałowy odbiornik pracujący w paśmie 2,4Ghz, przeznaczony do aparatur FS-i6 oraz FS-i10, z modulacją AFHDS2 i telemetrią. Tutaj sygnały wyjściowe wyglądają jeszcze inaczej niż we wszystkich wcześniej prezentowanych odbiornikach – a mianowicie na wszystkich kanałach sygnał jest generowany jednocześnie (a dokładniej prawie jednocześnie). To może stanowić utrudnienie dla najprostrzego dekodowania więcej niż jednego sygnału wyjściowego.
Odbiornik FS-iA6B to „mocniejsza” wersja FS-iA6, wyposażona w dodatkowe gniazda do podłączenia zewnętrznych modułów telemetrii a także urządzeń magistrali iBus (sBus w wersji FlySky). Na diagramach widać, że algorytm dekodowania PPM jest w obu tych odbiornikach jednakowy.
Aktualizacja 03.10.2016
Kolejny odbiornik, który miałem okazję przetestować, to RX-F801 do systemu FR-Sky, tzw. „DIY FR-Sky”. Więcej o tym odbiorniku można przeczytać w innym artykule.
Odbiornik ten może pracować w kilku trybach, w zależności od tego jaki „firmware” został załadowany, ja testowałem go z oprogramowaniem z sierpnia 2016, w wersji z telemetrią. Jak widać na wykresach powyżej, pierwszy tryb PPM wygląda „klasycznie”, podobnie jak w odbiornikach analogowych - czyli impulsy na kolejnych kanałach układają się w czasie jeden za drugim, kanałów jest 7 z racji tego, że Pin 8 w tym trybie jest przeznaczony do telemetrii. Ramka jest powtarzana co 22,5msec, co daje częstotliwość 44,5Hz, czyli trochę mniej niż standard 50Hz.
Drugi tryb pracy tego odbiornika, to klasyczny PPM-Sum (CPPM), gdzie na jedno wyjście jest podawany „sumowany” sygnał PPM (negatywny). W tym przypadku szerokości impulsu kanałowego (1-2msec) odpowiada okres impulsu (opadające-opadające zbocze). Tu ramki również są powtarzane co 22,5msec, a przerwa synchronizacyjna ma 11,6msec, ale (tak jak było to wyjaśnione na początku artykułu) wartość ta jest zmienna i zależy od tego, w jakim położeniu są drążki w nadajniku. W tym trybie odbiornik generuje sygnał dla 8 kanałów i ta postać szczególnie dobrze się nadaje się do dekodowania przy pomocy mikrokontrolera z użyciem jednego wejścia, co zamierzam wkrótce sam sprawdzić w praktyce. Odbiornik ma jeszcze jeden tryb „FrSKy S-Bus”, ale tego już nie sprawdzałem, bo wymagałoby to wyprowadzenia ze środka dodatkowego sygnału na zewnątrz, a nie mam żadnych dodatkowych urządzeń FrSky, pracujących w tym standardzie. W każdym razie wykres powinien wyglądać podobnie jak pokazany wcześniej iBus firmy FlySky.
Na zakończenie jeszcze uwaga odnośnie terminologii. W różnych opisach zaczynają się pojawiać określenia PWM na oznaczenie klasycznego trybu pracy PPM, natomiast PPM jest używane w sensie CPPM. Być może ten podział w przyszłości wejdzie na stałe do terminologii modelarskiej. Ja w tym artykule na razie trzymam się określeń używanych od kilkudziesięciu lat.