Wstęp
Skoro otworzyliście ten kurs jesteście zainteresowani sterowaniem Waszym arduino z ESP8266 przez internet, albo na mniejszą skalę w sieci lokalnej. Na filmie znajduje się demo które pokazuje co mnie udało się osiągnąć. W dalszej części kursu wrócimy do omówienia co się na filmie dzieje, i dlaczego to działa w pokazany sposób.
Ogolnie, żeby sterować czymś przez przeglądarkę musimy mieć coś co będzie nam serwowało stronę internetową. Opcji jest kilka :
ESP8266 jako web serwer
Jest to najprostsza opcja, polega ona na tym, że nasze arduino przyjmuje requesty HTTP ( najczęściej jest to sam GET). Samą stronę internetową serwuje nam arduino więc w jego pamięci musimy mieć ją zakodowaną. Gdy podłączymy się do arduino w odpowiedzi dostajemy po prostu html’a którego przeglądarka nam odpowiednio wyświetli. Arduino musi też rozpoznawać parametry które przekażemy w adresie np:
1 |
192.168.0.1/?led=ON |
wtedy przed zaserwowaniem samej strony internetowej arduino analizuje przekazane parametry i odpowiednio reaguje.
Tutaj możecie znaleźć kurs który pokazuje jak taki efekt osiągnąć
Zaletą tego rozwiązania jest to, że poza arduino nie potrzebujecie niczego innego. Wad jest więcej:
- ograniczona wielkość pamięci – więc nasza strona będzie ascetyczna, nie będziemy mogli sobie pozwolić na grafiki, czy coś bardziej skomplikowanego
- jeżeli stan diody zostanie zmieniony nie przez naszą stronę internetową, tylko poprzez guzik na arduino, albo przez inną niż nasza przeglądarka nie dowiemy się o tym.
- Jeżeli będziemy chcieli zmienić wygląd naszej strony musimy ponownie wgrać ją na arduino
Osobny serwer w sieci lokalnej
Strona internetowa jest serwowana przez serwer który znajduje się w sieci lokalnej, np może to być raspberryPi.
Tutaj kurs jak coś takeigo zrobić
Teraz zalet jest zdecydowanie więcej :). Gdy zdecydujemy się na takie rozwiązanie musimy podjąć decyzje czy strony internetowe będziemy pisali sami wtedy:
- pierwsza decyzja w czym napiszemy serwer może to być np PHP wtedy potrzebujemy np Apache Server, możemy też się zdecydować na popularny teraz NodeJS – zależy to od waszych preferencji i od tego w czym czujecie się dobrze
- komunikacja z arduino
- arduino przez websockety jest podłączone do naszego serwera, a serwer odbierając komunikaty od przeglądarki wysyła po otwartym połączeniu komendy do arduino
- serwer służy tylko do serwowania stron html, a my przez osobne bezpośrednie połączenie wysyłamy komunikaty do arduino np podobnie jak przy przykładzie dla “ESP8266 jako web serwer” albo połączenie websocketowe
Możemy też skorzystać z gotowych rowiązań, jest ich naprawde sporo tutaj najbardziej popularne:
Wybierając gotowe rozwiązanie godzimy się na ograniczenia, np domoticz/smarthome powstały z myślą o inteligentym domu i nie zbudujemy np robota
z serwerem w sieci lokalnej są dwa zasadnicze problemy
- musimy mieć serwer – osobiście postawiłbym na raspberryPi – wtedy raz na jakiś czas pada nam karta SD, więc musimy dbać o dobry backup, ale mamy zalety takie jak koszt samego RPi i niski pobór prądu, a samo RPi możemy wykorzystać też jako NAT
- żeby mieć możliwość sterowania poza siecią lokalną potrzebujemy mieć publiczny adres IP (+ przekierowanie portu na routerze ) , lub serwisem np remot3.
Remoteme.org
W tym kursie chciałbym Wam opisać system nad którym sam pracuje i który wg mnie oferuje dużo możliwości, bez ograniczania np nie jest problemem zbudować sobie robota z podglądem FPV albo możemy wykorzystać go do sterowania diodą podpiętą do naszego arduino – i od tego zaczniemy ;)
Co oferuje nam remoteme.org :
Głównym zadaniem systemu remoteme.org to podłączenie wszystkich Waszych urządzeń RPi, arduino, strony internetowe, skrypty, programy komputerowe do jednej szyny transmisyjnej – brzmi skomplikowanie więc wyjaśnię na trywialnym przykładzie listonosza.
- nasz listonosz czyli remoteme.org zna się ze wszystkimi urządzeniami – rozpoznaje je po ich adresie – każde urządzenie ma własny deviceId
- gdy urządzenie A chce wysłać Wiadomość do urządzenia B do koperty wkłada tablice bajtów , a na kopercie wpisuje adres urządzenia do którego koperta ma być dostarczona czyli deviceId
- listonosz dostarcza dwa rodzaje listów:
- listy asynchroniczne czyli takie na które nie oczekujemy odpowiedzi, to moze byc polecenie typu zapal mi diodę, albo skręć kołami w prawo – ja takie listy nazywamy UserMessage
- listy synchroniczne czyli takie na które oczekujemy odpowiedzi czyli wysyłamy naszego listonosza i czekamy w drzwiach, aż wróci z odpowiedzią, np – czy lampka led jest zapalona, jaka jest temperatura teraz – takie wiadomości nazywamy UserSyncMessage
- udostępniłem biblioteki dzięki którym z tym listonoszem (czyli z systemem app.remoteme.org) możecie sie łatwo komunikować przykład javascriptowy:
1remoteme.sendUserMessageByFasterChannel (123,[1,1,2,3,5,8]);tutaj do urządzenia z id 123 wyślemy tablice bajtów. A tutaj
123remoteme.sendUserSyncMessageWebSocket(123,[6],function(data){printTemperature(data[0]);});wyślemy do urządzenia 123 liczbę 6 i poczekamy na odpowiedź, bo wcześniej umówiliśmy się z urządzeniem ze jak dostanie liczbe 6 to w odpowiedzi ma liczbę – temperaturę.
- I przykład odbioru wiadomości – ale tym razem w arduino
1234567891011121314151617181920212223void setup() {...remoteMe.setUserMessageListener(onUserMessage);remoteMe.setUserSyncMessageListener(onUserSyncMessage);...}void onUserSyncMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t* data, uint16_t &returnDataSize, uint8_t *&returnData) {if (data[0]==6){returnDataSize=1;returnData=(uint8_t*)malloc(dataSize);returnData[0]=readTemperature();}}void onUserMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t *data) {doSomething();}w setup mówimy jakie remoteme.org ma wywołać funkcję gdy przyjdzie synchroniczny list, a co jak asynchroniczny (na dole w przykładzie z mrugającą diodą wszystko dokładnie opisze)
Samo remoteme.org daje wam też możliwość pisania własnych stron internetowych, i umieszczania ich tak, że są dostępne z zewnątrz. Też pokaże to w przykładzie na dole.
Dodatkowo remoteme.org udostępnia Wam baze danych gdzie możecie przechowywać odczytywaną temperaturę i potem ją wyświetlić w jaki sposób chcecie (na własnej stronie internetowej) – to pokaże w kolejnych kursach
Jest też możliwość napisania własnych skryptów które działają na serwerze np skrypt czeka na wiadomość od arduino, gdy nadejdzie łączy się z systemem pogodowym pobiera pogodę na następne 3 dni i zwraca ją w odpowiedzi jako prostą tablice bajtów, którą arduino przetwarza i wyświetla
Wiadomość do Waszych urządzeń możecie też wysłać korzystając z API Restowego, np jakiś zewnętrzny system uruchomi odpowiedni adres URL, a arduino w tym czasie włączy syrenę
(Opisane przykłady zastosowań zostały przezemnie już przetestowane i wkrótce powstaną kursy :) )
Oczywiście do Waszych stron internetowych, urządzeń tylko Wy macie dostęp.
Działanie
Przedewszstkim w systemie remoteme.org musicie mieć własne konto. Do konta generujecie Tokeny (klucze). Jak konfigurujecie “listonosza” ( patrzy przykład z listonoszem powyżej) podajecie mu ten token i wtedy listonosz dostarczy wiadomości tylko do Waszych urządzeń.
Bardziej formalnie: Do podłączenia do systemu remoteme.org każde urządzenie musi skorzystać z wygenerowanego wcześniej tokenu przypisanego do użytkownika, bez znajomośći tokenu nie ma możliwości wysłać wiadomość do żadnego urządzenia. Każdy użytkownik może wygenerować kilka tokenów. Tokeny oprócz wysyłania wiadomości oferują możliwość wyświetlania naszych stron internetowych – w adresie URL znajduje się token – dlatego gdy nie chcemy żeby dany URL wyświetlał stronę po prostu go dezaktywujemy lub usuwamy. Stąd też tokeny mają nazwę, żebyśmy wiedzieli do czego ich użyliśmy – trywialny przykład nazywamy token “Dla Weroniki” ,a strona internetowa służy do logowania się na kamerkę i obserwowania co robi kot w mieszkaniu (też będzie tutorial do takiego zastosowania :) ), po rozstaniu z Weroniką kasujemy jej token i nie może już ona mieć dostęp do kamerki.
Trochę szczegółów technicznych
Najczęściej nasze urządzenia – włączając w to strony internetowe, tworzą połączenie websocketowe z systemem remoteme.org, po tym połączeniu jest realizowana komunikacja. Połączenie websocketowe nie jest zawsze wymagane, remoteme.org udostępnia api restowe z którego można wysyłać wiadomości , odczytywać/zapisywać wartości z bazy danych. Autoryzacja połączeń Restowych wymaga podania w headerze pod wartością token – Tokenu, lub przekazaniu go bezpośrednio w URL’u, lub gdy wcześniej zostaliśmy zalogowani (sesja http) autoryzacja tokenem nie jest konieczna.
Na razie dostępne są biblioteki dla javascriptu, arduino, rasbperryPi
kody żródłowe bibliotekaArduino bibotekeJavascriptowa
W innych kursach na przykładach pokażę jak korzystać z bazy danych, komunikacji webRTC z rasbperrypi, wywoływania skryptów na serwerze remoteme.org
Przykład
Po dość długim wstępie pokażę na przykładzie jak zacząć zabawę z systemem remoteme.org. Chciałem żebyście mieli świadomość problemów jakie napotkacie przy sterowaniu urządzeniami przez internet i mieli świadomość jak działa system remoteme.org stąd też ten wstęp. Mam nadzieje że w Waszej głowie powstały już przykłady zastosowania remoteme.org dla Waszych potrzeb.
Kurs pokaże Wam jak sterować diodą podpiętą do arduino przez internet i przycisk.
Wymagania
- płytka z esp8266
- dioda
- rezystor
- przycisk
- umiejętność wgrywania programu na Waszą płytke z ESP9266 tutaj kurs
Podłączenie i opis co chcemy uzyskać
- podłączenie
- za każdym razem gsy naciśniemy guzik:
- dioda zmienia swój stan
- do strony internetowej jest wysyłany aktualny stan diody
- strona internetowa odbiera stan i aktualizuje obraz diody
- Jak strona internetowa jest uruchamiana wysyła zapytanie do arduino o aktualny stan diody
- Gdy wciśniemy symbol diody na stronie
- strona wysyła komendę zmien stan do arduino
- arduino aktualizuje diode
- arduino wysyła komunikat do strony z aktualnym stanem diody
Na filmie mam otwartą stronę internetową w trzech przeglądarkach – dwie w chromie, jedną na telefonie komórkowym. Jak widzicie stan diody zmienia się na wszystkich urządzeniach. Sam telefon komórkowy jest podpięty przez LTE – chciałem pokazać że wszystko działa poza siecią lokalną.
Dodatkowe Biblioteki
Musimy je zainstalować, są tutaj biblioteki do tworzenia klienta websocketowego, umożliwiające nawiązanie połączenia z WIFI, biblioteki do przycisku które zlikwidują problem drgania przycisku. I sama biblioteka remoteme.org bez niej nie podłączymy się do systemu. Poniżej wypisane biblioteki ze screenami żeby było łatwiej odpowiednią bibliotekę znaleźć
- WebSockets by Markus Sattler
- ArduinoHttpClient by Arduino
- ESP8266WiFi by Iven Grokhotkov
- RBD_Timer by Alex Taujenis
- RBD_Button by Alex Taujenis
- RemoteMe libraries by Remoteme.org
- Jak pisze ten kurs biblioteki nie są jeszcze dostępne w repozytorium i należy zainstalować je ręcznie
- ściągnijmy paczkę zip najnowszych bibliotek stąd
- a następnie dodajemy bibliotekę jako zipa:
- i sprawdźmy czy wysztko jest OK:
Sprawdzenie połączeń:
Poniższy program to tylko zmiana stanu diody za każdym razem gdy wciśniemy przycisk. Jak coś jest niezrozumiałe zachęcam do otwarcia dowolnego kursu “miganie diodą”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <RBD_Timer.h> #include <RBD_Button.h> uint8_t LEDpin = D5; RBD::Button button(D2); boolean currentState = false; void setup() { Serial.begin(9600); pinMode(LEDpin, OUTPUT); digitalWrite(LEDpin, LOW); } void changeDiodeState( ) { currentState= !currentState; digitalWrite(LEDpin, currentState?HIGH:LOW); } void loop() { if (button.onPressed()) { changeDiodeState(); } } |
Konfigurowanie systemu remoteme:
Zanim wrócimy do naszego arduino zarejestrujmy się w systemie i utwórzmy token – którego zadania opisałem wyżej.
Rejestracja
- przejdźmy pod adres klik tutaj
- zakładka Sign Up
- nie podajecie swojego maila więc nie ma możliwości odzyskania hasła – musicie je zapamiętać
- klik SignUp system od razu nas zaloguje
Tworzenie tokenu
Za pomocą tokenu dodanego do programu na arduino, arduino będzie się łączyło do naszego konta.
- Przechodzimy po lewej stronie do zakładki Tokens
- Klikamy New Token, uzupełniamy nazwę (obojętne co wpiszemy ) i klikamy OK
- [3] jest to jedyne pole jakie wypełniacie – nazwy tokenu jest tylko dla nas, nie jest wykorzystywana nigdzie indziej poza wyświetleniem tokenu na liście tokenów.
- Token zostanie utworzony:
- Jak tokenu nie widać odświeżamy stronę.
- w moim przypadku token to “~267_ZxoWtJ)0ph&2c” można go skopiować klikając w niebieską ikonkę
Właściwy program na arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
#define WIFI_NAME "" #define WIFI_PASSWORD "" #define DEVICE_ID 203 #define DEVICE_NAME "diodeWithButtonArduino" #define TOKEN "" #define WEBPAGE_DEVICE_ID 1001 #include <ArduinoHttpClient.h> #include <RemoteMe.h> #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <RBD_Timer.h> #include <RBD_Button.h> uint8_t LEDpin = D5; RBD::Button button(D2); ESP8266WiFiMulti WiFiMulti; RemoteMe& remoteMe = RemoteMe::getInstance(TOKEN, DEVICE_ID); boolean currentState = false; void setup() { Serial.begin(9600); WiFiMulti.addAP(WIFI_NAME, WIFI_PASSWORD); while (WiFiMulti.run() != WL_CONNECTED) { delay(100); } remoteMe.setUserMessageListener(onUserMessage); remoteMe.setUserSyncMessageListener(onUserSyncMessage); remoteMe.setupTwoWayCommunication(); remoteMe.sendRegisterDeviceMessage(DEVICE_NAME); pinMode(LEDpin, OUTPUT); digitalWrite(LEDpin, LOW); } void onUserSyncMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t* data, uint16_t &returnDataSize, uint8_t *&returnData) { returnDataSize = 1; returnData = (uint8_t*)malloc(returnDataSize); Serial.println("received sync message"); uint16_t pos = 0; RemoteMeMessagesUtils::putUint8(returnData, pos, currentState ? 1 : 0); } void onUserMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t *data) { changeDiodeState(); } void changeDiodeState( ) { currentState= !currentState; digitalWrite(LEDpin, currentState?HIGH:LOW); uint16_t returnDataSize = 1; uint16_t pos = 0; uint8_t *data = (uint8_t*)malloc(returnDataSize); RemoteMeMessagesUtils::putUint8(data, pos, currentState?1:0); remoteMe.sendUserMessage(WEBPAGE_DEVICE_ID, data, returnDataSize); } void loop() { remoteMe.loop(); if (button.onPressed()) { changeDiodeState(); } } |
Możemy go wgrać do arduino (Oczywiście wcześniej musimy uzupełnić nazwę sieci WIFI hasło do niej i nasz wygenerowany token we wcześniejszym kroku ) :
1 2 3 4 5 |
#define WIFI_NAME "" #define WIFI_PASSWORD "" #define DEVICE_ID 203 #define DEVICE_NAME "diodeWithButtonArduino" #define TOKEN "~267_ZxoWtJ)0ph&2c" |
musimy uzupełnić o nasze dane.
- WIFI_NAME – nazwa naszej sieci Wifi
- WIFI_PASSWORD – hasło do wifi
- DEVICE_ID id urządzenia jest to też adres urządzenia w remoteme.org w naszym przypadku to 203 i pod takim adresem widnieje na stronie
- DEVICE_NAME nazwa urządzenia pod jaką zarejestruje się arduino
- TOKEN – wcześniej wygenerowany token bez niego arduino nie będzie wiedziało do jakiego konta się podłączyć (wpisałem mój zmieńcie go)
Po uruchomieniu, na stronie naszych urządzeń zostanie dodane nowe urządzenie a zielona ikonka wskazuje, że jest ono aktualnie podłączone.
opis funkcji tutaj
Opis działania
1 |
RemoteMe& remoteMe = RemoteMe::getInstance(TOKEN, DEVICE_ID); |
to miejsce tworzy obiekt klasy remoteMe, za jego pomocą będziemy wysyłać wiadomości do naszej strony internetowej, i obiekt ten również wywoła odpowiednie funkcję gdy strona wyśle wiadomość do naszego arduino lub poprosi o aktualny stan diody.
stała TOKEN to wcześniej wygenerowany token, a DEVICE_ID w naszym przypadku 203 to deviceId czyli adres urządzenia który wykorzystamy wysyłając wiadomości do arduino.
jest też stała
1 |
#define WEBPAGE_DEVICE_ID 1001 |
pod 1001 będzie znajdowała się dodana później strona internetowa
w funkcji setup
1 2 3 4 |
WiFiMulti.addAP(WIFI_NAME, WIFI_PASSWORD); while (WiFiMulti.run() != WL_CONNECTED) { delay(100); } |
łączymy się z siecią wifi i czekamy aż połączenie zostanie nawiązanie.
1 2 |
remoteMe.setUserMessageListener(onUserMessage); remoteMe.setUserSyncMessageListener(onUserSyncMessage); |
ustawiamy funkcje które zostaną wywołane gdy nadejdzie wiadomość od strony internetowej (osobne funkcje dla wiadomości synchronicznych i asynchronicznych)
1 |
remoteMe.setupTwoWayCommunication(); |
ustawiamy komunikacje która będzie odbierała i wysyłała wiadomości do arduino.
1 |
remoteMe.sendRegisterDeviceMessage(DEVICE_NAME); |
Oraz rejestrujemy nasze urządzenie na stronie app.remoteme.org – dzięki temu urządzenie pojawi się w zakładce devices.
Zasada działania. Strona internetowa wysyła wiadomość (treść wiadomości jest nieistotna) którą odbiera funkcja:
1 2 3 |
void onUserMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t *data) { changeDiodeState(); } |
Jak widzicie parametry senderDeiviceId dataSize, data nie są wykorzystywane, dlatego niezależnie co znajduje się w wiadomości zawsze wywołujemy funkcje do zmiany stanu diody:
1 2 3 4 5 6 7 8 9 10 11 |
void changeDiodeState( ) { currentState= !currentState; digitalWrite(LEDpin, currentState?HIGH:LOW); uint16_t returnDataSize = 1; uint8_t *data = (uint8_t*)malloc(returnDataSize); uint16_t pos = 0; RemoteMeMessagesUtils::putUint8(data, pos, currentState?1:0); remoteMe.sendUserMessage(WEBPAGE_DEVICE_ID, data, returnDataSize); } |
funckje powyżej wywołujemy również, gdy wciśniemy przycisk. Na początek zmieniamy stan diody, potem przygotowujemy wiadomość. Wiadomość ma rozmiar jednego bajta:
1 2 |
uint16_t returnDataSize = 1; uint8_t *data = (uint8_t*)malloc(returnDataSize); |
w bajcie tym wpisujemy 1 gdy dioda się aktualnie świeci i 0 gdy jest zgaszona:
1 2 |
uint16_t pos = 0; RemoteMeMessagesUtils::putUint8(data, pos, currentState?1:0); |
funkcja putUint8 jako parametry posiada:
- tablice gdzie zapisze dane w tym przypadku bezznakowy integer ośmio bajtowy
- pozycje pos w którym miejscu ma zapisać wartość, pos jest przekazywana przez referencje i we wnętrzu funkcji jest inkrementowana o ilość bajtów ile wpisywana liczba zajmuje (w tym przypadku jest to 1 ale są też funkcje do zapisu stringów, floatów)
- i ostani parametr liczba 0 lub 1 czyli stan aktualny diody
krócej można by zapisać:
1 2 3 |
uint16_t returnDataSize = 1; uint8_t *data = (uint8_t*)malloc(returnDataSize); data [0]= currentState?1:0 |
ale zachęcam do skorzystania z klasy RemoteMeMessagesUtils
na koniec wysyłamy wiadomość do strony internetowej:
1 |
remoteMe.sendUserMessage(WEBPAGE_DEVICE_ID, data, returnDataSize); |
Funkcja do odczytu aktualnego stanu diody:
1 2 3 4 5 6 7 8 |
void onUserSyncMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t* data, uint16_t &returnDataSize, uint8_t *&returnData) { returnDataSize = 1; returnData = (uint8_t*)malloc(returnDataSize); Serial.println("received sync message"); uint16_t pos = 0; RemoteMeMessagesUtils::putUint8(returnData, pos, currentState ? 1 : 0); } |
Po odświeżeniu strony pyta ona jaki stan ma aktualnie dioda- wtedy strona zawsze pokaże prawidłowy stan diody. W funkcji powyżej odpowiadamy na tą wiadomość, wpisując bajty do przekazanej przez referencje returnData i rozmiar zwracanej tablicy w returnDataSize . Wiadomość jest jedno-bajtowa i zawiera 0 lub 1 dla odpowiedniego stanu diody.
ostatnią funkcją którą omówię to loop()
1 2 3 4 5 6 7 8 |
void loop() { remoteMe.loop(); if (button.onPressed()) { changeDiodeState(); } } |
remoteMe.loop(); <– sprawdza czy nadeszła wiadomość , stan połączenia, robi reconnecta gdy jest taka potrzeba i pare innych rzeczy – możecie sprawdzić w źródłach
Wgrajmy program na arduino.
Wysyłanie wiadomości
Wyślijmy zatem wiadomość do urządzenia – na razie nie mamy strony internetowej więc wyślijmy wiadomość z poziomu remoteme.org:
w belce z urządzeniem mamy ikonkę dymku rozmowy. Dzięki niej możemy wysłać wiadomość do urządzenia. Pola:
- 3 jako kto wysyłamy wiadomość – jest to bez znaczenia bo jak widzieliśmy w funkcji onUserMessage nie odczytujemy żadnych parametrów wywołania.
- 4 wiadomość w formie tekstowej – również po stronie arduino ignorowana
- poniżej 4 wiadomość ale w formie Heksadecymalnej
przycisk 5 wysyła wiadomość do arduino.
jak widzicie za każdym razem jak naciśniemy przycisk send – dioda zmieni swój stan.
Przetestujmy też wiadomość synchroniczną, jak pamiętamy po wywołaniu wiadomości synchronicznej arduino zwróci nam od razu aktualny stan diody. Tym razem klikamy w ikonke podwojnego dymku rozmowy
Pola
- 3 jako kto wysyłamy – ignorowane po stronie arduino
- 4 wiadomość w postaci stringa
- po wciśnięciu przycisku send 5 w polu 6 otrzymamy odpowiedź pierwsza linia to interpretacja wiadomości jako stringa druga to wartość heksadecymalna
w miejscu zaznaczonym nr 6 dostałem 1 bo moja dioda się świeciła. po kliknięciu Send zmieńcie status diody i kliknijcie Send ponownie powinniście dostać 1 lub 0 w zależności czy dioda się świeci czy nie.
Strona internetowa:
1 |
#define WEBPAGE_DEVICE_ID 1001 |
Tutaj w kodzie arduino ustawiliśmy id urządzenia do którego będą wysyłane wiadomości. Takiego urządzenia nie ma
Dodajmy stronę internetowa o id 1001
uzupełnimy okno:
- nazwa pod jaką będziemy widzieli urządzenie w zakładce devices (musi być unikalna czyli nie może się nazywać tak samo jak arduino ;) )
- 4 deviceID arduino wysyła pod adres 1001 więc taki podajmy w polu 4
- 5 wgramy od razu pliki do naszej strony empty sketch posiada trzy pliki wstępnie uzupełnione, zobaczycie za chwilę.
- 6 musi być aktywne
- 7 dodajemy naszą stronę internetową.
Po kliknięciu submit. zobaczymy nowe urządzenie. Po rozwinięciu przyciskiem “1” zobaczymy jakie strona ma pliki, ponieważ wybraliśmy empty sketch mamy 3 pliki index.html script.js, style.css
Otwórzmy i zmieńmy plik Index.html
do okienka które się pojawi wklejmy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/remoteMe_1_01.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/remoteMeMessages_1_01.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/adapter.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/control.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/gauge.js"></script> <script src="https://cdn.rawgit.com/remoteme/webPageTemplates/master/base/operationTimer.js"></script> <script> var thisDeviceId=####deviceId#; var arduinoId=203; </script> <script src="script.js"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div id="led" style="width:400px;height:400px;border:1px solid gray;border-radius: 400px; cursor: pointer;margin:10px" onclick="onLedClick()"></div> <script> setup(); </script> </body> </html> |
Jest to bardzo prosta strona, oprócz obowiązkowych importów, wyświetli nam okrągłego diva który będzie udawał diodę.
1 |
var arduinoId=203; |
tą zmienną wykorzystamy w javascripcie do wysyłania wiadomości gdy ktoś kliknie w diodę na stronie WWW – to jest deviceId naszego arduino
1 |
var thisDeviceId=####deviceId#; |
przed zaserwowaniem strony do przeglądarki remoteme.org zmieni ####deviceId# na 1001 bo taki jest deviceId naszej strony. Możecie sprawdzić :)
Nie zapomnijcie kliknąć przycisk “Save” ;) Możecie też przenieść style diva do pliku style.css ;)
zedytujmy plik script.js (podobnie jak plik index.html) wklejając:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
var remoteme; function setup(){ remoteme = new RemoteMe({ automaticlyConnectWS: true, automaticlyConnectWebRTC:false, webSocketConnectionChange: webSocketConnectionChange, webRTCConnectionChange: undefined, onUserMessage: onUserMessage, mediaConstraints: {'mandatory': {'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false}} }); } function onUserMessage(sender,data){ var data = new RemoteMeData(data); changeDiode(data.popUint8()) } function changeDiode(state){ $("#led").css("background-color",state==0?"white":"red"); } function webSocketConnectionChange(state){ if (state==WebsocketConnectingStatusEnum.CONNECTED){ remoteme.sendUserSyncMessageWebSocket(arduinoId,[],function(data){ var data = new RemoteMeData(data); changeDiode(data.popUint8()); }); } } function onLedClick(){ remoteme.sendUserMessageByFasterChannel (arduinoId,[]); } |
Analiza kodu:
1 2 3 4 5 6 7 8 9 10 11 12 |
var remoteme; function setup(){ remoteme = new RemoteMe({ automaticlyConnectWS: true, automaticlyConnectWebRTC:false, webSocketConnectionChange: webSocketConnectionChange, webRTCConnectionChange: undefined, onUserMessage: onUserMessage, mediaConstraints: {'mandatory': {'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false}} }); } |
definiujemy zmienna remoteme i ją inicjalizujemy (funkcję setup uruchomi nam nasz index.html)
znajdują się tutaj ustawienia więcej o nich możecie poczytać tutaj i tutaj
najważniejsze dla nas w tym momencie to
1 |
automaticlyConnectWS: true, |
dzięki temu nasz obiekt remoteme od razu połączy się z systemem.
1 |
onUserMessage: onUserMessage, |
wskazujemy jaka funkcja javascriptowa zostanie wywołana gdy przyjdzie wiadomość z arduino.
oraz:
1 |
webSocketConnectionChange: webSocketConnectionChange, |
moniturujemy stan tego połączenia i zaraz jak się połączy zapytamy nasze arduino o aktualny stan diody:
1 2 3 4 5 6 7 8 |
function webSocketConnectionChange(state){ if (state==WebsocketConnectingStatusEnum.CONNECTED){ remoteme.sendUserSyncMessageWebSocket(arduinoId,[],function(data){ var data = new RemoteMeData(data); changeDiode(data.popUint8()); }); } } |
funkcja która wysyła wiadomość synchroniczną – czyli taką na której odpoweidź czekamy:
1 |
remoteme.sendUserSyncMessageWebSocket |
pierwszy parametr to adres naszego arduino, drugi to wiadomość do wysłania – my wysyłamy pustą bo i tak nie ma ona znaczenia. oraz funkcja która zostanie uruchomiona zaraz jak dostaniemy odpowiedź z arduino:
1 2 3 4 |
function(data){ var data = new RemoteMeData(data); changeDiode(data.popUint8()); } |
korzystając z RemoteMeData pobierzemy pierwszy bajt wiadomości od arduino będzie to 1 albo 0 i potem wywołamy funkcję:
1 2 3 |
function changeDiode(state){ $("#led").css("background-color",state==0?"white":"red"); } |
która zmieni kolor kółeczka.
gdy wciśniemy przycisk na arduino ta funkcja zostanie wywołana:
1 2 3 4 |
function onUserMessage(sender,data){ var data = new RemoteMeData(data); changeDiode(data.popUint8()) } |
podobnie wyciągamy pierwszy bajt i zmieniamy stan diody.
Otwórzmy naszą stronę:
zobaczymy:
po klikaniu w kółeczko dioda przy arduino będzie się zmieniała :). A po odświeżeniu strony pokaże ona prawidłowy stan diody.
Otwórzmy stronę telefonem komórkowym z internetem mobilnym (żeby sprawdzić czy działa też poza siecią lokalną).
Zamiast logować się do systemu remoteme.org wygenerujmy kod QR który sobie zeskanujemy – wyżej pisałem że tokeny umieszczone w adresie URL od razu logują nas na nasze konto w remoteme. Jak zobaczycie w adresie URL jest podawany nasz token.
klikamy na index.html następnie Gen anonynous link, potem w okienku które się pojawi ikonkę kodu QR, i skanujemy telefonem QR code który się pojawił.
Podsumowanie:
Mam nadzieje, że przybliżyłem Wam ideę sterowania arduino przez internet, i wyjaśniłem działanie systemu remoteme.org. Nad systemem cały czas pracuje, więc jak macie jakieś sugestie, chcecie pomóc zapraszam :)
pełne źródła tutaj
zachęcam do polubienia FB
w następnym kursie coś bardziej zaawansowanego,
albo jeden z tych projektów
- stacja pogodowa
- lampka udająca koguta policyjnego
- odczytywanie temperatury ciśnienia wilgotności i zapis do bazy i wyświetlanie na stronie internetowej,
- podgląd kamerki,
Jeszcze nie zdecydowałem ;)
Pozdrawiam,
Maciek
świetna robota
Jestem co prawda świeżynka w tej tematyce, ale troche poczytałem no i zaczynam zabawę
Z tego co widze to masz dużą wiedze o module 8266
Jęsli nie byłoby to dla Ciebie problemem to chciałbym zapytać , o problem jaki mam
Mianowicie – chce zrobić termometr z wysłaniem danych na thingspeak, jeden z projektów jest na majsterkowo
Oczywiście powoli mam komplet , ale powstał problem z Ardiuno IDE , mianowicie , nie mogę skompilować kodu pod żaden moduł płytki zaimportowanych
Wyskakuje błąd kompilacji dla płytki – do żadnej nie wchodzi
masz jakiś pomysł?
Wgraj najnowsze IDE i wszystkie najnowsze biblioteki potrzebne do projektu.
Hey mam problem z funkcją setupTwoWayCommunication(); Mam zainstalowane wszystkie biblioteki jadnak nie można znaleźć tej funkcji? Czy coś się zmieniło może inna nazwa jest teraz?
W linku drzewo projektu
https://pokazywarka.pl/drzewo___/
Witam, chciałbym wykorzystać Twój pomysł, ale niestety nie mogę skompilować sketcha dla ESP 01S, gdyż wyskakuje mi bład:
‘class RemoteMe’ has no member named ‘remoteMe.setupTwoWayCommunication’
Instalowałem rózne biblioteki RemoteMe i na każdej ten sam błąd.
Masz może pomysł co może być nie tak?
Pozdrawiam Grzegorz
Cześć,
Potwierdzam, u mnie jest ten sam problem. Problem ten występuje także w innym projekcie tego autora na tym portalu (serwer z temperaturami).
Jest rozwiązanie?
Witam
Czy ten system nadal działa? Próbowałem z moim esp8266 i esp32 niestety brak połączenia. Nie działa ani socket ani websoket. Hasło i nazwa sieci wpisane poprawnie. Brak firewalli.