[019] Arduino pilotem

[019] Arduino pilotem

Ostatnio pisałem o pilotach i metodach współpracy tychże z Arduino. Czas na drugą część, w której napiszę tym razem jak z Arduino można zrobić pilota. Odwrócenie roli w tandemie pilot – odbiornik ma równie wiele zastosowań, choć oczywiście w sytuacjach zupełnie innych. Można je podzielić między dwie grupy. W pierwszej Arduino będzie sterować za pomocą podczerwieni… no właśnie, nie tylko różnego rodzaju urządzeniami, ale także innym Arduino, bo przecież nic nie stoi na przeszkodzie, by stworzyć sobie taki system.


Jednak typowo taki programowalny pilot będzie umożliwiał nie tylko dublowanie działania oryginalnego pilota, lecz także, a czasem – przede wszystkim – stworzenie makrokomend, wykonujących po sobie szereg działań. Ma to szczególne znaczenie obecnie, gdy wokół nas pojawia się tak wiele elementów inteligentnego domu z możliwością sterowania podczerwienią. Zatem jeden malutki i niedrogi komputerek może tworzyć na przykład sceny świateł złożonych z wielu elementów, wysyłając kolejne instrukcje adresowane do kolejnych odbiorników. A integrując taki algorytm z zegarem, można stworzyć system zależny od czasu, wciąż w obrębie jednego małego urządzenia. Zresztą można iść dalej i do inicjacji wykorzystać czujniki światła, ruchu itd.

Drugą grupą jest wymieniony już duplikat pilotów. Bywają urządzenia, których piloty kosztują krocie, a ich zastąpienie pilotami uniwersalnymi nie jest takie proste. Odrobina czasu na analizę danych wysyłanych umożliwi stworzenie stuprocentowego zastępnika za cenę najtańszego modułu Arduino i dobranej dla tych celów obudowy.

Przypomnę: piloty to urządzenia zawierające specjalizowany układ, które po pobudzeniu którymś z przycisków wysyłają komendy w wybranym standardzie za pomocą serii błysków w paśmie podczerwieni. Dlaczego akurat w podczerwieni, a nie w świetle widzialnym? Przyczyn jest kilka: diody świecące pracujące w tym paśmie historycznie szybciej osiągnęły możliwość pracy z większą mocą. Pasmo to łatwo odfiltrować. Zwykle też nie ma w nim tyle zakłóceń, co w paśmie widzialnym, a zwłaszcza wszelkiego rodzaju modulacji. No i mamy tutaj cały zestaw odbiorników, które już te wszystkie filtry mają wbudowane. Dlatego, o ile nie ma żadnego problemu, by zrobić sobie pilota pracującego w paśmie widzialnym, wybór podczerwieni uprości sprawę.

Co nam będzie potrzebne? Znowu niewiele elementów. Przedstawię dwa projekty: w pierwszym niezbędna będzie sama dioda oraz rezystor. To umożliwi stworzenie pilota o nieco mniejszym zasięgu od fabrycznych, w praktyce do trzech metrów. Gdybyśmy chcieli posiąść pilota pełnokrwistego, potrzebny będzie jeszcze tranzystor i jeden rezystor. Ale wtedy wypadałoby już dołożyć drugą diodę, którą można lekko odchylić względem pierwszej, zyskując większy kąt pracy i zasięg ogólny.

W pierwszym przypadku rezystor ograniczający powinien podać prąd wielkości 20 mA. Teoretycznie z portów można pociągnąć dwa razy więcej prądu, jeśli nie robi się tego hurtowo, lecz nie zaleca się tego. Spadek napięcia na diodzie podczerwieni wynosi mniej więcej półtora wolta, więc bez ryzyka można wstawić rezystor o wartości 150 omów. W drugiej wersji, jeśli założymy wpuszczanie w diody 200 mA, należy wstawić rezystor o wielkości 6,8 oma, co wynika z sumy spadków napięć i oczywiście prawa Oma. Rezystor sterujący tranzystorem z zapasem może mieć kiloom.

Do naszej zabawy wybiorę wariant pierwszy, wykorzystując elementy, które rozbieracze starych pecetów na pewno znają. Wymieniłem tutaj tylko oryginalną czerwoną diodę na taką, która pracuje w podczerwieni. Całość łączymy z masą i trzecim wyprowadzeniem Arduino, w przypadku płytki edukacyjnej TME dostępnym na zdublowanym złączu.

W poprzednim odcinku wykorzystywałem prostą bibliotekę obsługującą jedynie odczyt danych w kilku standardach. Dziś wybiorę jedną z najbardziej zaawansowanych bibliotek, umożliwiających stworzenie zarówno odbiornika jak i nadajnika. Nas będzie interesować tylko druga funkcja.

#define SEND_PWM_BY_TIMER  // Definicja niezbędna dla Arduino Uno
#include <IRremote.h>      // Biblioteka obsługi nadajnika podczerwieni.

const byte pstryczekWylacz = 6;     // Adres pstryczka wyłączającego ledy.
const byte pstryczekCzerwony = 4;   // Adres pstryczka włączającego kolor czerwony.
const byte pstryczekZielony = 8;    // Adres pstryczka włączającego kolor zielony.
const byte pstryczekNiebieski = 7;  // Adres pstryczka włączającego kolor niebieski.

const unsigned int adres = 64482;  // Adres urządzenia, którym będziemy sterować.
const byte kodWylacz = 38;         // Kod wyłączający ledy.
const byte kodCzerwony = 6;        // Kod wyłączający kolor czerwony.
const byte kodZielony = 8;         // Kod wyłączający kolor zielony.
const byte kodNiebieski = 90;      // Kod wyłączający kolor niebieski.

void setup() {
  IrSender.begin(DISABLE_LED_FEEDBACK);    // Inicjacja biblioteki
  pinMode(pstryczekWylacz, INPUT_PULLUP);  // Deklaruj linie pstryczków jako wejścia podciągnięte wewnętrznie do wysokiego stanu.
  pinMode(pstryczekCzerwony, INPUT_PULLUP);
  pinMode(pstryczekZielony, INPUT_PULLUP);
  pinMode(pstryczekNiebieski, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(pstryczekWylacz) == HIGH) {  // Jeśli pstryczekWylacz jest wciśnięty...
    IrSender.sendNEC(adres, kodWylacz, 0);     // Wyślij w standardzie NEC: adres, komendę i bit braku autorepetycji.
    zakoncz();                                 // Dokończ obsługę pstryczka.
  }

  if (digitalRead(pstryczekCzerwony) == HIGH) {
    IrSender.sendNEC(adres, kodCzerwony, 0);
    zakoncz();
  }

  if (digitalRead(pstryczekZielony) == HIGH) {
    IrSender.sendNEC(adres, kodZielony, 0);
    zakoncz();
  }

  if (digitalRead(pstryczekNiebieski) == HIGH) {
    IrSender.sendNEC(adres, kodNiebieski, 0);
    zakoncz();
  }
}

void zakoncz() {
  delay(50);  // Zaczekaj 50 ms
  while (     // Czekaj dopóki wszystkie przyciski zostaną zwolnione.
    (digitalRead(pstryczekWylacz) == HIGH) || (digitalRead(pstryczekCzerwony) == HIGH) || (digitalRead(pstryczekZielony) == HIGH) || (digitalRead(pstryczekNiebieski) == HIGH)) {}
  delay(50);  // Zaczekaj 50 ms
}

IRremote jest biblioteką uniwersalną, obsługującą nie tylko referencyjne moduły Arduino, ale także te nieoficjalne, używające nietypowych mikrokontrolerów. Dlatego w przykładach można znaleźć wiele definicji związanych z konkretnymi rozwiązaniami. Żeby nie zaciemniać sytuacji, postanowiłem usunąć nadmiar kodu, ograniczając użycie biblioteki wyłącznie do modułów Arduino Uno i pochodnych, czyli Nano, Mini i pozostałych. Ponieważ biblioteka korzysta ze sprzętowego generatora, diodę – przypomnę, przez rezystor – należy podłączyć pod wyprowadzenie numer 3.

Żeby istniał pilot, muszą być przyciski. Korzystając ze znanej już płytki edukacyjnej TME, dostałem ich kilka, podłączonych do portów od czwartego do ósmego. Oczywiście każdy, mając swój moduł, może je podłączyć gdziekolwiek, z wyjątkiem zajętego już portu trzeciego.

No dobrze, ale czym mój pilot ma sterować? Wśród zachomikowanych skarbów znalazłem taką oto listwę kolorowych ledów z pilotem.

Nie potrzebny mi drugi pilot, ale w celach edukacyjnych nie robi się tego, co potrzebne. Postanowiłem na chwilę zdublować pilota, a właściwie cztery jego przyciski, odpowiedzialne za włączanie poszczególnych kolorów i wyłączanie całości. W każdym przypadku należy najpierw poznać standard, w jakim pilot pracuje i kody przycisków, które chcemy emulować. Jak to zrobić? O tym pisałem w poprzednim artykule, wystarczy na chwilę zbudować tamten układ, spisać sobie dane, które przychodzą do odbiornika podczerwieni i wykorzystać je w tym projekcie.

Więc teraz konkretnie: oryginalny pilot nadawał w zreformowanym trybie NEC-a, na adresie 64482, a interesujące mnie przyciski generowały kody: 38, 6, 8 i 90. Tak więc widać, że nijakiego porządku w tym nie ma, ale tak już miewają piloty. Spójrzmy teraz na szkic. Po oczyszczeniu wszystkiego co zbędne, pozostaje tylko jedna definicja, konieczna do działania pilota i musi się ona znajdować przed importem biblioteki. Tę oczywiście należy pobrać znaną już metodą, za pomocą menedżera bibliotek.

#define SEND_PWM_BY_TIMER  // Definicja niezbędna dla Arduino Uno
#include <IRremote.h>      // Biblioteka obsługi nadajnika podczerwieni.

Następnie definiuję położenie przycisków, nazywając je w jakiś ludzki sposób.

const byte pstryczekWylacz = 6;     // Adres pstryczka wyłączającego ledy.
const byte pstryczekCzerwony = 4;   // Adres pstryczka włączającego kolor czerwony.
const byte pstryczekZielony = 8;    // Adres pstryczka włączającego kolor zielony.
const byte pstryczekNiebieski = 7;  // Adres pstryczka włączającego kolor niebieski.

Tutaj definiuję adres, czyli to, co odczytałem szkicem z poprzedniego filmu. Zwróćmy uwagę na to, że adres ten ma wartość przekraczającą liczbę 32767, a więc wymaga zadeklarowania typu danej unsigned int, która różni się od int tym, że nie zawiera znaku, a więc może być liczbą naturalną od zera do 65535.

const unsigned int adres = 64482;  // Adres urządzenia, którym będziemy sterować.

A tutaj definiuję poznane już kody, które kolejne przyciski mają wysyłać. Te wszystkie dane każdy powinien ustawić sobie zgodnie z tym, co posiada.

const byte kodWylacz = 38;         // Kod wyłączający ledy.
const byte kodCzerwony = 6;        // Kod wyłączający kolor czerwony.
const byte kodZielony = 8;         // Kod wyłączający kolor zielony.
const byte kodNiebieski = 90;      // Kod wyłączający kolor niebieski.

Przy starcie programu należy zainicjować bibliotekę. Wpis w nawiasie można pominąć, wtedy z automatu przy każdym wysłaniu komunikatu mrugnie dioda świecąca znajdująca się na porcie 13, czyli ta wbudowana w każde Arduino.

IrSender.begin(DISABLE_LED_FEEDBACK);    // Inicjacja biblioteki

Następnie mamy obowiązkowe definiowanie portów klawiatury jako wejścia, wewnętrznie podciągnięte do zasilania, ale to już znamy. Czas na główną pętlę.

if (digitalRead(pstryczekWylacz) == HIGH) {  // Jeśli pstryczekWylacz jest wciśnięty...
  IrSender.sendNEC(adres, kodWylacz, 0);     // Wyślij w standardzie NEC: adres, komendę i bit braku autorepetycji.
  zakoncz();                                 // Dokończ obsługę pstryczka.
}

if (digitalRead(pstryczekCzerwony) == HIGH) {
  IrSender.sendNEC(adres, kodCzerwony, 0);
  zakoncz();
}

if (digitalRead(pstryczekZielony) == HIGH) {
  IrSender.sendNEC(adres, kodZielony, 0);
  zakoncz();
}

if (digitalRead(pstryczekNiebieski) == HIGH) {
  IrSender.sendNEC(adres, kodNiebieski, 0);
  zakoncz();
}

 Żadnej filozofii tutaj nie ma. Mamy cztery bliźniacze bloki, badające stan klawiatury. Jeśli którykolwiek z przycisków zostanie wciśnięty, biblioteka wyśle komunikat w systemie NEC-a (IrSender.sendNEC), o adresie zdefiniowanym wcześniej (adres), kodzie przyporządkowanym temu przyciskowi (np. kodCzerwony) i z zerowym bitem autorepetycji. Nadmienię, że w tym wypadku wciśnięcie przycisku ma miejsce, gdy stan wejścia staje się wysoki, co wynika z budowy płytki edukacyjnej, której używam, a o czym już kiedyś wspominałem.

Potem następuje, wspólna już dla wszystkich akcji, część badająca (zakoncz) czy przycisk nadal jest wciśnięty i pozwalająca na powrót do pętli, gdy zostanie puszczony. Pauzy pomiędzy analizą stanu przycisków zabezpieczają nas przed stanami nieustalonymi, a takie uproszczenie, będące swego rodzaju marnotrawstwem czasu, nie mają znaczenia w urządzeniu takim jak pilot.

delay(50);  // Zaczekaj 50 ms
while (     // Czekaj dopóki wszystkie przyciski zostaną zwolnione.
  (digitalRead(pstryczekWylacz) == HIGH) || (digitalRead(pstryczekCzerwony) == HIGH) || (digitalRead(pstryczekZielony) == HIGH) || (digitalRead(pstryczekNiebieski) == HIGH)) {}
delay(50);  // Zaczekaj 50 ms

 Kompilujemy, sprawdzamy i… nasz pierwszy w życiu pilot zachowuje się dokładnie jak oryginał, a nawet lepiej, bo tutaj mamy przyciski lepszej jakości. Modyfikacje pozostawię czytelnikom. Można tutaj naprawdę wiele, łącznie ze stworzeniem wielkiego pilota z klawiaturą matrycową.

Ciąg dalszy historii o pilotach znajduje się tutaj.

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