Komunikacja urządzeń inteligentnego domu – Arduino i OpenWRT

Zgodnie z koncepcją, przygotowałem część sprzętową mojego systemu odpowiedzielnego za podlewanie ogródka i parę innych rzeczy. Obiecałem, że wkrótce napiszę, jak to wszystko oprogramować. Wcześniej jednak należałoby zaprojektować komunikację różnych elementów systemu – nie tylko części odpowiedzialnej za podlewanie, ale urządzeń związanych z automatyką domową w szczególności.

Jak już wiecie z koncepcji systemu, „mózgiem” będą routery (jeden główny, drugi zapasowy) z oprogramowaniem w php. Oczywiście nie muszą to być routery – w szczególności mogą to być serwery, komputery, cienkie klienty lub inne urządzenia, na których można uruchomić Linuksa. Router (z zainstalowym OpenWRT) jest o tyle dobrym wyborem, że jest energooszczędny a dodatkowo i tak działa cały czas pełniąc inne funkcje.

Ze względu na zastosowane technologie (m.in. Ethernet Sield do Arduino), naturalne będzie użycie protokołu HTTP. W takim wypadku możliwa jest komunikacja zarówno od routera do Arduino, jak i  w drugą stronę. Komunikaty będą jednak na tyle niezależne od protokołu, że gdy zajdzie taka konieczność, będzie można wykorzystać inne medium komunikacji, jak port szeregowy (gdyby w przyszłości np. zaszła konieczność bezpośredniego połączenia dwóch Arduino, a jedno z nich nie miałoby podłączenia do sieci).

Będziemy operować pojęciem komunikatu – krótkiej wiadomości określającej funkcję i jej parametry. Komunikat będzie możliwe zwięzły i łatwy do interpretacji po stronie Arduino – będziemy więc unikać złożonych poleceń zawierających wiele parametrów. Pozwoli to uprościć oprogramowanie, a co za tym idzie zmniejszy ryzyko błędów w nim.

Każde urządzenie podrzędne (w tej chwili Arduino) posiadać będzie własny identyfikator – jeden znak, którym „podpisywać” będzie każdy komunikat. Urządzenie nadrzędne także będzie umieszczać takie oznaczenie w każdym komunikacie. Pozwoli to dodatkowo upewnić się, że informacja trafia do właściwego urządzenia (oraz od niego pochodzi).

Co więc będzie zawierał komunikat? Identyfikator urządzenia podrzędnego (niezależnie czy informacja jest od czy do niego), kod polecenia/informacji – na razie też przyjmiemy, że jednoznakowy oraz parametry polecenia. Każdy z elementów będzie obowiązkowy, więc jeżeli polecenie nie ma parametrów, to podajemy „0” w ich miejsce. Proste? Po tym opisie nie wygląda tak? Weźmy więc przykład.

Mamy Arduino Uno, któremu nadaliśmy identyfikator „u”. Chcecmy je zapytać o stan wejść (czyli np. informację o otwarciu drzwi, zalaniu pomieszczania, itp.). Wysyłamy więc do niego komunikat ui0 – gdzie „u” to identyfikator, „i” to polecenie „podaj mi stan wejść”, a „0” to parametr, w tym wypadku nieistotny. Arduino odpowiada np. 0011, czyli dwa wejścia mają stan niski a dwa – wysoki. Inny przykład – Arduino zauważyło, że ktoś otworzył drzwi do piwnicy, czyli zmienił się stan drugiego (czyli nr 1, licząc od 0) wejścia ze stanu niskiego na wysoki. Wysyła więc komunikat do routera – uh1, gdzie pierwszy znak to niezmiennie identyfikator Arduino, „h” to polecenie „wejście zmieniło stan na wysoki”, a „1” to parametr określający, że chodzi o pierwsze wejście.

Przykład z życia – podlewanie. Router chciałby (ewentualnie program w telefonie domownika lub jego przeglądarka, jeżeli na to pozwolimy), żeby Arduino zaczęło podlewanie – trawy przez 60 sekund, a reszty przez 30. Wysyła więc trzy komunikaty – ut60, ur30, us0 – ustaw czas podlewania trawnika na 60 sekund, reszty na 30, rozpocznij nawadnianie wg zaprogramowanych czasów. Arduino na każdy z nich odpowiada „OK”, uruchamia dopływ wody i wysyła komunikat do routera uw1, oznaczający, że właśnie zaczęło się podlewanie pierwszej sekcji (trawnika). Dalej to już Arduino dba o to, żeby zakończyć działanie o właściwym czasie i wysłać odpowiedni komunikat do systemu nadrzędnego.

Jak do tego użyć protokołu HTTP (tego, którego używają przeglądarki internetowe)? Przy tak zwięzłych komunikatach najprościej w zapytaniu typu GET (czyli w adresie strony internetowej). Gdy nasze Arduino ma adres 192.168.0.133, to otwieramy stronę internetową http://192.168.0.133/ut60,ur30,us0 i zaczyna się podlewanie (przez 60 i 30 sekund),a w przeglądarce dostajemy 3 linie „OK”. Banalne, prawda?

W drugą stronę, Arduino wpisze jeszcze nazwę skryptu php, jako, że na routerze mogą też działać jeszcze jakieś inne strony. Po rozpoczęciu podlewania wywoła więc połączenie ze stroną http://192.168.0.1/cmd.php?c=uw1, gdzie 192.168.0.1 to adres urządzenia nadrzędnego, cmd.php to adres skryptu, c to przekazywany parametr, a uw1 to nasz komunikat. Przy założeniu, że „http://192.168.0.1/cmd.php?c=” jest niezmienne i dołączane zawsze przy zapytaniu do tego routera, to także proste, prawda?

Jak od strony sieci wygląda takie zapytanie? Łatwo to sprawdzić w dokumentach RFC dla protokołu http, ale w skrócie napiszę, że otwarcie połączenia z portem 80 serwera (Arduino lub routera) i wysłanie ciągu znaków typu „GET /ut60,ur30,us0 HTTP/1.0” (oraz ewentualnych nagłówków w kolejnych liniach, ale to na razie pominiemy w rozważaniach) i zakończeniu pustą linią. Odpowiedzią serwera jest linia ze statusem odpowiedzi (np. „HTTP/1.1 200 OK”), liniami nagłówków określającymi parametry (np. rodzaj dokumentu i informację czy połączenie będzie kontynuowane czy zakończone) oraz treści po pustej linii. Trochę bardziej złożone? Nic podobnego, w praktyce również bardzo proste – o czym zaświadczy program, gdy pojawi się na blogu – pewnie wkrótce.

Uff… Dużo rozważań teoretycznych, jak na jedn raz. Protokół komunikacyjny, za pomocą którego „rozmawiać” będą wszystkie urządzenia, to jednak ważna rzecz.

Ten wpis został opublikowany w kategorii Inteligentny Dom i oznaczony tagami , , , , , . Dodaj zakładkę do bezpośredniego odnośnika.

0 odpowiedzi na Komunikacja urządzeń inteligentnego domu – Arduino i OpenWRT

  1. luck pisze:

    Witam
    Mam pewne, pewnie banalne pytanie…. 🙂
    Czy można (w jakiś sposób) połączyć się z tym routerem poprzez wifi i odczytać te dane?
    Czy możliwe jest zdalne połączenie się z ruterem – poprzez Internet z drugiego końca Polski ?
    Pozdrawiam

  2. Kofec pisze:

    Arduino i Openwrt – Ja używam Dragino ale mysle ze nie warto. Używam tez LEDE (Openwrt) na Raspberry PI + Arduino (MySensors).

Skomentuj luck Anuluj pisanie odpowiedzi

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *