Układy ESP8266 / ESP32 posiadają zintegrowaną kartę WIFI. Jest to więc idealna baza do budowy modnych w ostatnim czasie urządzeń IoT. Problem komunikacji z użytkownikiem można rozwiązać na wiele sposobów. Jednym z nich jest stworzenie prostego serwera WWW, który wykorzystamy do konfiguracji oraz przesyłania danych. W najprostszym przypadku można utworzyć prostą stronę WWW, na której będziemy wyświetlać dane odczytywane z czujników podłączonych do naszego urządzenia.
Zaczynamy
W sieci Internet można znaleźć kilka bibliotek wspomagających budowę serwera WWW na układach ESP. W poniższym przykładzie skorzystałem z dostępnej po zainstalowaniu biblioteki: ESP8266WebServer. W pierwszym kroku utworzymy nowy punkt dostępowy, żeby w prosty sposób można było dostać się na naszą nową stronę.
const char *ssid = "NAZWA_AP";
const char *password = "klucz";
WiFi.softAP(ssid, password);
Jak widać jedna linia kodu powoduje, że dysponujemy sprawnym punktem dostępowym, do którego możemy się podłączyć. Docelowo nasze urządzenie będzie pracowało w trybie klienta, czyli będzie podłączone do naszej sieci domowej. Aktualne ustawienie układu ESP w trybie punktu dostępowego umożliwia łatwe testowanie pisanej aplikacji i zabezpiecza przed ewentualnymi problemami z funkcjonowaniem naszej sieci lokalnej.
Dysponując działającym punktem dostępowym możemy przejść do właściwej części zadania. Utworzymy prostą stronę internetową.
Pierwszym niezbędnym elementem będzie załączenie wymaganej biblioteki:
#include <ESP8266WebServer.h>
następnie powołujemy do życia obiekt serwera:
ESP8266WebServer server(80);
Od tego momentu możemy się odwoływać do nazwy "server" wykonując kolejne operacje na nowo powstałym serwerze WWW. W kolejnym kroku przypiszemy konkretne strony WWW do określonych akcji obsługiwanych przez nasz serwer.
void stronaGlowna(){
server.send(200, "text/html", "<h2>To jest strona główna</h2>");
}
server.on("/", stronaGlowna);
metoda on obiektu server umożliwia przypisanie odpowiednich akcji w zależności od zapytań użytkownika. Dowolnie możemy określić akcje, które mają zostać obsłużone przez nasz serwer www. Powyższy kod przygotowuje obsługę strony głównej naszego serwera. Wpisując w przeglądarce adres IP naszego układu otrzymamy Komunikat "To jest strona główna". Dodatkowo warto obsłużyć wywołania stron, których na naszym serwerze nie ma. Służy do tego metoda onNotFound . Poniższy kod umożliwi obsługę nieprawidłowych żądań wysyłanych przez użytkownika.
void handleNotFound() {
String message = "Brak strony na serwerze...";
server.send(404, "text/plain", message);
}
server.onNotFound(handleNotFound);
Pozostały tylko dwa kroki do uruchomienia naszej strony internetowej. Pierwszy z nich to "oficjalne uruchomienie serwera" za pomocą metody begin.
server.begin();
Ostatni element to oczekiwanie na połączenia od klientów. Zajmuje się tym metoda handleClient
server.handleClient();
Od tego momentu dysponujemy uruchomionym prostym serwerem HTTP, który potrafi przesłać do przeglądarki zawartość strony internetowej.
Po zebraniu wszystkiego w jedną całość otrzymujemy najprostszy możliwy kod serwera HTTP działającego w oparciu o układ ESP8266:
#include <ESP8266WebServer.h>
const char *ssid = "NAZWA_AP";
const char *password = "klucz";
ESP8266WebServer server(80);
void stronaGlowna(){
server.send(200, "text/html", "<h2>To jest strona główna</h2>");
}
void handleNotFound() {
String message = "Brak strony na serwerze...";
server.send(404, "text/plain", message);
}
void setup(){
WiFi.softAP(ssid, password);
server.on("/", stronaGlowna);
server.onNotFound(handleNotFound);
server.begin();
}
void loop(){
server.handleClient();
}
Z powyższego przykładu istotne jest, by metodę handleClient wywoływać cyklicznie w loop, natomiast metoda begin musi być ostatnią po metodach on.
Po przetestowaniu działania naszego serwera możemy przejść do elementów "bardziej skomplikowanych". Rozbudujemy nasz układ o możliwość sterowania wbudowaną diodą LED. Dla uproszczenia kodu zostanie to wykonane z wykorzystaniem dodatkowych stron serwera www. Wpisując adres: IP/On zapalimy diodę, wpisując IP/Off zgasimy diodę. W tym celu należy dopisać obsługę dwóch stron naszego serwera.
server.on("/On", handleOn);
server.on("/Off", handleOff);
Powyższe dwie linie musimy umieścić przed wywołaniem server.begin() w funkcji setup. Mamy już przekazaną informację, że nasz serwer potrafi obsłużyć kolejne dwie strony, ale nie mamy zdefiniowanego dla nich zachowania serwera. Musimy dopisać obsługę powyższych stron, czyli funkcje handleOn i handleOff.
void handleOn(){
pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
server.send(200, "text/html", "<h2>Dioda włączona :)</h2>");
}
void handleOff(){
pinMode(LED,OUTPUT);
digitalWrite(LED,HIGH);
server.send(200, "text/html", "<h2>Dioda wyłączona :)</h2>");
}
Kilka uwag do powyższego kodu. LED to zdefiniowany pin, do którego podłączona jest dioda LED. Różne układy ESP mają podłączoną wbudowaną diodę do różnych pinów. Funkcje handleOn i handleOff ustawiają pin diody jako wyjście. Bardziej elegancko byłoby, gdyby to ustawienie następowało w funkcji setup. Ostatni element to włączenie/wyłączenie diody. W przykładzie założyłem, że podanie zera na pinie spowoduje włączenie diody, a podanie logicznej jedynki spowoduje wyłączenie diody. jeżeli podłączymy diodę do masy, wtedy układ będzie pracował odwrotnie.
Dysponujemy możliwością przekazania poleceń do serwera. Dodam jeszcze możliwość odczytania stanu kontrolowanej diody. W tym celu dodamy obsługę nowej strony, którą nazwiemy status.
void handleStatus(){
if(digitalRead(LED))
server.send(200, "text/html", "<h2>Dioda włączona</h2>");
else
server.send(200, "text/html", "<h2>Dioda wyłączona</h2>");
}
Dysponując przygotowaną obsługą strony możemy dodać ją do serwera. Przed metodą begin wpisujemy
server.on("/status",handleStatus);
Podsumowanie
Kilka linijek kodu przekształca nasz układ ESP8266 w pełnowartościowy serwer HTTP. Wygląd stron prezentowanych przez nasz układ jest ograniczony wyłącznie ilością dostępnej pamięci w układzie oraz inwencją twórczą autora. W przypadku, gdybyśmy chcieli udostępniać bardziej skomplikowaną szatę graficzną niezbędne będzie podłączenie karty SD przechowującej zawartość naszej strony. Warto poruszyć w tym miejscu jedną ważną sprawę: Przedstawione rozwiązanie nie zapewnia bezpieczeństwa urządzenia. Każdy znający adres IP może sprawdzić status oraz sterować urządzeniem. W zastosowaniu rzeczywistym należy zadbać o wprowadzenie mechanizmów zabezpieczających nasze urządzenie przed niepowołanym dostępem. Pokazane powyżej możliwości serwera są bardzo skromne, nie można np. przekazać do serwera konkretnej wartości jakiegoś parametru. Opiszę to w kolejnym artykule.