Fyzikální kabinet FyzKAB

Wi-Fi přístup k modulu ESP32

Aktualizováno: 9. 7. 2024

Nový modul ESP32 (nástupce modulu ESP8266) se pomalu stává hvězdou mezi projekty souvisejícími s IoT. Jedná se o velmi efektivní modul z pohledu výkon/cena. Díky tomu, že obvod je osazen Wi-Fi, lze s trochou úsilí jej naprogramovat tak, aby vytvořil samostatný webový server, který můžeme využít pro řízení nebo měření. To není vůbec špatné!

LED server ESP32

Provozní režimy ESP32

Jednou ze skvělých funkcí, kterou ESP32 poskytuje, je to, že se nemusí připojovat pouze ke stávající síti Wi-Fi, ale může také vytvořit vlastní síť, která umožňuje připojení dalších zařízení přímo k ní. My si dále v článku ukážeme, jak modul ESP32 může pracovat ve dvou různých režimech: režim stanice a režim měkkého přístupového bodu (ale jak si ukážeme, může pracovat v obou režimech současně!).

Režim stanice (STA)

Jakékoliv zařízení, tedy i ESP32, které se připojuje ke stávající síti Wi-Fi (vytvořené vaším bezdrátovým domácím routerem), se nazývá Station (STA)

V režimu STA získává modul ESP32 svou IP adresu z bezdrátového routeru, ke kterému je připojen. S touto IP adresou můžeme nastavit webový server tak, aby doručovat webové stránky všem připojeným zařízením v rámci stávající Wi-Fi sítě.

Režim měkkého přístupového bodu (AP)

Zařízení (zde náš modul ESP32), které vytváří vlastní Wi-Fi síť a funguje jako rozbočovač (podobně jako Wi-Fi router) pro jednu nebo více stanic, se nazývá přístupový bod (AP). Jen na rozdíl od routeru Wi-Fi nemá rozhraní ke kabelové síti. Takový provozní režim se nazývá Soft Access Point (soft-AP). Maximální počet stanic, které se mohou k modulu ESP32 připojit, je omezen na pět!

V režimu AP vytvoří ESP32 novou Wi-Fi síť s nastaveným SSID (název sítě) a IP adresu. S touto IP adresou může doručovat webové stránky všem připojeným zařízením v rámci vlastní sítě.

Režim STA a AP současně

Zajímavou „vychytávkou“ modulu ESP32 je možnost pracovat s režimy STA (Station) a soft-AP (Soft Access Point) současně. To znamená, že modul ESP32 je připojen ke klasickému Wi-Fi routeru (režim STA), ale zároveň má aktivovaným Wi-Fi přístupovým bodem (režim AP). Tento režim se nazývá WIFI_AP_STA.

Lze tedy napsat v prostředí Arduino IDE kód, který kombinuje jak správu režimu STATION, tak režim AP. To může sloužit kupříkladu jako takový „akční“ hotspot, ke kterému jsou připojena Wi-Fi čidla (např. několik teploměrů, vlhoměry apod.) jako k AP, uživatel se prostřednictvím internetu a wi-fi, ke které je modul ESP32 připojen jako STA, dotazuje na stav čidel. Odpovědí mu pak je například webová stránka s údaji ze všech bezdrátových čidel. Následující obrázek ukazuje tento případ.

uziti ESP32 v režimu STA+AP

Jelikož si nadále v článku ukážeme oba režimi (jak STA, tak AP) jednotlivě a podrobněji, nebudeme se zde smíšeným režimem příliš zabývat, neboť je jen kombinací obou dále posaných. Nyní si zde jen ukážeme ukázkový kód, který nám umožní mít oba dva režimy současně. Kód je popsán v komentářích, vysvětlení je dále v rámci ostavců STA a AP.

#include <WiFi.h>

/* Udaje pro STA */
const char *wifi_network_ssid = "Tady-ma-byt-jmeno-site-pro-STA";    //Sem zadejte jmeno Wi-Fi, kam se ESP32 prihlasi jako STA
const char *wifi_network_password = "heslo-pro-pristup-k-Wi-Fi";     //Sem zadejte heslo k Wi-Fi pro STA

/* Udaje pro AP */
const char *soft_ap_ssid = "Nazev-AP";     //Timto jmenem se bude Wi-Fi modulu ESP32 zobrazovat
const char *soft_ap_password = "heslo-pro-AP";     //Pomoci tohoto hesla se cidla pripoji k ESP32
// const char *soft_ap_password = NULL;     //kdyz nechci mit zadne heslo k AP

void setup() {
   Serial.begin(115200);     //nastaveni serial vystupu
   WiFi.mode(WIFI_AP_STA);   //nastaveni smiseneho modu AP+STA

   //nejdrive se vytvari AP
   Serial.println("Vytvarim ESP32 AP");
   WiFi.softAP(soft_ap_ssid, soft_ap_password);     //nastaveni modu AP
   Serial.print("AP je vytvoren s IP adresou ");
   Serial.println(WiFi.softAPIP());     //vypis IP adresy pro AP

   //pripojeni k existujici Wi-Fi (rezim STA)
   WiFi.begin(wifi_network_ssid, wifi_network_password);    //spusteni STA rezimu a zacatek pokusu o prihlaseni
   Serial.println("\nPripojuji se do WiFi site ");
   while( WiFi.status() != WL_CONNECTED ) {    //testuje se, zda jiz doslo k pripojeni k Wi-Fi
     Serial.print(".");
     delay(100);
   }
   //Pripojeni k Wi-Fi se podarilo
   Serial.print("\nPripojeno k WiFi siti, ESP32 ma lokalni IP: ");
   Serial.println( WiFi.localIP() );     //vypis IP adresy pro STA
}

void loop() {}

Po kompilaci a spuštění kódu v modulu ESP32 bychom úspěšné spuštění módu STA+AP měli poznat ve výstupním okně sériového monitoru prostředí Arduino IDE následujícími hláškami.

ESP32 v režimu STA+AP - vystup v Serial Monitor
Poznámka:
V modulu ESP32 existuje pro každý režim samostatné síťové rozhraní. Protože jsou rozhraní nezávislá, má pak každé jinou IP adresu.
ESP32 mode STA+AP

Pochopitelně by se měla v okolí objevit nová Wi-Fi síť generovaná modulem ESP32 – tomto případě s názvem Nazev-AP a přístupovým heslem heslo-pro-AP. Tím jsme současně vytvořili v modulu ESP32 režim STA a AP. Je na samotném vývojáři, jak dále bude s touto možností nakládat a jaký program pro svůj projekt vytvoří.


ALE pojďme na to raději pomalu a postupně!

Zkusíme si použití Wi-Fi u modulu ESP32 ukázat na nějakém jednoduchém „praktickém“ příkladu.
Asi každý očekává, že budeme vzdáleně přes Wi-Fi síť blikat LED 😀.

Tak pojďme na to!

Začneme zapojením, kdy k modulu ESP32 připojíme mezi zemnící pin GND a GIPIO pin 4 standardní červenou LED přes rezistor o odporu 100 Ω (viz schéma):

ESP32 LED server - schema

ESP32 jako HTTP server využívající režim Wi-Fi Station (STA)

Jako první příklad si ukážeme, jak nastavit ESP32 do režimu Station (STA) a zasílat webové stránky libovolnému připojenému klientovi v rámci stávající Wi-Fi sítě.

Náš program (píšeme jej v prostředí Arduino IDE) musí začít přidáním knihovny WiFi.h. Tato knihovna poskytuje metody Wi-Fi specifické pro modul ESP32, které potřebujeme volat pro připojení k síti. Poté též přidáme knihovnu WebServer.h, která nám přidá některé metody, které nám pomohou nastavit server a zpracovávat příchozí požadavky HTTP, aniž bychom se museli starat o podrobnosti implementace na nízké úrovni.

#include <WiFi.h>
#include <WebServer.h>

Když nastavujeme modul ESP32 v režimu STA musíme nastavit SSID (jméno sítě) a heslo sítě. Jméno Wi-Fi sítě, ke které se chceme připojit a platné heslo při přihlášení vepíšeme do hodnoty proměnných ssid a password:

/*Put your SSID & Password*/
const char *ssid = "Tady-ma-byt-jmeno-site";     //Enter SSID here
const char *password = "Sem-je-treba-napsat-heslo";     //Enter Password here

Dále deklarujeme objekt knihovny WebServer, abychom měli přístup k jejím funkcím. Konstruktor tohoto objektu má jako vstupní parametr hodnotu port, což je číslo portu, kde bude server naslouchat. Protože je výchozí hodnota portu pro http obvykle hodnota 80, použijeme tuto hodnotu. Díky tomu můžete přistupovat k serveru, aniž byste museli zadávat port v adrese URL.

//declare an object of WebServer library
WebServer server(80);

Dále musíme deklarovat vše potřebné pro náš projekt, kupříkladu GPIO pin modulu ESP32, ke kterému například připojíme přes patřičný rezistor LED diodu, aby náš ovládací server mohl něco ovládat. Deklarujeme tedy GPIO pin a počáteční stav připojené LED diody.

uint8_t LEDpin = 4;
bool LEDstatus = false;

Funkce uvnitř procedury Setup()

Náš měřící server se musí před jeho skutečným spuštěním ještě nakonfigurovat. K tomu slouží procedura Setup(), která se spouští jen jednou po startu modulu. V této proceduře nejdříve otevřeme sériové připojení pro účely ladění a nastavíme port GPIO na VÝSTUP.

Serial.begin(115200);
pinMode(LEDpin, OUTPUT);

Nyní již nezbývá, než se připojit k Wi-Fi síti. Zde však neodpustím jednu drobnou „vychytávku“. Jde o nastavení jména zařízení v síti. Podíváme-li se v nastavení Wi-Fi routeru nebo HotSpotu na seznam připojených zařízení, budou se nám všechny připojené moduly ESP32 identifikovat jako „espressif“ (některé typy modulů ESP32 se identifikují jako „esp32-arduino“). Pokud bychom do jedné Wi-Fi sítě připojovali více modulů ESP32, bylo by dobré je nějak rozlišit. K tomu nám poslouží funkce WiFi.setHostname(). Je třeba jen zdůraznit, že funkce WiFi.setHostname(), jejímž parametrem je naše pojmenování modulu, musí být v kódu zařazena PŘED funkcí pro připojení (WiFi.begin).

Připojení k Wi-Fi síti provedeme pomocí funkce WiFi.begin(). Síťové pojmenování zvolíme „trochu netradiční“, ale aspoň náš modul v síti dobře najdeme 😉.

//connect to your local wi-fi network
WiFi.setHostname("AHOJ Babicko");
WiFi.begin(ssid, password);

Po nastavení různých názvů modulů ESP32 pro identifikaci v síti můžeme situace v seznamu připojených zařízení vypadat kupříkladu takto:

Nastaveni hotspot

Zatímco se ESP32 pokouší připojit k síti, můžeme stav připojení zkontrolovat pomocí funkce WiFi.status().

//check wi-fi is connected to wi-fi network
while(WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
}

Jen pro informaci, tato funkce vrací následující stavy:

  • WL_CONNECTED: vráceno při připojení k síti Wi-Fi
  • WL_NO_SHIELD: vráceno, pokud není k dispozici žádný shield/modul Wi-Fi
  • WL_IDLE_STATUS: dočasný stav přiřazený při volání WiFi.begin() a zůstává aktivní, dokud nedojde k připojení, nebo nevyprší počet pokusů
  • WL_NO_SSID_AVAIL: vráceno, když není k dispozici zadaná SSID
  • WL_SCAN_COMPLETED: vráceno po dokončení skenování sítí
  • WL_CONNECT_FAILED: vráceno, když připojení selže přes všechny pokusy
  • WL_CONNECTION_LOST: vráceno při ztrátě připojení
  • WL_DISCONNECTED: vráceno při odpojení od sítě

Jakmile se modul ESP32 připojí k síti, vytiskneme na Serial Monitor IP adresu modulu pomocí funkce WiFi.localIP().

Serial.println("Wi-Fi connected!");
Serial.print("Got IP: ");
Serial.println(WiFi.localIP());

Abychom mohli zpracovávat příchozí požadavky HTTP, musíme určit, který kód se má spustit, když je zaslán dotaz na konkrétní URL adresu. K tomu použijeme metodu server.on, která má dva parametry. První z nich je zaslaná URL a druhá je název funkce, kterou při tomto dorazu provést. Uvedená adresa URL je relativní cesta.

Například první řádek níže uvedeného fragmentu kódu ukazuje, že když server obdrží požadavek HTTP na cestu root ( / ), spustí proceduru handle_OnConnect().

server.on("/", handle_OnConnect);
server.on("/ledon", handle_ledon);
server.on("/ledoff", handle_ledoff);

Vidíme, že jsme přiřadili URL adrese /ledon proceduru pro rozsvícení LED (handle_ledon) a adrese /ledoff proceduru pro zhasnutí (handle_ledoff).

Po správný běh serveru bychom měli specifikovat, co by měl server dělat, pokud klient požaduje jinou adresu URL, než je uvedeno pomocí server.on(). Potřebujeme, aby server odpověděl stavem HTTP 404 (Nenalezeno) a zprávou pro uživatele. To učiníme pomocí funkce server.onNotFound(), kde určíme, co by se mělo v takovou chvíli spustit (zde procedura handle_NotFound):

server.onNotFound(handle_NotFound);

Máme-li vše připravené, můžeme spustit náš server.

server.begin();
Serial.println("HTTP server started");

Funkce uvnitř procedury Loop()

Abychom zvládli obsloužit skutečné příchozí požadavky HTTP, musíme cyklicky volat proceduru handleClient() objektu serveru. Podle požadavku také budeme měnit stav LED.

void loop() {
    server.handleClient();
    if(LEDstatus) {
        digitalWrite(LEDpin, HIGH);
    } else {
        digitalWrite(LEDpin, LOW);
    }
}

Tím máme funkci Loop() vyřízenou. Dále musíme vytvořit funkci, kterou jsme připojili k URL adrese root ( / ) pomocí server.on. Vzpomínáte si? Na začátku této funkce nastavíme stav LED na LOW (počáteční stav LED). Abychom mohli reagovat na požadavek HTTP, používáme pro odpověď metodu server.send. Přestože tuto metodu lze volat s různou sadou argumentů, její nejjednodušší forma se skládá se tří argumentů: z kódu odpovědi HTTP, typu obsahu a samotného obsahu.

V našem případě tedy posíláme kód 200, což je jeden ze stavových kódů HTTP, který odpovídá odpovědi OK. Poté nastavujeme typ obsahu jako text/html a nakonec jako třetí parametr voláme funkci SendHTML(), která nám vytvoří dynamickou stránku HTML obsahující stav LED diody.

void handle_OnConnect() {
    LEDstatus = false;
    Serial.println("Request for the home page");
    server.send(200, "text/html", SendHTML(LEDstatus));
}

Stejně tak musíme vytvořit funkce pro zpracování požadavků na zapnutí/vypnutí LED a chybovou stránku 404.

void handle_ledon() {
    LEDstatus = true;
    Serial.println("GPIO4 Status: ON");
    server.send(200, "text/html", SendHTML(true));
}

void handle_ledoff() {
    LEDstatus = false;
    Serial.println("GPIO4 Status: OFF");
    server.send(200, "text/html", SendHTML(false));
}

void handle_NotFound() {
    server.send(404, "text/plain", "Not found");
}

Zobrazení webové stránky HTML

Funkce SendHTML() je určená pro generování webové stránky, kterou zobrazí server ESP32, kdykoli obdrží požadavek od webového klienta. Tato funkce vytvoří kód HTML jako textový řetězec, který vrátí funkci server.send() (viz dříve). Funkce SendHTML() přebírá stav LED diody jako parametr pro dynamické generování obsahu HTML.

První text, který byste měli při odesílání HTML stránky vždy odeslat, je deklarace <! DOCTYPE>, která označuje, že odesíláme kód HTML.

String SendHTML(uint8_t ledstat) {
    String ptr = "<!DOCTYPE html>\n<html>\n";

Další prvek <meta> činí webovou stránku responzivní v libovolném webovém prohlížeči. Dále pak značka <title> nastavuje název stránky.

    ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
    ptr += "<title>LED Control</title>\n";

Aby naše webová stránka vypadala „trochu k světu“, přidáme i nějaké to CSS pro stylování vzhledu webové stránky. Vybereme písmo „monospace“, definujeme obsah, který má být zobrazen jako vložený blok a zarovnán uprostřed.

    ptr += "<style>\n html { font-family: monospace; display: inline-block; margin: 0px auto; text-align: center;}\n";

Následující kód pak nastaví barvu, písmo a okraj kolem textu, HTML značek H1, H3 a p.

    ptr += "body {margin-top: 50px;} h1 {color: #444;margin: 50px auto 30px;} h3 {color: #444;margin-bottom: 50px;}\n";
    ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";

Na tlačítko se aplikuje také určitý styl s vlastnostmi, jako je barva, velikost, okraj atd. Tlačítko ZAPNOUT a VYPNOUT má jinou barvu pozadí, zatímco vlastnost „action“ zajišťuje efekt kliknutí na tlačítko.

    ptr += ".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
    ptr += ".button-on {background-color: #3498db;}\n";
    ptr += ".button-on:active {background-color: #2980b9;}\n";
    ptr += ".button-off {background-color: #34495e;}\n";
    ptr += ".button-off:active {background-color: #2c3e50;}\n";
    ptr += "p {font-size: 14px; color: #888; margin-bottom: 10px;}\n";
    ptr += "</style>\n";

Po nastavení CSS stylu můžeme uzavřít hlavičku HTML dokumentu a v části BODY je nastaven zobrazovaný obsah webové stránky.

    ptr += "</head>\n";
    ptr += "<body>\n";
    ptr += "<h1>ESP32 Web Server</h1>\n";
    ptr += "<h3>Using Station(STA) Mode</h3>\n";

K dynamickému generování tlačítek a stavu LED používáme příkaz if. V závislosti na stavu GPIO pinu se tedy zobrazí tlačítko ON/OFF.

    if (ledstat) {
        ptr += "<p>LED Status: ON</p><a class=\"button button-off\" href=\"/ledoff\">OFF</a>\n";
    } else {
        ptr += "<p>LED Status: OFF</p><a class=\"button button-on\" href=\"/ledon\">ON</a>\n";
    }

Nyní si zde uvedeme kód celý, stačí jej zkopírovat do Arduino IDE a nahrát do modulu ESP32:

Kód (mód STA):

#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "Tady-ma-byt-jmeno-site"; // Enter SSID here
const char* password = "Sem-je-treba-napsat-heslo"; //Enter Password here

WebServer server(80);

uint8_t LEDpin = 4;
bool LEDstatus = LOW;

void setup() {
  Serial.begin(115200);
  delay(100);
  pinMode(LEDpin, OUTPUT);
  Serial.println("Connecting to ");
  Serial.println(ssid);

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Wi-Fi connected!");
  Serial.print("Got IP: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.on("/ledon", handle_ledon);
  server.on("/ledoff", handle_ledoff);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
  if(LEDstatus) {
    digitalWrite(LEDpin, HIGH);
  } else {
  digitalWrite(LEDpin, LOW);
  }
}

void handle_OnConnect() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(LEDstatus));
}

void handle_ledon() {
  LEDstatus = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true));
}

void handle_ledoff() {
  LEDstatus = LOW;
  Serial.println("GPIO4 Status: OFF");
  server.send(200, "text/html", SendHTML(false));
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t ledstat) {
  String ptr = "<!DOCTYPE html>\n<html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>\nhtml {font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444;margin: 50px auto 30px;} h3 {color: #444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;";
  ptr +="text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #3498db;}\n";
  ptr +=".button-on:active {background-color: #2980b9;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP32 Web Server</h1>\n";
  ptr +="<h3>Using Station(STA) Mode</h3>\n";

  if(ledstat) {
    ptr +="<p>LED Status: ON</p><a class=\"button button-off\" href=\"/ledoff\">OFF</a>\n";
  } else {
    ptr +="<p>LED Status: OFF</p><a class=\"button button-on\" href=\"/ledon\">ON</a>\n";
  }

  ptr +="</body>\n";
  ptr +="</html>\n";

  return ptr;
}

Po nahrání programu otevřete Sériový monitor s přenosovou rychlostí 115200 a stiskněte na modulu ESP32 tlačítko RESET. Pokud je vše v pořádku, modul se přihlásí do Wi-Fi sítě a získá z vašeho Wi-Fi routeru dynamickou IP adresu, kterou zobrazí společně se zprávou: HTTP server started.

Poté otevřete internetový prohlížeč na zařízení (PC, tablet, mobil) připojeném na téže Wi-Fi. Do adresního řádku zadejte IP adresu modulu ESP32. Měla by se načíst webová stránka, která ovládá a zobrazuje aktuální stav LED.

ESP32 - STA

Jakmile kliknete na tlačítko ON modul ESP32 obdrží požadavek /ledon. Tím zapne LED a zobrazí webovou stránku s aktualizovaným stavem LED.


ESP32 jako HTTP server v režimu Wi-Fi Access Point (AP)

Jak naznačuje nadpis, tento příklad ukazuje, jak z modulu ESP32 udělat přístupový bod (AP) a odesílat webové stránky libovolnému připojenému klientovi. Nebude tedy třeba se přihlašovat k existující Wi-Fi, ale modul ESP32 si vytvoří Wi-Fi svojí.

Program je obdobný předešlému, jediný rozdíl je v nastavení Wi-Fi. Začínáme tedy stejně, tedy knihovnami WiFi.h a WebServer.h.

Podobně předešlému, i když nastavujeme ESP32 v režimu přístupového bodu (AP), musíme nastavit SSID, heslo. Zde nejde o jméno a heslo sítě, do které se potřebujeme modulem ESP32 přihlásit, ale název a heslo sítě, kterou modul vytvoří. Tyto údaje budou muset znát zařízení, které se budou moci připojit do sítě modulu ESP32. Na rozdíl od předešlého příkladu, kde byl modul ESP32 v režimu STA, tedy byla IP přiřazena dynamicky, zde nastavíme IP adresu, masku podsítě IP a bránu IP napevno.

/* Put your SSID & Password */
const char* ssid = "Sit modulu ESP32";    // Enter SSID here
const char* password = "12345678";    //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

Další změna programu se odehrává až v proceduře Setup(), kde nastavíme měkký přístupový bod pro vytvoření sítě Wi-Fi. To provedeme za pomoci deklarovaných proměnných SSID, hesla, IP adresy, masky podsítě IP a brány IP.

WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
delay(100);

Tím máme hotovo!

Další část programu je totožná s předchozím příkladem. Můžeme se tedy podívat na celý kód:

Kód (mód AP):

#include <WiFi.h>
#include <WebServer.h>

/* Put your SSID & Password */
const char* ssid = "Sit modulu ESP32"; // Enter SSID here
const char* password = "12345678"; //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

WebServer server(80);

uint8_t LEDpin = 4;
bool LEDstatus = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(LEDpin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);

  server.on("/", handle_OnConnect);
  server.on("/ledon", handle_ledon);
  server.on("/ledoff", handle_ledoff);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
  if(LEDstatus) {
    digitalWrite(LEDpin, HIGH);
  } else {
    digitalWrite(LEDpin, LOW);
  }
}

void handle_OnConnect() {
  LEDstatus = LOW;
  server.send(200, "text/html", SendHTML(LEDstatus));
}

void handle_ledon() {
  LEDstatus = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true));
}

void handle_ledoff() {
  LEDstatus = LOW;
  Serial.println("GPIO4 Status: OFF");
  server.send(200, "text/html", SendHTML(false));
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t ledstat){
  String ptr = "<!DOCTYPE html>\n<html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>\nhtml {font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body {margin-top: 50px;} h1 {color: #444;margin: 50px auto 30px;} h3 {color: #444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;";
  ptr +="text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #3498db;}\n";
  ptr +=".button-on:active {background-color: #2980b9;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP32 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";

  if(ledstat) {
    ptr +="<p>LED Status: ON</p><a class=\"button button-off\" href=\"/ledoff\">OFF</a>\n";
  } else {
    ptr +="<p>LED Status: OFF</p><a class=\"button button-on\" href=\"/ledon\">ON</a>\n";
  }

  ptr +="</body>\n";
  ptr +="</html>\n";

  return ptr;
}

Přístup na webový server v režimu AP

Po nahrání programu zprvu postupujte jako v předešlém případě, tedy: otevřete Sériový monitor s přenosovou rychlostí 115200 a stiskněte tlačítko RESET na modulu ESP32. Pokud je vše v pořádku, zobrazí se zpráva HTTP server started.

Dále vezměte jakékoli zařízení, které se můžete připojit k síti Wi-Fi (mobil, tablet, PC atd.). Vyhledejte síť s názvem „Sit modulu ESP32“ a připojte se heslem 12345678.

pripojeni tabletu k AP

Po připojení k síti „Sit modulu ESP32“ spusťte na svém zařízení internetový prohlížeč a odkažte na adresu modulu ESP32, tedy na 192.168.1.1. Modul ESP32 by měl zobrazit webovou stránku pro ovládání LED diody.

ESP32 - mode AP

Postup ovládání je již stejný – kliknutím na tlačítko ON obdrží modul ESP32 požadavek /ledon, poté zapne LED a zobrazí webovou stránku s aktualizovaným stavem LED.

Poznámka na konec

  • V případě režimu AP jsme si jistě všimli pevného nastavení IP adresy, které má svůj význam. Pevné nastavení IP je však možné i v případě STA. V naší výše uvedené ukázce režimu STA byla IP adresa přiřazena dynamicky, ale někdy (kupříkladu kvůli požadavku správce sítě) je třeba i v případě STA nastavit IP adresu napevno.

    Kód pak bude vypadat následovně (čísla IP adres se mohou lišit dle požadavků Vašeho správce sítě):
/* NASTAVENI PEVNE IP ADRESY (deklarace) */
IPAddress local_ip(192, 168, 1, 123); //staticka IP addresa
IPAddress gateway(192, 168, 1, 1); //IP brany
IPAddress subnet(255, 255, 255, 0); //maska podsite
IPAddress primaryDNS(192, 168 , 1, 1); //primarni DNS
IPAddress secondaryDNS(8, 8, 8, 8); //sekundarni DNS
    :
    :
void setup() {
         :

    /* NASTAVENI PEVNE IP ADRESY (procedura SETUP) */
    if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
        Serial.println("STA Failed to configure");
    }
          :
        //connect to your local wi-fi network
        WiFi.begin(ssid, password);
          :
}

Skener dostupných Wi-Fi sítí

Jako poslední příklad pro otestování Wi-Fi funkce modulu ESP32 si zde uvedeme ukázkový kód pro skenování Wi-Fi sítí v okolí.

/* ESP32 - skenovani WiFi siti v okoli */

// pripojeni potrebne knihovny
#include <WiFi.h>

void setup() {
  Serial.begin(115200);   // nastaveni komunikace po seriove lince
  WiFi.mode(WIFI_STA);   // nastavena Wi-Fi do modu STA pro skenovani
  WiFi.disconnect();   // odpojeni od siti pro povoleni skenovani
  delay(100);
}

void loop() {
  Serial.println("scan start");   // zahajeni skenovani
  int n = WiFi.scanNetworks();   // nacteni poctu viditelnych siti
  Serial.println("scan done");

  if (n == 0) {   // pokud nebyly nacteny zadne site, vypis informaci
    Serial.println("Zadna sit nebyla nalezena.");
  } else {   // v opacnem pripade vypis dostupne informace
    Serial.print(n);
    Serial.println(" siti nalezeno.");
    for (int i = 0; i < n; i++) {
      // postupne vytiskni nazev (SSID) a silu signalu (RSSI)
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
      delay(10);
    }
  }
  Serial.println("");

  delay(5000);   // 5s pauza pred novym skenovanim
}

Po spuštětní kódu se bude v pěti vteřinových intervalech načítat seznam dostupných Wi-Fi sítí a vypisovat do okna sériového monitoru – viz následující obrázek.

wifi skener

Závěrem

Tento článek měl za úkol představit dvě základní možnosti vzdáleného řízení modulu ESP32 pomocí Wi-Fi sítě. Pochopitelně výše uvedené kódy nejsou dogma a lze je jakkoliv modifikovat podle potřeby pro konkrétní projekt. Snad v některém z dalších článků se pustíme do nějaké konkrétní a „užitečné“ aplikace. Myslím, že modul ESP32 včetně mnoha svých modifikací si naši pozornost ještě zaslouží.

Modul ESP32 začíná být na internetu poměrně dobře dokumentován a objevuje se řada příkladů a tipů na různé aplikace. Bohužel zatím jde většinou jen v anglické webové stránky, tak snad tento článek aspoň trochu pomohl rozšířit tu publikační českou minoritu.

Autor článku: Miroslav Panoš
POZNÁMKA:
Článek vychází z následujících anglických textů:
UPOZORNĚNÍ:
Nesouhlasíme s vyřazením Newtonových zákonů, Ohmova zákona a zákona zachování energie z učiva fyziky základních škol v České republice!