INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
Witam! To jest mój pierwszy artykuł. Chciałbym przedstawić jak wprowadzać dane do Arduino przez zwykły pilot od telewizora.
Nazwy elementów są jednocześnie linkami do artykułów w sklepie Botland.
Wstęp
Porównanie komunikacji przez podczerwień, radiowej i przez moduły XBee
Lp. | Komunikacja przez podczerwień | Komunikacja radiowa | Xbee |
Cena (Nadajnik + odbiornik/moduł) | Od 5zł do 20zł | Od 10zł do 50zł | Od 50zł do 250zł |
Polecane produkty | TSOP31236 (odbiornik), IR LIRED3B 3mm 940nm (nadajnik) | HC-12 433MHz
|
Zależne od potrzeby i budżetu |
Zasięg (metry) | 5-20 | 100-1000 | 100-1500 |
Szybkość transmisji | Mała | Średnia | Bardzo duża |
Zalecane miejsce użycia | Mieszkania, biura | Teren otwarty, duże hale, rzadziej małe pomieszczenia | Raczej mieszkania, biura |
Co wywołuje zakłócenia | Światło słoneczne | Inne moduły radiowe w tym Wi-Fi | – |
Przeznaczenie | Raczej zdalne sterowanie, rzadko komunikacja | Komunikacja i zdalnie sterowanie | Raczej komunikacja, rzadko zdalne sterowanie |
Komunikacja przez podczerwień
Płytka Arduino np. Uno, MegaCo będzie nam potrzebne:
- Odbiorniki podczerwieni np. popularny TSOP31236 lub np. moduł Digital IR Receiver Module dołączony do zestawów startowych: DFRobot Intermediate Kit – zestaw dla średniozaawansowanych użytkowników Arduino v2.0 i DFRobot Mega D3 Kit – kompleksowy zestaw edukacyjny z DFRDuino Mega 2560.
- Nadajnik IR LIRED3B 3mm 940nm
- Pilot IR np. od telewizora
- Płytka stykowa, przewody połączeniowe
Biblioteka
Najpierw konieczne będzie pobranie biblioteki z strony:http://www.dfrobot.com/image/data/DFR0107/IRremote.zip. Plik rozpakowujemy do folderu Libraries. Po włączeniu Arduino Ide w Szkic/Importuj bibliotekę… na dole listy powinna pojawić się biblioteka “IRremoute”. Jeżeli nie ma jej musimy ją ręcznie dodać: Szkic/Importuj bibliotekę…/Dodaj bibliotekę… znajdujemy folder “Rremoute” i klikamy Open.
Sterowanie Arduino przez pilot od telewizora
Schemat
Podłączmy według schematu:
Jeżeli posiadamy moduł należy go podłączyć: czerwony – 5V, czarny – GND, zielony – pin cyfrowy nr 2. Numer pinu cyfrowego można zmienić, ale trzeba to uwzględnić w kodzie.
Przypisywanie przycisków na pilocie do numerów
Zgrywamy kod na płytkę Arduino:
#define receiverpin = 2; // pin Arduino, do którego został podłączony odbiornik IR #include <IRremote.h> // biblioteka IRrecv irrecv(receiverpin); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni } void loop() { if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygnał IR { Serial.print(results.value); Serial.println(" "); irrecv.resume(); // odbiera następną wartość delay(100); } ]
Włączmy monitor portu szeregowego. Wciskamy po kolei potrzebne do naszej komunikacji przyciski i zapisujemy liczbę, która wyświetli nam się w monitorze portu szeregowego. Przykład:
4105841032 – POWER
3261853764 – PRZYCISK DO GÓRY
3305092678 – PRZYCISK W DÓŁ
1400905448 – PRZYCISK W PRAWO
1972149634 – PRZYCISK W LEWO
Funkcje i program
Wykorzystując te dane możemy teraz napisać przykładową funkcję:
int irRemoute () { int dane; if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygna� IR { unsigned long odczyt = results.value; // sygnał zapisuje jako odczyt switch (odczyt) { case 4105841032: //power dane = 11; break; case 2331063592: //eneter dane = 12; break; case 3261853764: // góra dane = 13; break; case 3305092678: // dół dane = 14; break; case 1400905448: // prawo dane = 15; break; case 1972149634: // lewo dane = 16; break; case 3778927144: // 1 dane = 1; break; case 2908251746: // 2 dane = 2; break; case 657459652: // 3 dane = 3; break; case 4120482440: // 4 dane = 4; break; case 1931099650: // 5 dane = 5; break; case 742730860: // 6 dane = 6; break; case 1167253836: // 7 dane = 7; break; case 1747313982: // 8 dane = 8; break; case 2340753640: // 9 dane = 9; break; case 3119867746: // 0 dane = 10; break; default: dane=0; } } else { dane=0; } irrecv.resume(); // resetuje czujnik return dane ; }.
W miejsca liczb należy wpisać własne używając danych z poprzedniego programu. Zbędne wiersze trzeba usunąć, pamiętając że po każdej liczbie jest dwukropek. Dodatkowo na końcu pętli switch-case znajduje się: default: dane=0; oraz cała pętla switch-case zamknięta jest klamrą. Dotyczy to wszystkich programów i funkcji, które są zaprezentowane w tym artykule.
Pętla sprawdza odczyt, a następnie porównuje go z różnymi wartościami i przypisuje mu odpowiednią wartość zmiennej “dane”, która zostaje zwrócona przez funkcję. Funkcja ta nie blokuje programu, ale jeżeli chcemy być obsypani ogromną ilością danych możemy wprowadzić drobną modyfikację:
byte irRemoute () { byte dane=0; while(dane==0) { if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygna� IR { unsigned long odczyt = results.value; // sygnał zapisuje jako odczyt switch (odczyt) { case 4105841032: //power dane = 11; break; case 2331063592: //eneter dane = 12; break; case 3261853764: // góra dane = 13; break; case 3305092678: // dół dane = 14; break; case 1400905448: // prawo dane = 15; break; case 1972149634: // lewo dane = 16; break; case 3778927144: // 1 dane = 1; break; case 2908251746: // 2 dane = 2; break; case 657459652: // 3 dane = 3; break; case 4120482440: // 4 dane = 4; break; case 1931099650: // 5 dane = 5; break; case 742730860: // 6 dane = 6; break; case 1167253836: // 7 dane = 7; break; case 1747313982: // 8 dane = 8; break; case 2340753640: // 9 dane = 9; break; case 3119867746: // 0 dane = 10; break; default: dane=0; } irrecv.resume(); // reseruje czujnik } else { dane=0; } } return dane ; }
W powyższym kodzie nie tylko zmieniłem typ zmiennej z int na byte, aby zajmowała mniej miejsca. W większych programach może to być konieczne. Ponadto liczba zapisana w zmiennej byte jest o wiele łatwiejsza do przesłania np. do innego Arduino niż int. W powyższej funkcji dodałem też pętlę while, która powtarza się dopóki, dopóty czujnik nie odbierze wartości, z której korzystamy. Ta funkcja może być wykonywana czasem bardzo długo, więc Arduino nie może odbierać w tym czasie danych z innych źródeł, co może być uciążliwe w zaawansowanych projektach. W takich przypadkach lepiej jest zastosować pierwszą funkcję i polecenie if w pętli głównej:
void loop() { byte check = irRemoute(); if (check != 0) { // Tutaj podajemy co ma wykonać dalej z zmienną check jeżeli nie jest ona zerem } }
Jednak w większości projektów nie będziemy korzystać z tak wielu danych. Czasami będziemy chcieli się zatrzymać i poczekać na dane z czujnika podczerwieni, a czasami będziemy chcieli korzystać wyłącznie ze sterowania przez IR. Wtedy polecenie if nie będzie miało sensu. A oto przykładowy program:
#include <IRremote.h> // biblioteka IRrecv irrecv(2); //numer pinu decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni } void loop() { Serial.println(irRemoute()); delay(100); } byte irRemoute () { byte dane=0; while(dane==0) { if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygna� IR { unsigned long odczyt = results.value; // sygnał zapisuje jako odczyt switch (odczyt) { case 4105841032: //power dane = 11; break; case 2331063592: //eneter dane = 12; break; case 3261853764: // góra dane = 13; break; case 3305092678: // dół dane = 14; break; case 1400905448: // prawo dane = 15; break; case 1972149634: // lewo dane = 16; break; case 3778927144: // 1 dane = 1; break; case 2908251746: // 2 dane = 2; break; case 657459652: // 3 dane = 3; break; case 4120482440: // 4 dane = 4; break; case 1931099650: // 5 dane = 5; break; case 742730860: // 6 dane = 6; break; case 1167253836: // 7 dane = 7; break; case 1747313982: // 8 dane = 8; break; case 2340753640: // 9 dane = 9; break; case 3119867746: // 0 dane = 10; break; default: dane=0; } irrecv.resume(); // reseruje czujnik } else { dane=0; } } return dane ; }
Otwieramy monitor portu szeregowego i wciskamy po kolei przyciski na pilocie. Oto efekt:
Sterowanie światłami – mały SmartHome
Jeżeli chcemy sterować przykładowo światłami w domu, trzeba z powrotem zamienić dane na konkretny sygnał. Przykładowy schemat (układy z przekaźnikami zastąpiłem LED-ami):
Wiem, że takie diody najlepiej podłączyć do tranzystorów, ale w naszym projekcie nie jest to istotne. Odbiornik podczerwieni podłączmy do pinu nr 11.
Schemat przekaźnika
Jeżeli chodzi o układy z przekaźnikami można je zrobić samemu lub kopić gotowe płytki np. Moduł z przekaźnikiem v3.1 5V 277V/10A – DFRobot lub zbudować własne w oparciu o ich schemat:
Z powyższego schematu można usunąć LED. Na schemacie są pokazane Przekaźnik JQC-3FF-S-Z-5V – cewka 5V, styki 10A/250VAC. Proponuję użyć tranzystora NPN BC338-40 25V/0.8A. Pin oznaczony numerem 3 z listwy J1 należy podłączyć do masy, 2 z J1 do 5V, 1 z J1 do pinu cyfrowego Arduino, 1 z J2 do napięcia sieciowego, 3 z J2 do zasilania np. lampy.
UWAGA! BEZPOŚREDNI KONTAKT CZŁOWIEKA Z PRĄDEM 230V 50Hz POWODUJE BOLESNE SKURCZE MIĘŚNI, MIGOTANIE KOMÓR SERCA I ŚMIERĆ.
Program:
#include <IRremote.h> // biblioteka IRrecv irrecv(14); decode_results results; boolean jeden = 0; boolean dwa = 0; boolean trzy = 0; boolean cztery = 0; boolean piec = 0; boolean szesc = 0; boolean siedem = 0; boolean osiem = 0; boolean dziewiec = 0; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni } void loop() { if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygnał IR { unsigned long odczyt = results.value; // sygnał zapisuje jako odczyt switch (odczyt) { case 3778927144: // 1 jeden = change(jeden); digitalWrite(2,jeden); break; case 2908251746: // 2 dwa = change(dwa); digitalWrite(3,dwa); break; case 657459652: // 3 trzy = change(trzy); digitalWrite(4,trzy); break; case 4120482440: // 4 cztery = change(cztery); digitalWrite(5,cztery); break; case 1931099650: // 5 piec = change(piec); digitalWrite(6,piec); break; case 742730860: // 6 szesc = change(szesc); digitalWrite(7,szesc); break; case 1167253836: // 7 siedem = change(siedem); digitalWrite(8,siedem); break; case 1747313982: // 8 osiem = change(osiem); digitalWrite(9,osiem); break; case 2340753640: // 9 dziewiec = change(dziewiec); digitalWrite(10,dziewiec); break; } irrecv.resume(); // reseruje czujnik } delay(1000); } byte change (boolean otrz) { return (!otrz); }
A oto film jak to działa (film dodany na moim kanale gdzie znajdują też inne filmiki z Arduino i Lego Mindstorms):
Wysyłanie wiadomości przez IR z jednego Arduino do drugiego Arduino i funkcja “Random”
Arduino działające jako odbiornik
Schemat z poprzedniego projektu:
Program:
#include <IRremote.h> // biblioteka IRrecv irrecv(14); decode_results results; boolean jeden = 0; boolean dwa = 0; boolean trzy = 0; boolean cztery = 0; boolean piec = 0; boolean szesc = 0; boolean siedem = 0; boolean osiem = 0; boolean dziewiec = 0; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni } void loop() { if (irrecv.decode(&results)) // sprawdza, czy otrzymano sygna� IR { byte odczyt = (byte) results.value; // sygnał zapisuje jako odczyt /* odczyt = constrain(odczyt,1,9);
- /
Na początku pętli loop znajduje się kod, który zamknąłem w komentarzu:
/* odczyt = constrain(odczyt,1,9);
- /
Powyższy fragment kodu (gdyby nie był w komentarzu) zamienia wszelkie liczby większe od 9 otrzymane w wyniku zakłóceń na 9. Jest to opcjonalny fragment kodu i jego celem jest zmienianie stanu on/off LEDu podłączonego do pinu nr 10 przy wystąpieniu zakłóceń.
Arduino działające jako nadajnik
Schemat:
Program:
#include <IRremote.h> IRsend irsend; void setup(){} void loop() { byte dane = random(1,10); irsend.sendSony(dane, 18); // Wysyła wylosowaną liczbę w przedziale od 1 do 10 delay(2500); }
Efekty
Czas zapalania się i gaśnięcia poszczególnych LEDów jest chaotyczny, ale ilość takich cykli dla każdego z nich jest porównywalny.
Komunikacja radiowa lub przez XBee
Jeżeli mówimy o komunikacji radiowej zapewne mamy na myśli radio FM albo zachwalane moduły o częstotliwości 2,4 GHz stosowany w samochodach RC i dronach. Radio FM jest świetnym wynalazkiem, ale nie nadaje się do komunikacji robotów. Moduły 2,4 GHz byłyby wręcz idealne, ale jeżeli chodzi nam o jak najdokładniejszy przekaz (bardzo zakłóca np. Wi-Fi) lepiej wybrać częstotliwość trochę mniejszą np 433MHz lub 868MHz. Jest prawdą fakt, że są co najmniej 2,5 do 5 razy wolniejsze, ale 433 milionów stanów zegarowych na sekundę to wystarczająco nawet dla bardziej złożonych komunikacji.
Dalsze działanie
Całość można wgrać na mikrokontroler np. ATTINY2313 za pomocą ARDUINO IDE (link do artykułu) . Daje nam to możliwość zbudowania taniego i trwałego układu.
INFORMACJA: Poniższy post nie wydostał się z Poczekalni :(
Super
każda dioda ma inne napięcie zasilania
Faktycznie. Poprawiłem schemat (każda dioda powinna mieć swój rezystor). Jednak zastosowałem wszędzie rezystor 220Ω dlatego, że przy takich diodach można przyjąć, że napięcie LED równe jest 2V
Nie ma sensu opisywać 2X tego samego z tą samą biblioteką https://majsterkowo.pl/jak-sterowac-dowolnym-urzadzeniem-za-pomoca-pilota-i-arduino/
Po zapoznaniu się z tym artykułem uważam, że pierwsza część mojego artykułu jest ściśle powiązana z drugą, a biblioteka ta jest z tego co wiem jedną z najprostszych i najwyraźniej najbardziej popularnych do sterowania IR
Dla mnie wporzo. A co do tego że już było to mi to nie przeszkadza a wręcz przeciwnie. Dobrze jest poczytać wiele poradników odnoszących się do jednego problemu bo żaden nie jest idealny no i powtarzamy sobie wiadomości i przyswajamy co dla początkującego jest wskazane. 5.
a mnie drażni w takich projektach brak wykończenia -robione na płytkach stykowych, kilka ledow i tyle
a gdzie zrobiona płytka (wytrawiona lub chociaz polutowane na uniwersalnej, gdzie obudowa? wszędzie tylko pajęczynki na płytce stykowej
tak jakby ktoś robił poradnik pt “jak zrobić stół’ ale podal tylko wymiary, ucial blat i deski i położył jedno na drugim mówiąc “a potem sobie posklejajcie/skręccie, pomalujcie” itd
takie to wszystko niedokończone…
Rozumiem Krapi co masz na myśli. Według mnie przerabianie takiego prostego układu z LEDami, który ma właściwie sprawdzić działanie programu jest trochę bez sensu. Pokazując natomiast jak zrobić małe SmartHome sterowane podczerwienią jest może ciekawe, ale ten projekt ma bardziej charakter zabawy ze względu na wady sterowania IR – podatność na zakłócenia, mały zasięg i mały kąt nadawania.
cześć,
mam pewien problem i znajomy mi podesłał ten artykuł z myślą że może to jest rozwiązanie dla mnie.
Jeśli mogli byś przeczytać w czym problem i mi odpowiedzieć czy ma rację i czy ktoś się tego podejmie.
Mam ramkę cyfrową (dokładnie 20 szt.) która ma sterowani przyciskami ale też pilotem. Wyświetlany na niej jest zapętlony film.
Ma zaprogramowany czas włączenia i wyłączenia się.
Niestety sklepy w których stoją te ramki mają na noc centralnie wyłączany prąd i po ponownym włączeniu prądu ramka nie startuje filmem tylko swoim ekranem startowym z ikonami typy VIDEO, ZDJĘCIA KALENDARZ. Oczywiście można uruchomić wyświetlanie filmu pilotem ale chodzi o to aby ramka była bezobsługowa czyli żeby film startował sam.
Pytanie czy tego typu rozwiązanie jak w powyższym artykule można by było zastosować.
Może macie inny pomysł?
Uprzedzę pytania że ups’y i power banki nie są rozwiązaniem. Już to przerobiliśmy.
Witam. A co gdybym chciał żeby dioda/diody świeciły się tylko w momencie przyciskania przycisku na pilocie? Próbuje to ogarnąć ale bez efektu. Proszę o pomoc
Wszystko pięknie tylko jedno ‘ale’.
Na końcu pętli CASE dajesz “dane=0” jako wartość gdy nie jest odbierany żaden kod, a wcześniej jest przypisanie że gdy z pilota odebrany zostanie kod klawisza ‘ZERO’ to przypisujesz wartość ’10’. Dla mnie to trochę zamieszane.
Niech kod ‘ZERO’ z pilota przypisuje wartość ‘0’, a wartość gdy nie jest odbierany żaden kod np. wynosi ‘255’.
Na pierwszy rzut oka wtedy widać że odbieramy kod ‘ZERO’ bo ma wartość ‘0’ i łatwiej to wtedy opanować.
Gdybyś chciał do urządzenia wprowadzić np. jakąś wartość w postaci ciągu cyfr, dajmy na to jakiś np. PIN i w nim byłaby cyfra ‘0’ (np. 6083) to łatwiej połączyć w całość odczytane zmienne 6, 0, 8, 3, a niżeli zmienne 6, 10, 8, 3.
To tylko moja taka uwaga bardziej stylistyczna bo oczywiście w samym wyniku działania programu nic nie zmieni.
Niby wszystko super, tylko czemu ? kody co kolejne wciśnięcie klawisza na pilocie są różne ?