Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Nadajnik/odbiornik IR na ESP8266 (Arduino)

krzbor 02 Jun 2023 22:43 4230 7
Suntrack
  • Nadajnik/odbiornik IR na ESP8266 (Arduino)
    Przeznaczenie i zasada działania
    Istnieją biblioteki do Arduino służące do sterowania urządzeniami poprzez IR. Postanowiłem jednak rozwiązać to w inny sposób – chciałem stworzyć układ uczący się, tzn. zapamiętujący kody z oryginalnego pilota. Umożliwia to sterowanie całym szeregiem urządzeń typu klimatyzatory, łańcuch świetlne, kule dyskotekowe itp. Głównym zadaniem układu miała być praca na zasadzie włącz/wyłącz, ale oczywiście można nagrywać i odtwarzać dowolne sekwencje impulsów i tym samym symulować naciśnięcie dowolnego przycisku pilota lub sekwencji naciśnięć. Układ ma także dodatkową funkcjonalność – sygnalizację, czy urządzenie jest załączone, czy też nie. Czasami jesteśmy daleko od sterowanego układu i chcemy mieć pewność, że np. klimatyzator został wyłączony. Przy okazji tworzenia oprogramowania na Arduino postanowiłem użyć chat GPT do stworzenia części kodu. Co z tego wynikło przeczytacie dalej.

    Trochę historii, czyli dlaczego powstał układ?
    W domu mam kominek i DGP. Postanowiłem dorobić DZP czyli Dystrybucję Zimnego Powietrza. W tym celu na strych dałem klimatyzator pokojowy typu monoblok, który podłączyłem do wentylatora kominkowego oraz dodatkowego wentylatora tłoczącego powietrze do pokoi. Układ był sterowany pilotem, ale przecież nie będę wchodził na strych za każdym razem, gdy trzeba wyłączyć lub załączyć klimatyzator. Należało stworzyć jakiś przedłużacz. Pierwsza wersja była przewodowa (odbiornik TSOP oraz generator 38 kHz. Działało to dobrze, ale po zmianie umeblowania bardzo brzydko wyglądał kabel łączący odbiornik z nadajnikiem. Kolejne rozwiązanie opierało się o gotowy przedłużacz radiowy na 433 MHz (taki w kształcie UFO). Nie działał on perfekcyjnie – czasami były kłopoty z wyłączeniem klimatyzatora. Jednak największym problemem było samoczynne załączanie klimatyzacji (na całe szczęście w trybie wentylacji). Winny był odbiornik umieszczony na strychu, który łapał olbrzymią liczbę sygnałów radiowych i bez przerwy coś nadawał w podczerwieni. Pozbyłem się wiec tego układu i zastąpiłem go prezentowanym rozwiązaniem – przesyłanie komend pilota przez Wi-Fi, a w połączeniu z resztą infrastruktury inteligentnego domu – możliwość sterowania z dowolnego miejsca z dostępem do internetu.

    Budowa układu
    Ponieważ wszystko robię na ESP8266 i Arduino, wybór platformy był oczywisty. Pozostało stworzyć taki układ, a w zasadzie dwa układy – jeden do uczenia (odczytu), a drugi do nadawania. Myślałem o samodzielnej budowie, albo o przeróbce SONOFF Basic. Znalazłem jednak taki moduł:
    Nadajnik/odbiornik IR na ESP8266 (Arduino)
    Ma on w sobie zarówno odbiornik jak i nadajnik i to połączony z ESP8266. Piny konieczne do programowania są łatwo dostępne i dobrze opisane:
    Nadajnik/odbiornik IR na ESP8266 (Arduino)
    Zdecydowałem się zatem na zakup takiego modułu. Kupiłem 3 sztuki, gdyż chciałem jeden układ przerobić na czytnik, a drugi na nadajnik (trzeci to zapas). Później zmieniłem koncepcję i każdy moduł może pracować zarówno w trybie odbiornika, jak i nadajnika. Układ nie jest idealny – brakuje przede wszystkim diody pracującej w świetle widzialnym. Taka dioda okazuje się bardzo przydatna przy testowaniu – można migać w self teście i mrugać podczas nadawania. Po prostu wiadomo co się dzieje. Było to dla mnie bardzo istotne, gdyż po pierwszym programowaniu „z kabelków” od razu przechodzę na OTA i nie bawię się RX,TX, dlatego mój układ został doposażony w taką diodę:
    Nadajnik/odbiornik IR na ESP8266 (Arduino) Nadajnik/odbiornik IR na ESP8266 (Arduino)
    Użyłem czerwonej „jasnej” diody 3 mm w przezroczystej obudowie połączonej rezystorem 220R z ESP. Polecam takie diody – świecą jasno już przy prądzie 1-2 mA, a bezbarwna obudowa nie zostawia wątpliwości, czy w danym momencie dioda świeci, czy nie.

    Odczyt klawiszy pilotów
    Odczytane sekwencje z przycisków pilotów należało gdzieś zapamiętać. Postanowiłem, że „bazą danych” będzie pojedynczy plik json, w którym będą zapisane poszczególne piloty, a w każdym pilocie – przyciski. Wygląda to mniej więcej tak (sekwencje liczb zostały skrócone w celu prezentacji):
    Code: json
    Log in, to see the code


    Każdy pilot (identyfikowany przez nazwę) ma dwa parametry globalne: częstotliwość (w Hz) oraz wypełnienie (w %) oraz oczywiście listę przycisków z czasami. Jednostką czasu jest 10 µs, czyli liczba 290 odpowiada 2,9 ms. Liczby nie mogą być większe niż 16 bit bez znaku, czyli ok. 655 ms. Pierwsza liczba to czas sygnału, kolejna - czas przerwy i tak dalej. Ostatnia liczba zawsze jest czasem sygnału. Samą sekwencję liczb (jako 16 bitowe dane binarne) dostarcza ESP. Powstał problem jak dopisać to do „bazy”. W tym celu powstało oprogramowanie pomocnicze w postaci strony WWW i skryptu PHP:
    Plik "przycisk.htm":
    Code: html
    Log in, to see the code


    przycisk.php:
    Code: php
    Log in, to see the code


    Strona i skrypt umożliwiają wygodne zapisanie niezbędnych danych w tymczasowym pliku irs.json. Plik ten jest interpretowany przez skrypt PHP odbierający dane z ESP, a następnie jest kasowany. Sekwencja programowania jest zatem następująca: wprowadzamy nazwę pilota, nazwę przycisku i naciskamy „Wyślij”. Teraz kierujemy pilota w stronę odbiornika TSOP i naciskamy właściwy przycisk pilota. To dosyć prosta sekwencja umożliwiająca wygodne zaprogramowanie dużej liczby przycisków. Nazwy pilotów i przycisków najlepiej nadawać z użyciem wyłącznie łacińskich liter i cyfr – chodzi o to, aby nie było kłopotu przy wysyłaniu pilota oraz kodu klawisza poprzez zapytania GET.
    Tu drobna uwaga – w wielu miejscach kodu (zarówno PHP jak i C) będzie występować sekwencja: „192.168” Chodzi o to, że skrypty PHP działają u mnie na serwerze dostępnym także z zewnątrz i muszę się zabezpieczać przed ich wywołaniem spoza sieci domowej.

    Kod Arduino
    Code: arduino
    Log in, to see the code

    Kod niestety trochę się rozrósł. Wynika to z faktu, że zaszyta jest w nim zarówno funkcjonalność odczytu jak i zapisu. Urządzenie wybiera właściwy tryb na podstawie zworki. Jeśli piny RX i TX są zwarte w momencie startu, to układ pracuje jako odbiornik, a jeśli są rozwarte, to działa jako nadajnik. Po uruchomieniu nie można zmienić trybu. Kod odpowiedzialny za odczyt jest stosunkowo prosty – mierzone są czasy nadawania (niski stan na wyjściu odbiornika IR) oraz czas przerwy. Jeśli przerwa trwa dłużej niż 0,5 s proces odczytu jest przerywany, a cała sekwencja jest wysyłana do skryptu IR.php, który zapisuje ją w bazie (pliku json).

    Działanie w drugą stronę polega na odbiorze sekwencji liczb będących kodem przycisku pilota. Jak widać moduły nadawcze wysyłają w postaci błysków IR to co otrzymały i nie mają żadnej pamięci jeśli chodzi o sekwencję sterowania diodą IR. Takie sterowanie postanowiłem zrobić w oparciu o serwer WWW na ESP. Ponieważ jednak wcześniej nie robiłem serwera na ESP z odczytem danych przesyłanych metodą POST, postanowiłem się wspomóc chatGPT.

    Przygody z chatGPT
    Moja prośba o pomoc:
    "Podaj kod Arduino dla ESP8266 do utworzenia serwera WWW odbierającego binarne dane metodą POST"
    Odpowiedź:
    Code: arduino
    Log in, to see the code

    Muszę przyznać, że wygląda całkiem sensownie. Dodałem kolejny warunek:
    Serwer musi jeszcze kontrolować, czy połączenia są z sieci lokalnej 192.168.x.x. Połączenia spoza sieci lokalnej powinny być odrzucane.
    Code: arduino
    Log in, to see the code

    Od razu widoczny jest błąd – dane będą odbierane z dowolnego IP tylko nie własnego. Upomniałem chata, który jak zwykle przeprosił i zaproponował poprawiony kod:
    Code: arduino
    Log in, to see the code

    Zatem, czy kod zaproponowany przez bota działa? Niestety nie. Znalezienie błędów zajęło mi trochę czasu i musiałem się posiłkować tradycyjnie Google.
    Pierwszy problem – odczyt nagłówków. Aby był możliwy należy zadeklarować je wcześniej:
    Code: arduino
    Log in, to see the code

    Bez tej deklaracji po prostu nie działa odczyt zawartości nagłówków. Po naprawie tego błędu oprogramowanie jednak nadal nie działało. Zaproponowana metoda odczytu strumienia zawsze zwracała pusty ciąg. Aby odczytać surowe dane odebrane metodą POST należy użyć:
    server.arg("plain")
    Bardzo dziwna sekwencja – odczyt argumentu „plain”, którego po prostu nie ma. Nie dziwię się, że bot na to nie wpadł 😊
    Generalnie chatGPT pomoże nam, jeśli potrafimy szybko zweryfikować poprawność wygenerowanego kodu. Jeśli jednak czegoś nie wiemy, to możemy długo szukać błędów, a osoba, która nie zna się na programowaniu po prostu ich nie znajdzie.
    Taka drobna dygresja – na stronie stackoverflow.com (chyba najlepsza strona dla programistów) pojawił się zapis „Używanie tekstu generowanego przez ChatGPT w treściach na Stack Overflow jest tymczasowo zabronione”
    I wyjaśnienie „Podstawowy problem polega na tym, że chociaż odpowiedzi generowane przez ChatGPT mają wysoki wskaźnik niepoprawności, zazwyczaj wyglądają na dobre”. Tu link do oryginału
    Nic dodać, nic ująć – dokładnie tak było w moim przypadku.

    Powiadamianie o stanie kontrolowanego urządzenia
    Pin RX (STANWE) służy dodatkowo do detekcji stanu sterowanego urządzenia. Stanem aktywnym jest stan niski. Można to rozwiązać na wiele sposobów – pin ten możemy zwierać do masy za pomocą transoptora, gdzie dioda transoptora będzie podłączona gdzieś do sterowanego urządzenia (np. elektroniki klimatyzatora, wyjścia USB telewizora itp.) Najprostszym jednak rozwiązaniem jest dodanie fotorezystora, który jest oświetlany diodą Power urządzenia. Należy jednak pamiętać, że stan niski musi być odpowiednio rozpoznany przez ESP, a wewnętrzny rezystor podciągający ma stosunkowo małą wartość (poniżej 50 kΩ). Fotorezystor podłączony do masy nie „zbije” wystarczająco napięcia. Rozwiązaniem jest odkomentowanie linii pinMode(STANWE, INPUT); i stworzenie własnego podciągania do napięcia zasilania rezystorem o większej wartości. Oczywiście zamiast pinu RX możemy użyć inny wolny lub podłączyć się do wejścia analogowego ESP.
    ESP raportuje stan co 30 s i dodatkowo natychmiast po zmianie (wyłączeniu i załączeniu). Skrypt IR.php zapisuje stan w pliku logu (dodaje wpisy), a dodatkowo ostatni stan jest zapisany wraz z sygnaturą czasową w oddzielnym pliku. Ten plik jest używany później przez przeglądarkę do wyświetlania stanu urządzenia (załączony/wyłączony).
    Poniżej skrypt IR.php przyjmujący dane z ESP i zapisujący je w bazie:
    Code: php
    Log in, to see the code

    Skrypt IR.php jest swojego rodzaju interfejsem pomiędzy układami, a „światem zewnętrznym”. Poniżej opis jego wykorzystania w testowym pilocie oraz bezpośrednio w zapytaniu GET.

    Testowy „pilot”
    Code: php
    Log in, to see the code

    Skrypt działa jako demonstracyjny pilot. Możemy wysłać dowolny kod przycisku do dowolnego ESP. Funkcja wyślij() pokazuje jak wysłać kod. Jednym z parametrów jest nrir – to nazwa konkretnego układu i skompilowanego dla niego kodu. W przedstawionym przykładzie jest to „IRX1” (z APname).
    Jeśli mamy kilka układów, to musimy skompilować kod wielokrotnie za każdym razem zmieniając APname na IRX2, IRX3 itd. U mnie każdy układ przy starcie pyta się o aktualizację OTA, ale to zapytanie odnotowuje także APname i IP po stronie serwera. Dlatego zawsze wiem pod jakim IP jest w danym momencie konkretny układ:
    Code: php
    Log in, to see the code

    Wszystko to można zmienić – wystarczy po prostu nadać układom konkretne stałe IP.
    Polecenia pilota można także wysyłać za pomocą GET np.:
    http://192.168.1.20/IR.php?akcja=IRget&nrir=IRX1&remote=TV-SONY&button=Power

    Podsumowanie
    Zaproponowane rozwiązanie jest bardzo uniwersalne. Umożliwia sterowanie wieloma urządzeniami przez wiele nadajników IR. Kody można wgrywać do bazy także po uruchomieniu całości. Każdy z nadajników może wysyłać dowolną sekwencję i nie wymaga w tym celu przeprogramowania. Niestety taka uniwersalność skomplikowała rozwiązanie pod kątem prezentacji na elektrodzie. Na koniec kilka uwag odnoście prezentowanego układu nadajnika/odbiornika. Otóż jeszcze przed zakupem zauważyłem, że dioda IR jest sterowana tranzystorem bez jakiegokolwiek rezystora ograniczającego prąd. Jest to o tyle ciekawe, że całość zasilana jest ze stabilizatora mogącego dać nawet 1 A, co jest stanowczo za dużo jak na diodę IR. Układ jednak działa, a dioda się nie spaliła. Prawdopodobnie za ogranicznik prądu robi tranzystor, którego beta mocno spada wraz z prądem, co przy rezystorze 1 kΩ na bazie widocznie wystarcza. Układ ma jeszcze jedną wadę – umieszczenie diody IR. Praktycznie nie da się tego zabudować (dioda jest niższa niż płytka z ESP). Należy zatem rozwiązać to jakoś inaczej – albo diodę przelutować na drugą stronę, albo wyprowadzić ją na przewodzie. W każdym razie jej oryginalne miejsce jest niefortunne.

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    krzbor
    Level 25  
    Offline 
    krzbor wrote 1107 posts with rating 632, helped 21 times. Been with us since 2004 year.
  • Suntrack
  • #2
    TechEkspert
    Editor
    Ciekawa sprawa, taki most IR, może nawet posłużyć w prostych instalacjach z klimatyzatorem w pomieszczeniach technicznych, gdzie klimatyzator nie ma łączności z BMS. Można awaryjnie wysłać kod włączenia klimatyzacji/zmiany parametrów. W domu można wysłać komendy do klimatyzacji, sprzętu audio, wideo, szczególnie, że czasem pilotów do TV, dekoderów, odtwarzaczy itp.
  • Suntrack
  • #3
    krzbor
    Level 25  
    Prawdopodobnie jako klasyczny pilot układ nie znajdzie zastosowania - trzeba wziąć telefon, uruchomić stronę i nacisnąć przycisk. Tu pilot będzie zawsze szybszy i wygodniejszy. Sprawa wygląda inaczej, gdy mamy 2 telewizory i jeden odbiornik SAT. Tam gdzie jest SAT możemy użyć klasycznego pilota, a w drugim pomieszczeniu - zaprezentowane rozwiązanie jest całkiem dobre. Robiłem próby, czy sygnały będą odbierane "z odbicia" - czyli od przeciwległej ściany (odległość ok. 4 m). Dla TV SONY było to możliwe, ale wzmacniacz DENON już nie łapał tego typu sygnałów. Wszystko jednak zależy od mocy diody IR i ich liczby. Chyba jednak najciekawszym rozwiązaniem jest sterowanie na większą odległość np. przy klimatyzacji. Jeśli tylko w samej jednostce wewnętrznej jest trochę miejsca na miniaturowy zasilacz i ESP, to wszystko można w niej zabudować. Wystarczy diodę IR doprowadzić w pobliże odbiornika. Można użyć dodatkowego pinu, aby dołożyć DS18B20. Wówczas nasz układ może nam także meldować o temperaturze.
    Ciekawe może być także użycie tego układu do nadzoru nad starszą osobą. Tu jeszcze potrzebujemy kamerę, aby widzieć co się dzieje np. na odbiorniku TV.
  • #4
    khoam
    Level 42  
    krzbor wrote:
    Chyba jednak najciekawszym rozwiązaniem jest sterowanie na większą odległość np. przy klimatyzacji. Jeśli tylko w samej jednostce wewnętrznej jest trochę miejsca na miniaturowy zasilacz i ESP, to wszystko można w niej zabudować.

    A biorąc pod uwagę, ile "śpiewają" sobie niektórzy producenci klim za "moduł sterujący Wi-Fi", rozwiązanie przedstawiane przez Ciebie jest jak najbardziej na miejscu. Dla przykładu, do klimatyzatorów w moim domu sprzedawca "życzy" sobie ok. 400 PLN za pojedynczy moduł (po upustach za 3 takie moduły).
  • #5
    krzbor
    Level 25  
    Tu jeszcze dopowiem odnośnie kodów sterujących. Mój pilot klimatyzatora wysyłał je tylko raz. To dziwne rozwiązanie, bo piloty zwykle powtarzają sekwencję kilkakrotnie. Gdy zrobiłem układ, zauważyłem że nie zawsze klimatyzator się załączał i wyłączał. Rozwiązałem to bardzo prosto - sekwencja zał/wył zawsze kończy się na zał. Dodałem więc na końcu liczbę 10000 (100 ms przerwy) i skopiowałem ponownie całą sekwencję sterującą. Teraz działa za każdym razem. W ten sposób można łączyć kilka rozkazów, ale całość nie może być dłuższa niż 512 wpisów. W razie czego można jednak zwiększyć długość bufora w programie.

    khoam wrote:
    Dla przykładu, do klimatyzatorów w moim domu sprzedawca "życzy" sobie ok. 400 PLN za pojedynczy moduł (po upustach za 3 takie moduły).

    Za 400 zł można zrobić kilkanaście "moich" modułów :) Jeśli jednak klimatyzator ma miejsce na moduł Wi-Fi, to tam będzie zapewne złącze i trochę fizycznego miejsca. Z takiego złącza można wziąć zasilanie - jeśli będzie to 12 V, to wystarczy miniaturowa przetwornica, jeśli 5 V to wystarczy stabilizator liniowy - wydajność prądowa powinna być odpowiednia, bo wszystkie moduły Wi-Fi pobierają mniej więcej tyle samo.
  • #6
    weryfany
    Level 26  
    Jedyny argument to że nie ma "chmury typu p2p" w całym sterowaniu.
    Ostatnio kupiłem na aliexpress moduł IR-Wi-Fi kosztował aż 12 zł i sterujemy nim nawet z wysp Bahama (o ile jest tam internet). Funkcjonalność tutaj jest po stronie aplikacji na smartfonie. Harmonogramy włączeń/wyłączeń/sekwencji generowania sygnałów) z różnych pilotów. Do dyspozycji jest ogromna baza pilotów. Jak by brakowało nam danego pilota i producenta, możemy dodać własny, pod warunkiem że posiadamy fizycznie pilot.
  • #7
    Yazu
    Level 12  
    >>20604370
    Możesz zrobić taki moduł sam, tylko obsługa z telefonu nie jest wygodna.
    Link
  • #8
    gulson
    System Administrator
    Dzięki za opis ciekawej konstrukcji. Sporą popularność zdobyłeś. Napisz do mnie paczkomat i otrzymasz upominek.