Wi-Fi přístup k modulu ESP32
Modul ESP32 se stává hvězdou mezi projekty souvisejícími s IoT, neboť se jedná o velmi efektivní modul z pohledu poměru výkon/cena. Díky integrované Wi-Fi jej lze naprogramovat tak, aby vytvořil samostatný webový server nebo vystupoval jako aktivní klient. To není vůbec špatné!
Role v síti: Klient vs. Server
Než se pustíme do samotného zapojování a kódu, je důležité si ujasnit, v jaké roli může ESP32 v síťové komunikaci vystupovat. V architektuře klient-server je zásadní pochopit roli, kterou zařízení v danou chvíli zaujímá:
- Klient je zařízení nebo aplikace (typicky třeba webový prohlížeč v mobilu nebo počítači), která iniciuje komunikaci a odesílá požadavky. Typicky může ESP32 stahovat data o počasí nebo odesílat hodnoty ze senzorů do cloudu. Tomuto tématu se podrobně věnujeme v jiném článku – viz ESP32 jako Wi-Fi webový klient.
- Server naopak naslouchá a čeká na příchozí požadavky, na které následně reaguje – např. odesláním webové stránky nebo splněním příkazu k rozsvícení LED – to je popsáno v článku: ESP32 jako jednoduchý server.
Komunikace probíhá ve čtyřech krocích:
- klient odešle HTTP požadavek,
- server jej zpracuje,
- server vrátí HTTP odpověď,
- klient ji přečte.
V tomto úvodním článku se ale nebudeme zabývat vzájemnou síťovou komunikací modulu ESP32, ale podíváme se na to základní, a to, jak lze modul ESP32 vůbec k nějaké Wi-Fi síti připojit. Je asi jasné, že bez samotného připojení nemá vůbec cenu se zabývat jakoukoliv síťovou komunikací modulu. Případy použití modulu ESP32 jako serveru, či jako klienta se zabývají výše zmíněné články:
Provozní režimy modulu ESP32
Modul ESP32 nabízí několik provozních režimů, které definují jeho chování v bezdrátové síti. Pojďme si je postupně probrat.
Připojení ESP32 k Wi-Fi – režim STANICE (STA)
Režim stanice (STA): ESP32 se připojuje k existující Wi-Fi síti vytvořené routerem. V tomto režimu získává modul svou IP adresu od routeru a může komunikovat se zařízeními v lokální síti i v internetu.
Než začneme programovat modul ESP32 tak, aby komunikoval s webovými službami, odesílal HTTP požadavky typu GET nebo POST nebo vytvářel svou vlastní Wi-Fi síť a tak se stával přístupovým bodem pro jiné klienty, musíme jej nejprve připojit k Wi-Fi síti. Ta nám pak bude sloužit jako prostředník mezi modulem ESP32 a internetem.
Prakticky každý z následujících kódů věnovaných problematice Wi-Fi bude začínat stejnou úvodní sekvencí programu, která zajistí připojení k bezdrátové síti. Jak celý proces připojení ESP32 k Wi-Fi funguje, si nyní vysvětlíme.
Nyní budeme modul využívat v režimu stanice (Station Mode, STA), kdy se chová jako běžný klient bezdrátové sítě a připojuje se k existujícímu Wi-Fi přístupovému bodu (AP, routeru). Po úspěšném připojení získá od sítě IP adresu a může komunikovat s ostatními zařízeními v lokální síti i se servery na internetu.
Následující kód poměrně jednoduchým a přímočarým způsobem připojí modul ESP32 k Wi-Fi síti, jejíž název a heslo jsou nastaveny v konstantách ssid a password.
#include <WiFi.h>
// Nastaveni Wi-Fi
const char* ssid = "nazev wi-fi site"; // Sem zadejte jmeno Wi-Fi, kam se ESP32 prihlasi
const char* password = "heslo wi-fi site"; // Sem zadejte heslo k Wi-Fi
void setup(){
Serial.begin(115200);
delay(1000);
Serial.print("Pripojuji k SSID: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA); // nastaveni modu STA
WiFi.begin(ssid, password); //pripojeni k existujici Wi-Fi (rezim STA)
uint32_t startTime = millis();
const uint32_t timeout = 10000;
while (WiFi.status() != WL_CONNECTED) { // testuje se, zda jiz doslo k pripojeni k Wi-Fi
Serial.print(".");
delay(500);
if (millis() - startTime > timeout) { // nestihl se pripojit
Serial.println();
Serial.println("Timeout pripojeni.");
while(true); // neuspech konci nekonecnou smyckou
}
}
Serial.println();
Serial.println("Wi-Fi pripojena.");
Serial.print("IP adresa: ");
Serial.println(WiFi.localIP());
// dalsi kod programu
Serial.println("Zde bude dalsi kod programu.");
}
void loop(){
}
Po kompilaci a spuštění kódu v modulu ESP32 bychom měli úspěšné připojení k domácí Wi-Fi síti poznat ve výstupním okně sériového monitoru prostředí Arduino IDE – tuto skutečnost ukazuje obrázek č. 1.
connectWiFi()Pojďme se podívat na důležitá místa programu.
Program (vytváříme 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.
#include <WiFi.h>
Když nastavujeme modul ESP32 v režimu STA, musíme nastavit SSID (jméno sítě) a heslo sítě, ke které se připojujeme. Tyto údaje vepíšeme do hodnoty proměnných ssid a password:
const char *ssid = "nazev wi-fi site";
const char *password = "heslo wi-fi site";
Následuje nastavení modulu ESP32 do režimu stanice (STA). To provedeme zavoláním metody mode() objektu WiFi s vestavěnou konstantou WIFI_STA. Mimochodem, všimněte si, že jsme níže uvedený objekt WiFi nikde nedeklarovali, to se provedlo samo pouhým připojením knihovny WiFi.
V některých tutoriálech se toto nastavení neprovádí, neboť se vychází z předpokladu, že modul ESP32 je ve výchozím nastavení nastaven v režimu STA, což se pak ještě potvrdí samotným připojením k existující Wi-Fi síti. Asi je to možné… Na druhou stranu správné nastavení/potvrzení režimu STA je otázka jednoho příkazu, což nám kód moc výrazně neprodlouží – a jistota je jistota!
WiFi.mode(WIFI_STA);
Nyní již nezbývá, než se konečně připojit k Wi-Fi síti. To provedeme metodou begin(), která má jako vstupní parametry údaje o síti, do které se chceme připojit.
WiFi.begin(ssid, password);
Od tohoto okamžiku se modul ESP32 pokouší připojit. Nastavení vzájemného propojení se sítí a ověření vstupních údajů nějaký čas trvá, je tedy dobré na tuto dobu kupříkladu do sériového monitoru prostředí Arduino IDE vykreslovat tečky.
Aktuální stav připojování, případný úspěch či neúspěch připojení nám určuje metoda status(). V průběhu čekací smyčky na připojení tuto metodu testujeme. Čekáme na úspěšné připojení, což odpovídá hodnotě konstanty WL_.
Jen pro informaci zde uvádíme i možnosti jiných návratových stavů:
- WL_
CONNECTED : vráceno při připojení k síti Wi-Fi - WL_
NO_ : vráceno, pokud není k dispozici žádný shield/modul Wi-FiSHIELD - WL_
IDLE_ : dočasný stav přiřazený při voláníSTATUS WiFi.begin()a zůstává aktivní, dokud nedojde k připojení, nebo nevyprší počet pokusů - WL_NO_
SSID_ : vráceno, když není k dispozici zadané SSIDAVAIL - WL_
SCAN_ : vráceno po dokončení skenování sítíCOMPLETED - WL_
CONNECT_ : vráceno, když připojení selže přes všechny pokusyFAILED - WL_
CONNECTION_ : vráceno při ztrátě připojeníLOST - 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í metody localIP().
Serial.println(WiFi.localIP());
Máme hotovo! Náš modul ESP32 se právě připojil do zvolené Wi-Fi sítě
Zde však neodpustíme 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“ (nebo některé typy modulů ESP32 se identifikují jako „esp32-arduino“). Pokud bychom do jedné Wi-Fi sítě připojovali více modulů ESP32, budou mít všechny stejný název. Asi by bylo dobré je nějak rozlišit. K tomu nám poslouží metoda setHostname, jejímž parametrem je naše pojmenování modulu.
WiFi.setHostname("jmeno modulu");
Je třeba jen zdůraznit, že tato funkce musí být v kódu zařazena PŘED zahájením připojení (tedy před WiFi.).
Pojďme si to názorně ukázat. Na notebooku vytvoříme mobilní hotspot a k němu připojíme dva moduly ESP32. Jeden ponecháme s výchozím pojmenováním, druhému název změníme pomocí metody setHostname(). Toto síťové pojmenování zvolíme „trochu netradiční“, ať náš modul v síti dobře najdeme 😉.
WiFi.setHostname("AHOJ Babicko");
WiFi.begin(ssid, password);
Po zobrazení všech zařízení připojených k dané síti může situace v seznamu připojených zařízení vypadat kupříkladu takto:
Vytvoření vlastního modulu pro připojení k Wi-Fi
Jak jsme už řekli, ve všech ukázkách budeme dále potřebovat řešit připojení k Wi-Fi síti, a příslušný kód bychom proto museli do každého programu znovu a znovu kopírovat. Jeho přítomnost by nejen zbytečně prodlužovala kód, ale především zastiňovala to hlavní, co bychom si chtěli v programu ukázat. Proto si nyní ukážeme, jak tento opakovaně používaný kód přesunout do vlastního modulu tvořeného soubory WI-FI-moje.h a WI-FI-moje.cpp. Vlastně si vytvoříme takovou svou vlastní knihovnu, i když to úplně plnohodnotná knihovna nebude – budeme tomu spíše říkat „modul“. V tomto modulu si vytvoříme funkci connectWiFi(), která nám bude vracet logickou hodnotu, která nám bude říkat, zda připojení k Wi-Fi proběhlo (ne)úspěšně.
Hlavní program se tím výrazně zkrátí a současně si tím i osvojíme jeden ze základních principů tvorby větších projektů v jazyce C++ – rozdělení programu do samostatných, znovu použitelných částí.
Po dále popsaném přesunutí „připojovací části“ do funkce connectWiFi() a připojení našeho modulu nazvaného WI-FI-moje, bude hlavní program vypadat jen takto:
#include <WiFi.h>
#include "WI-FI-moje.h"
const char* ssid = "nazev wi-fi site";
const char* password = "heslo wi-fi site";
void setup(){
Serial.begin(115200);
if (!connectWiFi(ssid, password)) {
while (true); // neuspech konci nekonecnou smyckou
}
// dalsi kod programu
Serial.println("Zde bude dalsi kod programu.");
}
void loop(){
}
Jak jsme řekli, veškerý kód související s připojením k Wi-Fi síti musíme přesunout do vlastního modulu WI-FI-moje. Název jsme zvolili schválně „trochu svérázný“, aby bylo na první pohled zřejmé, že jde o náš vlastní modul a nikoli o systémovou knihovnu WiFi.
Modul WI-FI-moje
Prostředí Arduino IDE umožňuje rozdělit projekt do více zdrojových souborů. Není přitom nutné vytvářet plnohodnotnou knihovnu. Pro naše účely bude bohatě stačit vytvořit vlastní modul složený ze souborů WI-FI-moje a WI-FI-moje.cpp.
Proč dva soubory?
Možná vás napadlo, proč jsme místo jednoho souboru vytvořili hned dva – WI-FI-moje.h a WI-FI-moje.cpp. Důvod je jednoduchý. Jazyk C++ pro vytvoření modulu, do kterého můžeme přesunout část kódu, používá dvojici souborů, tzv.:
- hlavičkový soubor (
.h) - implementační soubor (
.cpp)
Každý z nich má jinou úlohu.
Soubor .h – veřejné rozhraní modulu
Hlavičkový soubor obsahuje především deklarace funkcí, tříd, konstant a datových typů, které mají být dostupné ostatním částem programu. Můžeme si jej představit jako jakýsi obsah nebo katalog služeb, které daný modul nabízí.
V našem případě soubor WI-FI-moje.h představuje okolnímu světu funkci:
bool connectWiFi(const char* ssid, const char* password);
Z hlavičkového souboru však není patrné, jak je tato funkce implementována. Je zde pouze informace o tom, že existuje a jakým způsobem ji lze volat.
Soubor WI-FI-moje.h
Nejprve vytvoříme nový soubor WI-FI-moje.h, který bude obsahovat deklarace funkcí dostupných pro hlavní program.
V prostředí Arduino IDE 2 v pravém horním rohu klikneme na ikonu se třemi tečkami ... (viz obr. č. 2), kde vybereme volbu Nová karta a zadáme název nové karty (tedy i nového souboru) – v našem případě zvolíme WI-FI-moje.h.
Do nového prázdného okna s názvem WI-FI-moje.h vložíme kód:
#ifndef WIFI_MOJE_H
#define WIFI_MOJE_H
bool connectWiFi(const char* ssid,
const char* password);
#endif
Soubor .cpp – vlastní implementace
Implementační soubor naopak obsahuje skutečný programový kód. Právě zde se nacházejí příkazy, které vykonávají vlastní práci.
V našem případě je v souboru WI-FI-moje.cpp uložen kód funkce connectWiFi() v jazyce C++. Hlavní program nemusí vědět, jakým způsobem je funkce connectWiFi() implementována. Stačí, že zná její rozhraní definované v souboru WI-FI-moje.h.
Stačí mu zavolat:
connectWiFi(ssid, password);
a veškerá potřebná práce proběhne uvnitř modulu – tedy v kódu uloženém v souboru WI-FI-moje.cpp.
Soubor WI-FI-moje.cpp
Vytvoříme v prostředí Arduino IDE druhý soubor, tentokráte s názvem WI-FI-moje.cpp. Do něj přesuneme vlastní implementaci funkce connectWiFi() – tedy kód, který zajišťuje navázání spojení s bezdrátovou sítí a kontrolu, zda připojení proběhlo úspěšně – tento kód hodně vychází z naší základní ukázky, jak se připojit k Wi-Fi síti. Na webu lze najít sofistikovanější řešení této funkce, které kupříkladu využívají události objektu WiFi, ale nám to jako základní ukázka stačí.
#include <Arduino.h>
#include <WiFi.h>
#include "WI-FI-moje.h"
bool connectWiFi(const char* ssid, const char* password) {
// Pokud už jsme připojeni, není třeba nic dělat
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Wi-Fi jiz je pripojena.");
return true;
}
Serial.print("Pripojuji k SSID: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
uint32_t startTime = millis();
const uint32_t timeout = 10000; // 10 s
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
if (millis() - startTime > timeout) {
Serial.println();
Serial.println("Timeout pripojeni.");
return false;
}
}
Serial.println();
Serial.println("Wi-Fi pripojena.");
Serial.print("IP adresa: ");
Serial.println(WiFi.localIP());
return true;
}
Při pohledu na zdrojový kód stojí za zmínku několik důležitých detailů.
- Na začátku souboru připojujeme knihovnu
WiFi.h, přestože ji budeme připojovat také v hlavním programu. Na první pohled to může působit zbytečně, ale ve skutečnosti jde o správný postup. Modul by měl obsahovat všechny knihovny, které ke své činnosti potřebuje. Pokud by někdo někdy použil náš modul v jiném projektu a zapomněl připojitWiFi.h, modul si ji připojí sám. Naopak pokud již byla knihovna připojena dříve, překladač ji podruhé nezpracuje. Díky tzv. ochranným mechanismům v hlavičkových souborech je opakované použití#includebezpečné. - Soubor
WI-FI-moje.cpppřipojuje pomocí direktivy#include "WI-FI-moje.h"svůj vlastní hlavičkový soubor. Tento postup je v jazyce C++ považován za standardní praxi a měl by být dodržován u každého modulu. Překladač tak může ověřit, že implementace funkcí v souboru.cppskutečně odpovídá jejich deklaracím v souboru.h. - Na rozdíl od hlavního programu zde nenajdeme funkce
setup()aniloop(). SouborWI-FI-moje.cppnení samostatný program, ale pouze modul obsahující implementaci funkcí, které mohou využívat jiné části projektu. V našem případě je to funkceconnectWiFi(), kterou bude volat hlavní program. - Všimněte si také, že síťové údaje
ssidapasswordnejsou v tomto souboru pevně zadané. Funkce je přijímá jako parametry, takže stejný modul lze bez úprav použít v libovolném projektu a připojit jej k jiné Wi-Fi síti pouhou změnou parametrů při volání funkce.
Tím máme vlastní modul dokončen. Než jej začneme používat v dalších projektech, zastavme se ještě na chvíli u otázky, proč jsme vlastně vytvořili dva soubory a jaká je úloha každého z nich. Tím zároveň vytvoříme přirozený prostor pro vysvětlení, proč se moduly v jazyce C++ skládají ze dvou souborů – hlavičkového souboru .h a implementačního souboru .cpp.
Hlavní program
Máme-li připravený hlavní program i oba soubory našeho modulu, je dobré zdůraznit, že soubory našeho modulu uložíme do stejné složky jako právě soubor .ino hlavního programu. Od té chvíle, když v hlavním programu napíšeme:
#include "WI-FI-moje.h"
přeloží se obsah hlavičkového souboru na místo direktivy #include. Překladač se tak dozví, že někde existuje funkce connectWiFi().
Samotnou implementaci potom najde v souboru WI-FI-moje.cpp, který Arduino IDE automaticky přeloží společně s hlavním programem. Výsledný program je tedy složen z několika zdrojových souborů, které dohromady tvoří jednu aplikaci.
Toto použití je stejné, jak ho kupříkladu známe i od jiných modulů, které někdo dříve napsal pro nás a my je nyní využíváme například pro práci s LCD nebo OLED displejem, čtení hodnot ze senzorů a podobně.
Vlastní hlavní program pak díky této koncepci může být, jak jsme si dříve ukázali, velmi stručný. Díky modulu WI-FI-moje a jeho funkci connectWiFi() se již nemusíme v dalších ukázkách zabývat detaily připojování k bezdrátové síti. Můžeme se proto plně soustředit na vlastní téma jednotlivých příkladů,
například na HTTP komunikaci, práci s webovými API nebo na přenos dat po síti.
- Poznámka:
- Právě takto se postupně rodí dobře strukturované projekty – rozdělením programu na menší, samostatně použitelné části, z nichž každá řeší pouze jeden konkrétní úkol. Takový kód se nejen lépe čte, ale také snadněji rozšiřuje a udržuje.
Poznámka k IP adrese v režimu STA
V případě režimu STA zpravidla počítáme s tím, že stanice, která se přihlásí do sítě, obdrží od řídicího síťového prvku IP adresu přiřazenou dynamicky – tedy tak trochu, „co na ní právě vyjde“. Jsou však situace, kde bychom potřebovali (kupříkladu kvůli požadavku správce sítě), aby náš modul měl IP adresu stále stejnou – tzv. statickou 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 adresa
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í
K režimu STA a vůbec připojování čehokoliv k Wi-Fi sítím se jistě hodí zmínit i následující kód. Jde o skener dostupných Wi-Fi sítí. Modul ESP32 zde provede „průzkum“ dostupných sítí ve svém okolí a vypíše na sériový port jejich seznam včetně síly jejich signálu a hvězdičkou označí ty, které jsou zabezpečeny heslem.
/* 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ění kódu se bude v pětivteř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, který zachycuje nalezení šesti dostupných sítí (názvy jsou raději „anonymizovány“), z toho jednu FREE (bez zabezpečení).
Připojení ESP32 k Wi-Fi – režim Soft Access Point (AP)
Režim přístupového bodu (AP): Modul vytvoří vlastní Wi-Fi síť (tzv. Soft Access Point) a funguje jako rozbočovač pro ostatní stanice. Tento režim z modulu vytváří zdroj vlastní Wi-Fi sítě, ke které se lze připojit. S ohledem na výkonové možnosti tohoto mikrokontroléru je počet připojených stanic omezen na pět.
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 naše zařízení nemá rozhraní ke kabelové síti. Takový provozní režim se nazývá Soft Access Point (soft-AP). V případě modulu ESP32 je maximální počet stanic, které se mohou k modulu ESP32 připojit, omezen na pět!
V režimu AP vytvoří ESP32 novou Wi-Fi síť s nastaveným SSID (název sítě) a IP adresou. 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ě.
Ukážeme si nastavení ESP32 jako (Soft)AP. Nebude tedy třeba se přihlašovat k existující Wi-Fi, ale modul ESP32 si vytvoří Wi-Fi svojí, kterou otestujeme tím, že se k ní připojíme pomocí mobilního telefonu – ten v tu chvíli bude v režimu stanice STA.
Program je obdobný předešlým, jediný rozdíl je v nastavení Wi-Fi. Začínáme tedy stejně, tedy knihovnou WiFi. Náš modul WI-FI-moje nyní nepotřebujeme, neboť se nikam nepřipojujeme.
Když nastavujeme ESP32 v režimu přístupového bodu (AP), musíme ale nastavit SSID, heslo sítě, kterou bude modul vysílat. Tedy 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.
// pripojeni potrebne knihovny
#include <WiFi.h>
const char* ssid = "Sit modulu ESP32"; // Enter SSID here
const char* password = "12345678"; //Enter Password here
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
if (WiFi.softAP(ssid, password)) {
Serial.println("Wi-Fi sit byla vytvorena.");
} else {
Serial.println("Vytvoreni Wi-Fi selhalo.");
while(true); // neuspech konci nekonecnou smyckou
}
delay(1000);
// Získání a výpis IP adresy modulu (výchozí bývá 192.168.4.1)
Serial.print("IP adresa Access Pointu: ");
Serial.println(WiFi.softAPIP());
}
void loop() {
}
V kódu vidíme nastavení názvu sítě a přístupového hesla v proměnných ssid a password. Aby byl Access Point (AP) zcela bez hesla (otevřená síť), stačí parametr s heslem úplně vynechat, případně na jeho místo zadat NULL.
// Varianta 1: Úplné vynechání parametru (nejčistší způsob)
WiFi.softAP("Otevrena_Sit");
nebo
// Varianta 2: Explicitní vyjádření pomocí NULL
WiFi.softAP("Otevrena_Sit", NULL);
- Poznámka:
- Zabezpečení WPA2 vyžaduje pro heslo minimálně 8 znaků.
- V některých tutoriálech se traduje takový mýtus, že zadáním kratšího hesla vznikne otevřená síť – ve skutečnosti se tím pouze způsobí selhání inicializace Wi-Fi. Pokud chceme síť opravdu bez hesla, druhý parametr v
WiFi.softAP()úplně vynecháme.
Režim přístupového bodu zapneme pomocí:
WiFi.mode(WIFI_AP);
Opět i toto nastavení zde není úplně nutné, protože následná funkce WiFi.softAP() má v sobě zabudovanou automatiku. Jakmile ji zavoláme, knihovna se podívá na aktuální stav, interně si zapne potřebné AP rozhraní. Když ale na začátek napíšete WiFi.mode(WIFI_AP), máte jistotu, že se klientská část (STA) striktně vypne a ESP32 nebude na pozadí plýtvat energií hledáním okolních sítí.
Přístupový bod však aktivujeme až příkazem:
WiFi.softAP(ssid, password)
Zároveň si všimněme, že metodu softAP() lze testovat jako funkci na úspěch vytvoření Wi-Fi sítě – viz kód výše.
Pro vypsání IP adresy právě vytvořeného přístupového bodu použijeme:
Serial.println(WiFi.softAPIP());
Pro získání IP adresy samotného Access Pointu nelze použít WiFi.localIP(), jako jsme používali v případě režimu STA. Pokud tuto funkci zavoláme v čistém AP režimu, vrátí nám pouze adresu 0.0.0.0. Knihovna pro ESP32 totiž striktně rozlišuje dvě síťová rozhraní, z nichž každé má svou vlastní IP adresu:
WiFi.softAPIP(): Vrací IP adresu rozhraní AP (Access Point). Tedy adresu sítě, kterou ESP32 samo vysílá (výchozí je192.168.4.1). Tuto adresu zadávají klienti do prohlížeče, aby se k modulu připojili.WiFi.localIP(): Vrací IP adresu rozhraní STA (Station). Tedy adresu, kterou ESP32 dostalo přidělenou od domácího routeru, když se k němu ESP32 připojilo jako klient.
Po nahrání programu postupujte jako v každém jiném případě, tedy: Otevřete Sériový monitor prostředí Arduino IDE s přenosovou rychlostí 115200 a stiskneme tlačítko RESET na modulu ESP32. Pokud je vše v pořádku, zobrazí se zpráva:
Wi-Fi sit byla vytvorena.
IP adresa Access Pointu: 192.168.4.1
Dále vezmeme jakékoli zařízení, které se můžete připojit k síti Wi-Fi (mobil, tablet, PC atd.). Vyhledáme síť s názvem „Sit modulu ESP32“ a připojíme se heslem 12345678.
Bohužel úspěšným připojením k této Wi-Fi síti naše snaha zatím skončí. Zatím nemáme na modulu ESP32 spuštěný server, který by byl schopen zpracovávat příchozí požadavky třeba z webového prohlížeče na připojeném zařízení. Jak to udělat, abychom konečně mohli to naše ESP32 začít řídit přes síť Wi-Fi, si ukážeme v některém z dalších článků. Protože to pak teprve začne být ta správná bastlířská zábava!
Jen ještě doplníme, že podobně jako v režimu STA, kde jsme mohli IP adresu přiřazovanou dynamicky nastavit napevno, i zde můžeme (obdobným způsobem) změnit výchozí IP adresu přístupového bodu AP.
/* Nastavení detailů IP adresy */
IPAddress local_ip(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.mode(WIFI_AP);
// DŮLEŽITÉ: softAPConfig se musí volat PŘED spuštěním samotného softAP
WiFi.softAPConfig(local_ip, gateway, subnet);
WiFi.softAP(ssid, password);
Připojení ESP32 k Wi-Fi – režim STA a AP současně
Režim STA + AP: ESP32 může současně (!) pracovat v obou režimech (WIFI_AP_STA). To umožňuje například vytvořit určitý „hotspot“ pro bezdrátová čidla v okolí a zároveň se jako stanice dotazovat na data z internetu.
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ý Wi-Fi přístupový bod (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žimu 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ů, vlhkomě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.
Jelikož si nadále v článku ukážeme oba režimy (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 popsaný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 odstavců 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.
- 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.
Pochopitelně by se měla v okolí objevit nová Wi-Fi síť generovaná modulem ESP32 – v 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ří.
Závěrem
Jak jsme viděli, rozjet na ESP32 vlastní Wi-Fi síť je otázkou několika málo řádků kódu. Díky dnešnímu přehledu už navíc víte, jak se třeba vyhnout chytákům s délkou hesla a jak si správně ohlídat konfiguraci IP adres, aby celá infrastruktura fungovala bez chyb a konfliktů.
Samotná běžící síť je ale teprve odrazovým můstkem. Aby měla vlastní Wi-Fi reálné využití, musíme zařídit, aby modul na síťové požadavky také smysluplně odpovídal. V navazujících článcích se proto posuneme k praktickému nasazení: Ukážeme si, jak z ESP32 postavit webový server pro ovládání hardwaru na dálku a pro přehledné zobrazování dat v prohlížeči. Podíváme se i na opačnou stranu mince – jak modul nakonfigurovat jako klienta, který se hladce integruje do stávající domácí sítě, bude do internetu odesílat webové dotazy a otevře nám tak dveře k plnohodnotným IoT projektům.