[018] Arduino i piloty

[018] Arduino i piloty

Tym razem będzie nauka i praktyka, bowiem oprócz poznania czegoś nowego zbudujemy coś przydatnego. Bohaterem najbliższych artykułów będą bowiem piloty podczerwieni i odbiorniki tych sygnałów. Piloty znane są od półwiecza co najmniej i po okresie wstępnym, gdy równolegle rozwijano techniki ultradźwiękowe, radiowe, optyczne i podczerwieni, wygrała ostatnia. Praktycznie od lat osiemdziesiątych każdy pilot posiada widoczną dobrze diodę nadawczą pracującą w podczerwieni, która jest zwyczajną diodą LED, tylko pracującą tuż poza widzialnym pasmem, choć nie do końca, bo w przypadku niektórych egzemplarzy w ciemnościach widać lekkie świecenie. Na pewno dobrze widać aktywność owych diod na ekranach cyfrowych aparatów, które sięgają w zakresy dłuższe niż nasze oko.


Niewątpliwie kusi, by zajrzeć do środka takiego pilota, lecz potraktujmy to urządzenie jak czarną skrzynkę: na obudowie mamy przyciski, a ich wciskanie – za pomocą specjalizowanego układu – generuje serie przebiegów, które zasilają diodę świecącą znajdującą się zwykle na krawędzi pilota.

Błyski te oświetlają czuły odbiornik, który przetwarza je z powrotem na sygnały elektryczne. Te zaś tłumaczone są przez bliźniaczy układ już na czynności potrzebne w danym urządzeniu. Kolejne rozkazy najczęściej ustawiają napięcia na wyprowadzeniach, czasem zmieniają wypełnienia przebiegów i tak dalej.

Dla nas najważniejsze jest to, że piloty są tanie, zgrabne i powszechne. Można kupić piloty uniwersalne, można także wykorzystać takie w spadku po urządzeniach, które już zakończyły żywot. Co zatem musimy zrobić, by móc połączyć naszego pilota z Arduino? Będą nam potrzebne dwie rzeczy: sprzęt i oprogramowanie. Zacznijmy od sprzętu.

Tutaj mam dobrą wiadomość. Otóż powszechność pilotów sprawiła, że nie musimy sobie zupełnie zawracać głowy budową dość skomplikowanego odbiornika. Powstała cała rodzina układów scalonych w wyjątkowych obudowach: podobnych nieco do tranzystora, ale z czarnego, a tak naprawdę ciemnoczerwonego tworzywa z charakterystycznym wypukleniem, stanowiącym soczewkę. W tym miejscu znajduje się fototranzystor. Jednak układ ten jest znacznie bardziej skomplikowany. Okazało się, że stworzenie linii optycznej, która przesyła zamienione impulsy elektryczne wprost na impulsy świetlne i z powrotem, działa sprawnie tylko w warunkach idealnych. W warunkach rzeczywistych pilot znajduje się w różnych miejscach i oświetla fototranzystor z różną mocą, a co gorsza – ten jest oświetlany także z innych źródeł, choćby światłem słonecznym. W praktyce całość działałaby tylko w nocy i przy dokładnym celowaniu pilotem w odbiornik.

Użyto tutaj szeregu zmyślnych rozwiązań. Po pierwsze, nie przesyła się światła zmodulowanego wprost przebiegiem szeregowym, a moduluje się nim przebieg o częstotliwości kilkudziesięciu kiloherców, najczęściej 36. Pracując na jednej tylko częstotliwości nośnej, możemy korzystać z dobrodziejstw na podobieństwo tych znanych z radia. A więc można tę częstotliwość odfiltrować, odrzucając wszelkie inne sygnały, w tym także stałe, których źródłem jest światło słoneczne czy oświetleniowe. Dzięki temu nasz pilot pracuje praktycznie w każdych warunkach. Jedna stała częstotliwość o stałej amplitudzie pozwala w łatwy sposób zmieniać wzmocnienie. Dopóki mocy wystarczy, pilot będzie pracować tak samo dobrze z odległości kilku metrów jak i kilku centymetrów. Do tego sam przebieg cyfrowy zwykle jest kodowany jeszcze na wstępnym etapie do któregoś z systemów odpornych na zniekształcenia, jak na przykład kodu Manchester, który ogranicza pasmo od dołu, eliminując szeregi kolejnych poziomów o tej samej wartości. Ale tego wszystkiego nie musimy wiedzieć, ponieważ jest to poza naszym zasięgiem. Tym zajmuje się pilot i ta mała kostka, na wyjściu której dostajemy czysty, cyfrowy sygnał.

Czas na rzecz drugą: oprogramowanie. Jak łatwo się domyślić, wspomniany cyfrowy sygnał nie należy do jednego standardu. Historia pilota to nie odkrycie Marii Skłodowskiej. Gdy powstała na to moda, każdy producent sprzętu AGD opracowywał własne rozwiązania. Szybko stało się to problemem, więc niektórzy zakładali spółdzielnie, dogadując się między sobą. Faktem jest, że standardów tych bardziej znanych jest kilkadziesiąt, a takich spotykanych na co dzień – kilka.

Z tego powodu miłośnicy gadżetów mieli takich pilotów sporo, osobno do każdego rozwiązania i tylko szczęśliwy traf sprawiał, że można było używać jednego do kilku urządzeń. Powstał rynek pilotów uniwersalnych, potrafiących rozmawiać w różnych językach i mogących uczyć się, czyli programować. Bardzo to było wygodne, ponieważ można było sobie stworzyć takiego superpilota, jednego i z funkcjami naprawdę użytecznymi.

Czy istniały próby standaryzowania pilotów? Tak, ale wyszło z tym jak z językami, którymi posługują się ludzie. Ktoś kiedyś wymyślił język uniwersalny: esperanto. Miał być łatwy, konkretny, pozbawiony wyjątków i dla wszystkich. Czymś takim jest protokół RC5. Jest po prostu śliczny: każdy rozkaz składa się z 14 bitów, w których zawarto adres urządzenia, a może być ich 32 oraz 64 różne funkcje. Zmieściła się tam nawet informacja, czy przycisk jest już trzymany dłużej i wpadł w autorepetycję.

Niestety, z RC5 wyszło jak z esperanto. Może lepiej, bo trochę pilotów w tym systemie pracuje. Ale, jak na świecie wygrał język angielski, tak wśród pilotów zdaje się prym wieść system stworzony przez firmę NEC. Z jakiegoś powodu został pokochany przez chińskie wytwórnie bubelków i obecnie praktycznie wszystkie małe piloty sterujące diodami świecącymi czy innymi fotoramkami używają tego systemu.

Tutaj wszystko mamy inaczej, choć jakiś porządek wciąż jednak jest. Długość bitów jest zmienna. Do tego mamy dodatkowe sygnały startu i zakończenia nadawania ramki, o jeszcze innych długościach. Tym razem przesyła się 32 bity, a konkretniej: bajt adresu urządzenia, bajt funkcji oraz to samo po zanegowaniu. Urządzenie może porównać obie pary bajtów i jeśli się różnią, odrzucić całość. Protokół ten został rozszerzony, łamiąc zasadę nadawania zanegowanych wartości. Dzięki temu można było poszerzyć pulę adresów do 65536, ale ramka nie miała już stałej długości. Z tym właśnie systemem spotykamy się dziś najczęściej. Wypada wspomnieć, że RC5 także doczekał się poszerzenia do RC6, lecz tutaj dla odmiany nie mamy żadnej kompatybilności i w zasadzie jest to zupełnie inny system. A z tych popularnych jest jeszcze sporo: Sony – SIRC i odmiany, własne stworzyli Samsung, Sharp, JVC, Sanyo, Panasonic, Denon i wiele innych. Z każdym da się wygrać, ale nie z każdym trzeba walczyć.

Weźmy się w końcu do pracy i stwórzmy moduł, który zrozumie języki pilotów, umożliwiając Arduino wykonywanie poleceń właśnie za pomocą pilota. Układ sprzętowy będzie niezwykle prosty: potrzebna nam będzie ta malutka kostka, którą podłączymy do wyprowadzenia drugiego lub trzeciego płytki UNO.

Musimy jeszcze zadbać o zasilanie układu. Aplikacja przewiduje umieszczenie szeregowo rezystora o wartości 100 omów i dodatkowego kondensatora filtrującego.

Na płytce edukacyjnej TME układ ten został już umieszczony i podłączony do portu trzeciego. Kupując taki układ osobno, powinno się użyć takiego, który pracuje przy częstotliwości 36 kHz, bo taka jest najbardziej popularna wśród pilotów. Program także nie będzie szczególnie rozbudowany, bo na tym etapie służy tylko identyfikacji konkretnych komunikatów. Co już z tym zrobimy, pozostawiam wyobraźni. Od najprostszych rozwiązań typu włączanie lampki, po zaawansowane sterowania np. kolejką elektryczną.

// #define IR_SMALLD_NEC                                   // Jeden z dostępnych protokołów do wyboru.
#define IR_SMALLD_NECx
// #define IR_SMALLD_RC5
// #define IR_SMALLD_SAMSUNG
// #define IR_SMALLD_SAMSUNG32
// #define IR_SMALLD_SIRC12
// #define IR_SMALLD_SIRC15
// #define IR_SMALLD_SIRC20
// #define IR_SMALLD_SIRC

#include <IRsmallDecoder.h>   // Biblioteka obsługi odbiornika podczerwieni.
IRsmallDecoder irDecoder(3);  // Port, do którego został podłączony odbiornik podczerwieni.
irSmallD_t irData;            // Nazwa zmiennej przechowującej przychodzące dane.

void setup() {
  Serial.begin(9600);                                       // Inicjuj przesyłanie danych portem szeregowym.
  Serial.println("Czekam na dane z pilota podczerwieni.");  // Komunikat powitalny.
}

void loop() {
  if (irDecoder.dataAvailable(irData)) {  // Jeśli nadszedł komunikat, wyświetl dane.

    Serial.print("\nadres pilota: ");  // Adres pilota (maksymalnie 16 bitów).
    Serial.print(irData.addr);

    Serial.print(" \tdana: ");  // Kod przycisku (maksymalnie 8 bitów).
    Serial.print(irData.cmd);

    Serial.print(" \tautorepetycja: ");  // 0 albo 1 - jeśli przycisk został przytrzymany.
    Serial.print(irData.keyHeld);
  }

  // irDecoder.disable();                                  // Wyłącz obsługę pilota - odciąża przerwania.
  // irDecoder.enable();                                   // Włącz obsługę pilota.
}

Potrzebna nam będzie biblioteka przetwarzająca dane z pilotów. Jest ich kilka, niektóre rozpoznają dziesiątki systemów albo mają bardzo rozbudowany algorytm, umożliwiający tworzenie całych akcji. Wybrałem bibliotekę IRsmallDecoder, prostą i przejrzystą, w większości wypadków wystarczającą do powierzonych zadań. Potrafi rozmawiać w językach NEC-a, Samsunga, Sonego oraz RC5.

Po ściągnięciu IRsmallDecoder musimy skonfigurować kilka elementów związanych z tą biblioteką. Przede wszystkim na wstępie wybrać standard, bo jednocześnie może działać tylko jeden. Wypisałem wszystkie i użyłem ukośników do zamienienia nieaktywnych w komentarz. Tak na marginesie, to jest najprostszy sposób wyłączania fragmentów programu. Po zamianie na komentarz nie są uwzględniane przez kompilator. W zależności od potrzeb, należy „odkomentować” jedną z linii zaczynającą się od wyrażenia #define IR_SMALLD_ Ja tu sobie wybrałem standard NECa.

IRsmallDecoder irDecoder(3);  // Port, do którego został podłączony odbiornik podczerwieni.
irSmallD_t irData;            // Nazwa zmiennej przechowującej przychodzące dane.

W tych wierszach wskazujemy port, do którego podłączony jest odbiornik, a poniżej – nazwę zmiennej z danymi, które do nas przyjdą. Ponieważ to program edukacyjny, dane te nie będą niczego wykonywać. Zostaną jedynie wyświetlone na ekranie komputera i teraz poznamy metodę na to, jak to zrobić. Otóż Arduino IDE zawiera pewien nieomawiany przeze mnie dotąd element, do którego dostać się można, klikając w ostatnią ikonkę na górze.

Teraz otworzy się nam okno, w którym pojawi się wszystko, co wyślemy do „dużego” komputera. A jak to zrobimy? Korzystając dokładnie z tej samej drogi, którą programujemy „mały” komputer, czyli Arduino. Otóż istnieje sposób, by tym łączem przesyłać dane z Arduino do programu monitora, który otworzy się nam po kliknięciu wspomnianej ikony. Wymaga to tylko jednej instrukcji wstępnej, inicjującej ową drogę:

Serial.begin(9600);                                       // Inicjuj przesyłanie danych portem szeregowym.

Cyferki, które tu widzimy określają szybkość pracy łącza szeregowego, czyli wspomnianej drogi. Może ona przyjmować kilka standardowych wartości i ważne jest, by zarówno zadeklarowana jak i ustawiona w programie monitora były takie same. 9600 bps jest wartością domyślną, ale zwykle ustawia się wartości znacznie wyższe, by nie opóźniać pracy szkiców Arduino. A jak wysyła się już konkretne komunikaty? W ten sposób:

Serial.println("Czekam na dane z pilota podczerwieni.");  // Komunikat powitalny.

Po wyrażeniu Serial.println, w nawiasie należy umieścić treść do wysłania. Jeśli będzie to tekst, musimy zamknąć go cudzysłowem. Istnieje bliźniacze wyrażenie Serial.print, które nie dodaje na końcu znaku entera i kolejne wyrażenia będą wtedy zestawiane jedno za drugim. W naszym przypadku następne pojawi się pod poprzednim. Zatem po skompilowaniu programu i otwarciu ekranu monitora ujrzymy napis Czekam na dane z pilota podczerwieni.

Potem już program wpada w pętlę. Z chwilą, gdy pojawi się komunikat, otrzymamy trzy informacje. W zmiennej addr – adres pilota, w tym przypadku jest to wartość szesnastobitowa, ustalona przez producenta pilota. W ten sposób możemy zawęzić współpracę do pilota o stałym adresie, blokując inne, które wysyłają te same dane. Częściej jednak dane te ignoruje się.

W kolejnej zmiennej cmd znajduje się kod przycisku o wartości ośmiobitowej, czyli może być cyfrą z przedziału od zera do 255. To jest dla nas najbardziej istotna informacja. Po zidentyfikowaniu – za pomocą choćby tego programu – co który przycisk wysyła, możemy już wykorzystać tę wiedzę i na przykład jednym przyciskiem włączać światło, a drugim wyłączać.

W końcu mamy trzecią zmienną, o nazwie keyHeld, która przyjmuje wartość jeden, gdy nastąpi autorepetycja, to znaczy gdy przycisk na pilocie będzie trzymany dłużej i zero, gdy dopiero został naciśnięty. Tutaj dla odmiany możemy ignorować serie komunikatów, jeśli z jakichś powodów jest to dla nas ważne.

I to właściwie wszystko. Dla porządku wymienię jeszcze dwa rozkazy związane z tą biblioteką. irDecoder.disable() wyłącza pracę biblioteki, odciążając zasoby, ponieważ korzysta ona z przerwań. irDecoder.enable() z powrotem włącza ją. Obie te instrukcje zamieściłem dla informacji, ale wyłączyłem, oznaczając symbolem komentarza.

Dalszy ciąg, jak mówiłem, zależy już od pomysłowości użytkownika. Po analizie kodów przycisków możemy stworzyć cały algorytm działań. Od stworzenia własnego odtwarzacza muzyki czy sterowania radiem, po rozbudowany sterownik wykonawczy inteligentnego domu, korzystający z szybkiej i odpornej na różnego rodzaju problemy komunikacji lokalnej, działającej w oparciu o podczerwień, a nie jak to zwykle bywa obecnie – wi-fi. Ale o tym napiszę już w innym artykule.

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2024 arduino.pl