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 handleOnhandleOff.

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 handleOnhandleOff 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.