Se connecter à un réseau Wi-Fi avec l’ESP32
(Mis à jour le 11/01/2023)
La librairie WiFi.h (installée automatiquement) va nous permettre
d’utiliser facilement les fonctionnalités Wi-Fi de la carte ESP32.
L’ESP32 possède 2 modes WiFi possibles :
- STATION (WIFI_STA ) : Le mode Station (STA) est utilisé
pour connecter le module ESP32 à un point d’accès Wi-Fi. L’ESP32 se
comporte comme un ordinateur qui serait connecté à notre box. Si la box
est reliée à Internet, alors l’ESP32 peut accéder à Internet. L’ESP32 peut
se comporter en tant que client , c’est-à-dire faire des
requêtes aux autres appareils connectés sur le réseau ou en tant que serveur ,
c’est-à-dire que d’autres appareils connectés sur le réseau vont envoyer
des requêtes à l’ESP32. Dans les 2 cas, l’ESP32 peut accéder à Internet.
- AP (Access Point) (WIFI_AP )
: En mode Access Point, l’ESP32 se comporte comme un réseau Wi-Fi (un peu
comme une box) : d’autres appareils peuvent s’y connecter dessus. Dans ce
mode, l’ESP32 n’est relié à aucun autre réseau et n’est donc pas connecté
à Internet. Ce mode est plus gourmand en calcul et en énergie (la carte
ESP32 va chauffer) puisque l’ESP32 doit simuler un routeur Wifi complet
(Soft AP). La latence et le débit seront moins bons qu’avec une box classique.
Note
L’ESP32 est par défaut en mode
STATION.
Pour le choix du mode :
- En général, on utilise le mode STATION .
On pourra accéder à internet pour récupérer des informations d’API, avoir
un serveur “domotique” avec des capteurs…
- On utilise en général le mode AP
provisoirement pour rentrer les paramètres de connexion du réseau WiFi
(SSID + MDP). On peut également l’utiliser pour avoir un réseau séparé de
son réseau domestique et non relié à Internet.
Connexion à un réseau Wi-Fi
Le programme pour se connecter à sa box se résume à
:
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); //Optional
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
Important
Il faut modifier "yourNetworkName" par le nom du réseau Wi-Fi et "yourNetworkPassword" par le mot de passe du réseau.
Astuce
Un moyen simple d’avoir un AP pour tester le
programme est de faire un partage de connexion Wi-Fi depuis son smartphone.

Sortie du terminal
Connecting
................
Connected to the WiFi network
Local ESP32 IP: 192.168.43.129
Le code fonctionne de la manière suivante :
- On pense à bien inclure la librairie WiFi.h .
- Puis on rentre le nom du réseau et son mot de passe.
- On met l’ESP32 en mode STATION avec la fonction WiFi.mode(WIFI_STA)
- L’ESP32 essaye de se connecter au réseau WiFi à l’aide de la
fonction WiFi.begin(ssid, password)
- La connexion n’est pas instantanée ! Il faut donc regarder
régulièrement l’état de la connexion : tant que l’ESP32 n’est pas connecté
au réseau, on reste bloqué dans la boucle while . On
ajoute un petit délai pour éviter de regarder en permanence le statut.
- Une fois que l’on est connecté, on affiche l’adresse IP locale de
l’ESP32 sur ce réseau.
S’il s’agit d’un réseau ouvert (sans mot de passe),
alors le programme se simplifie :
#include <WiFi.h>
const char* ssid = "yourNetworkName";
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid);
Serial.println("\nConnecting");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
Note
Stocker les identifiants et mot de passes en clair dans le code est une
mauvaise pratique. Néanmoins, le faire permet de simplifier les tutoriels.
Obtenir des informations sur le réseau Wi-Fi
On peut obtenir des informations sur le réseau une
fois que l’on est connecté sur celui-ci :
- La puissance du signal WiFi (RSSI) avec la fonction WiFi.RSSI()
- L’adresse MAC du réseau WiFi avec WiFi.BSSIDstr() ou WiFi.macAddress()
- L’adresse IP locale de l’ESP32 attribuée par le serveur DHCP du réseau
WiFi WiFi.localIP()
- L’adresse IP locale du réseau WiFi (passerelle) avec WiFi.gatewayIP() (en
général 192.168.0.1)
- Le masque de sous-réseau avec WiFi.subnetMask() (en
général 255.255.255.0)
Le code ci-dessous affiche toutes ces informations
:
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void get_network_info(){
if(WiFi.status() == WL_CONNECTED) {
Serial.print("[*]
Network information for ");
Serial.println(ssid);
Serial.println("[+]
BSSID : " + WiFi.BSSIDstr());
Serial.print("[+]
Gateway IP : ");
Serial.println(WiFi.gatewayIP());
Serial.print("[+]
Subnet Mask : ");
Serial.println(WiFi.subnetMask());
Serial.println((String)"[+] RSSI :
" + WiFi.RSSI() + " dB");
Serial.print("[+]
ESP32 IP : ");
Serial.println(WiFi.localIP());
}
}
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the
WiFi network");
get_network_info();
}
void loop(){}
Sortie du terminal
Connecting
..............
Connected to the WiFi network
[*] Network information for
HUAWEI_**
[+] BSSID : F0:43:47:32:1F:4D
[+] Gateway IP : 192.168.43.1
[+] Subnet Mask : 255.255.255.0
[+] RSSI : -25 dB
[+] ESP32 IP : 192.168.43.129
Debugger les problèmes de connexion
Regarder le statut de la connexion
On peut connaître le statut de la connexion WiFi
avec la fonction WiFi.status() . Cette
fonction renvoie un entier en fonction de l’état actuel de la connexion.
Les statuts possibles sont :
- WL_IDLE_STATUS : C’est le statut par défaut avant d’essayer de se connecter à
un réseau.
- WL_SCAN_COMPLETED : Le scan des réseaux
WiFi est terminé.
- WL_NO_SSID_AVAIL : L’ESP32 n’arrive pas à trouver le nom du réseau WiFi. Soit le
réseau est trop loin de l’ESP32, soit le nom (SSID) du réseau est
incorrect.
- WL_CONNECT_FAILED : L’ESP32 n’arrive pas
à se connecter au réseau WiFi désigné.
- WL_CONNECTION_LOST : La connexion WiFi
avec le réseau est perdue. Si cette erreur se répète c’est peut-être un
problème d’alimentation de l’ESP32.
- WL_CONNECTED : L’ESP32 est connecté au réseau WiFi.
- WL_DISCONNECTED : L’ESP32 est déconnecté du réseau WiFi.
Code qui permet d’afficher les statuts de la
connexion WiFi
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
String get_wifi_status(int status){
switch(status){
case WL_IDLE_STATUS:
return "WL_IDLE_STATUS";
case WL_SCAN_COMPLETED:
return "WL_SCAN_COMPLETED";
case WL_NO_SSID_AVAIL:
return "WL_NO_SSID_AVAIL";
case WL_CONNECT_FAILED:
return "WL_CONNECT_FAILED";
case WL_CONNECTION_LOST:
return "WL_CONNECTION_LOST";
case WL_CONNECTED:
return "WL_CONNECTED";
case WL_DISCONNECTED:
return "WL_DISCONNECTED";
}
}
void setup(){
Serial.begin(115200);
delay(1000);
int status = WL_IDLE_STATUS;
Serial.println("\nConnecting");
Serial.println(get_wifi_status(status));
WiFi.begin(ssid, password);
while(status != WL_CONNECTED){
delay(500);
status = WiFi.status();
Serial.println(get_wifi_status(status));
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
Exemples de scénarios possibles
Connexion réussie
Connecting
WL_IDLE_STATUS
WL_DISCONNECTED
WL_DISCONNECTED
WL_CONNECTED
Connected to the WiFi network
Local ESP32 IP: 192.168.43.129
SSID introuvableMauvais mot de passe
Redémarrer l’ESP32
De temps en temps, pour une raison inconnue,
l’ESP32 peut ne pas arriver temporairement à se connecter au réseau WiFi. La meilleure
solution est de dire qu’au bout de n secondes si l’ESP32 ne
s’est toujours pas connecté au WiFi, on redémarre l’ESP32. Il suffit d’ajouter
un timeout et d’utiliser la fonction ESP.restart() pour redémarrer l’ESP32 depuis le code.
Voici un exemple qui permet de redémarrer
l’ESP32 au bout de 10 s s’il n’est toujours pas connecté au WiFi.
#include <WiFi.h>
#define CONNECTION_TIMEOUT 10
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); //Optional
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
int timeout_counter = 0;
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(200);
timeout_counter++;
if(timeout_counter >= CONNECTION_TIMEOUT*5){
ESP.restart();
}
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
L’ESP32 est bien reset au bout de 10 s en cas
d’échec de connexion depuis le code avec le flag SW_CPU_RESET lors du boot.
Connecting
.......................................................
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13
(SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac
Connecting
.......
Connected to the WiFi network
Local ESP32 IP: 192.168.43.129
Changer de canal Wi-Fi
Si l’ESP32 à plus ou moins du mal à se connecter au
WiFi en fonction de périodes (ou de plage horaire), c’est peut-être lié au
canal Wi-Fi choisi par votre box. En fait, même si la fréquence du Wi-Fi soit
de 2.4GHz, les boxs utilisent une multitude de bandes autour de 2.4GHz, que
l’on appelle des canaux pour désengorger le trafic. C’est ce qui permet d’avoir
dans des immeubles beaucoup de box Wi-Fi différentes dans un espace très proche
sans qu’elles se gênent mutuellement.
Il y a en France, 14 canaux disponibles. Les canaux
disponibles varient en fonction des pays. En général, le canal est choisi
automatiquement par le modem (en mode auto ), en fonction des autres canaux utilisés par les boxs aux alentours.
Sauf qu’en pratique, les box se retrouvent toujours sur les derniers canaux 12,
13 et 14.
Une solution est de changer le numéro du canal
utilisé par la box, vers le numéro 1, 6 ou 11 par exemple. Ce changement se
fait via l’interface administrateur de la box, en général sur l’IP 192.168.0.1 .
Si vous utilisez beaucoup d’objets IOT connectés en
Wi-Fi, je vous recommande d’avoir un second routeur Wi-Fi, pour séparer
l’utilisation domestique à celle de l’IOT. En choisissant le canal 1 ou 6 pour
le routeur des capteurs IOT et un canal entre 11 et 14 pour l’autre routeur,
vous ne devriez plus avoir de problème de connexion Wi-Fi.
Pour aller plus loin
Attribuer une adresse IP fixe
L’adresse IP locale de l’ESP32 a été attribuée automatiquement
par le serveur DHCP de la box. C’est pratique d’avoir une adresse IP
automatiquement sur l’ordinateur car on n’a pas à la rentrer manuellement.
L’inconvénient (ou avantage en fonction des cas) est que l’adresse IP est
dynamique : elle peut changer. Cela peut devenir gênant si par exemple, dès que
l’on redémarre l’ESP32 (ou que le bail du DHCP est expiré) l’adresse IP change,
alors qu’on a un serveur web qui tourne sur l’ESP32. Il faudrait à chaque fois
retrouver l’IP de l’ESP32. On peut pallier ce problème en fixant l’adresse IP
de l’ESP32 sur le réseau. Il faut utiliser pour cela la fonction WiFi.config(ip,
dns, gateway, subnet)
Les paramètres à renseigner sont :
- IP : L’adresse IP que l’on souhaite attribuer.
- DNS : Service qui fait le lien entre une URL et une IP. Par défaut,
on utilise le serveur DNS de la box internet ou le routeur : donc on
indique la même adresse que le routeur (en général 192.168.0.1).
- GATEWAY : C’est l’adresse IP de la box internet ou du routeur (en
général 192.168.0.1)
- SUBNET : Masque de sous-réseau (en général 255.255.255.0)
Note
Il faut connaître l’adresse IP du routeur : le plus simple est d’utiliser
le code qui affiche les informations du réseau WiFi dans le moniteur série.
Dans cet exemple, en utilisant le partage WiFi d’un
téléphone l’adresse IP du routeur est 192.168.43.1 . Je
choisis d’avoir comme IP statique 192.168.43.42 pour l’ESP32.
Code qui permet de fixer l’adresse IP de l’ESP32
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
IPAddress ip(192, 168, 43, 42);
IPAddress dns(192, 168, 43, 1);
IPAddress gateway(192, 168, 43, 1);
IPAddress subnet(255, 255, 255, 0);
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.config(ip, gateway, subnet, dns);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("[+]
ESP32 IP : ");
Serial.println(WiFi.localIP());
}
void loop(){}
Avertissement
Il faut penser à ne pas utiliser une IP déjà prise par un autre appareil
sur le réseau. On peut aussi assigner une adresse IP fixe liée à l’adresse MAC
directement depuis les paramètres du routeur.
À but informatif, on peut ensuite faire un ping
depuis l’ordinateur vers l’IP 192.168.43.42 pour voir si la
nouvelle adresse a bien été prise en compte :

Ping de l’ESP32 depuis le terminal Windows
(cmd.exe)
Note
Si vous avez l’erreur, ping : échec de la transmission.
Défaillance générale , il y a un sûrement un logiciel ou pare-feu
qui désactive l’utilisation des pings. Cela peut être notamment le cas avec des
clients VPN.
Changer l’adresse MAC
Dans certaines applications, il peut être
intéressant de modifier l’adresse MAC de l’ESP32. On peut changer l’adresse MAC
avec quelques lignes de code en utilisant la fonction esp_wifi_set_mac()
Note
Le changement de l’adresse MAC est temporaire, elle ne remplace pas celle
d’origine. Il suffit d’uploader un nouveau programme pour retrouver l’adresse
MAC d’origine.
#include <WiFi.h>
#include <esp_wifi.h>
uint8_t new_mac[] = {0x60, 0x8B, 0x0E, 0x01, 0x5A, 0x32};
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);//Needed to change MAC adress
Serial.print("[+]
Current MAC Address: ");
Serial.println(WiFi.macAddress());
esp_wifi_set_mac(ESP_IF_WIFI_STA, new_mac);
Serial.print("[+]
New MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop(){}
Terminal série :
[+] Current MAC Address: 24:6F:28:BB:2E:E8
[+] New MAC Address: 60:8B:0E:01:5A:32
Code qui se connecte à un réseau Wi-Fi avec une
adresse MAC modifiée
#include <WiFi.h>
#include <esp_wifi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
uint8_t new_mac[] = {0x6C, 0x8D, 0xC1, 0x01, 0x5A, 0x32};
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);//Needed to change MAC adress
esp_wifi_set_mac(ESP_IF_WIFI_STA, new_mac);
delay(1000);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
Une capture Wireshark montre que l’adresse a bien été changée (ici par une adresse MAC
d’Apple):

Capture d’une trame réseau avec Wireshark
Economiser de l’énergie
Si on utilise un ESP32 dans un projet qui doit
forcément utiliser le WiFi pour fonctionner, il est judicieux de mettre l’ESP32
en mode Deep Sleep en cas d’échec de connexion, pour minimiser la consommation
d’énergie. C’est un code similaire avec celui de l’ESP32 qui “dort” pendant 10
secondes entre chaque tentative.
Code qui permet de mettre l’ESP32 en Deep Sleep
entre 2 tentatives
#include <WiFi.h>
#include <esp_wifi.h>
//Time in seconds
#define CONNECTION_TIMEOUT 5
#define DEEP_SLEEP_DURATION 10
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
int timeout_counter = 0;
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
timeout_counter++;
if(timeout_counter >= CONNECTION_TIMEOUT*10){
Serial.println("\nCan't establish
WiFi connexion");
//Setup timer
esp_sleep_enable_timer_wakeup(DEEP_SLEEP_DURATION * 1000000);
//Start deep sleep
esp_deep_sleep_start();
}
}
Serial.println("\nConnected to the
WiFi network");
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void loop(){}
Utiliser les Wi-Fi events pour avoir un code optimisé
Jusqu’à maintenant, on faisait du polling avec les
fonctions Wi-Fi, c’est-à-dire que l’ESP32 reste bloquée tant qu’elle n’a pas
reçu un évènement (event) par le contrôleur Wi-Fi. On faisait de la
programmation séquentielle. Prenons un exemple :
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(100);
}
On regarde (poll en anglais) régulièrement si
l’ESP32 a réussi à se connecter au réseau Wi-Fi. Pendant l’attente, on ne fait
rien (on pourrait cependant faire des calculs entre 2 polls) et on reste bloqué
dans la boucle while. Difficile de s’y retrouver si l’on veut faire des choses
différentes en fonction du statut du Wi-Fi.
Une manière plus propre est de faire de la programmation
évènementielle en utilisant les évènements. En effet, des évènements
sont générés quand le wifi change d’état. L’intérêt est que l’on peut exécuter
du code automatiquement en fonction de l’événement reçu. Cela ressemble
beaucoup aux interruptions que l’on utilise sur les pins GPIO. Un
changement d’état du pin génère une interruption, qui va exécuter une portion
de code prioritaire. Ici un changement d’état du Wi-Fi génère un évènement qui
va également exécuter une portion de code.
Le code de base pour gérer les évènements
est :
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void my_function(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info){
//Code
}
void setup(){
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); //Optional
WiFi.onEvent(my_function, WIFI_EVENT_ID);
WiFi.begin(ssid, password);
}
void loop(){}
On utilise la fonction WiFi.onEvent(my_function,
WIFI_EVENT_ID) pour préciser quelle fonction sera exécutée
quand l’événement WIFI_EVENT_ID sera
détecté. Il faut remplacer WIFI_EVENT_ID par le nom ou le numéro de l’event (voir tableau ci-dessous). La
fonction my_function() doit avoir
les paramètres WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info même s’ils ne sont pas utilisés.
Avertissement
En fonction de la version du portage ESP32 en code Arduino que vous avez
installé, le nom des événements est différent.
Version 2.0x
|
Liste des évènements Wi-Fi |
||
|
Numéro |
Nom de l’event |
Description |
|
0 |
ARDUINO_EVENT_WIFI_READY |
ESP32 WiFi ready |
|
1 |
ARDUINO_EVENT_WIFI_SCAN_DONE |
ESP32 finish scanning AP |
|
2 |
ARDUINO_EVENT_WIFI_STA_START |
ESP32 station start |
|
3 |
ARDUINO_EVENT_WIFI_STA_STOP |
ESP32 station stop |
|
4 |
ARDUINO_EVENT_WIFI_STA_CONNECTED |
ESP32 station connected to AP |
|
5 |
ARDUINO_EVENT_WIFI_STA_DISCONNECTED |
ESP32 station disconnected from AP |
|
6 |
ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE |
the auth mode of AP connected by ESP32 station
changed |
|
7 |
ARDUINO_EVENT_WIFI_STA_GOT_IP |
ESP32 station got IP from connected AP |
|
8 |
ARDUINO_EVENT_WIFI_STA_LOST_IP |
ESP32 station lost IP and the IP is reset to 0 |
|
9 |
ARDUINO_EVENT_WPS_ER_SUCCESS |
ESP32 station wps succeeds in enrollee mode |
|
10 |
ARDUINO_EVENT_WPS_ER_FAILED |
ESP32 station wps fails in enrollee mode |
|
11 |
ARDUINO_EVENT_WPS_ER_TIMEOUT |
ESP32 station wps timeout in enrollee mode |
|
12 |
ARDUINO_EVENT_WPS_ER_PIN |
ESP32 station wps pin code in enrollee mode |
|
13 |
ARDUINO_EVENT_WIFI_AP_START |
ESP32 soft-AP start |
|
14 |
ARDUINO_EVENT_WIFI_AP_STOP |
ESP32 soft-AP stop |
|
15 |
ARDUINO_EVENT_WIFI_AP_STACONNECTED |
a station connected to ESP32 soft-AP |
|
16 |
ARDUINO_EVENT_WIFI_AP_STADISCONNECTED |
a station disconnected from ESP32 soft-AP |
|
17 |
ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED |
ESP32 soft-AP assign an IP to a connected station |
|
18 |
ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED |
Receive probe request packet in soft-AP interface |
|
19 |
ARDUINO_EVENT_WIFI_AP_GOT_IP6 |
ESP32 ap interface v6IP addr is preferred |
|
19 |
ARDUINO_EVENT_WIFI_STA_GOT_IP6 |
ESP32 station interface v6IP addr is preferred |
|
20 |
ARDUINO_EVENT_ETH_START |
ESP32 ethernet start |
|
21 |
ARDUINO_EVENT_ETH_STOP |
ESP32 ethernet stop |
|
22 |
ARDUINO_EVENT_ETH_CONNECTED |
ESP32 ethernet phy link up |
|
23 |
ARDUINO_EVENT_ETH_DISCONNECTED |
ESP32 ethernet phy link down |
|
24 |
ARDUINO_EVENT_ETH_GOT_IP |
ESP32 ethernet got IP from connected AP |
|
19 |
ARDUINO_EVENT_ETH_GOT_IP6 |
ESP32 ethernet interface v6IP addr is preferred |
|
25 |
ARDUINO_EVENT_MAX |
|
Ancienne version 1.x
Le code suivant fait la même chose que le code du
tout début pour se connecter à une box mais cette fois avec l’utilisation d’événements
lorsque l’on est connecté à un réseau.
Code qui permet de se connecter à une box avec les
événements Wi-Fi
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void connected_to_ap(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info) {
Serial.println("\nConnected to the
WiFi network");
}
void got_ip_from_ap(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info) {
Serial.print("Local
ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); //Optional
WiFi.onEvent(connected_to_ap, ARDUINO_EVENT_WIFI_STA_CONNECTED);
WiFi.onEvent(got_ip_from_ap, ARDUINO_EVENT_WIFI_STA_GOT_IP);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
}
void loop() {}
Sortie de la console :
Connecting
.............
Connected to the WiFi network
Local ESP32 IP: 192.168.43.167
On peut enlever l’exécution de la fonction liée à
un évènement pendant l’exécution du programme avec WiFi.removeEvent(WIFI_EVENT_ID)
Une utilisation pratique des évènements est la
possibilité de reconnecter automatiquement l’ESP32 en cas de déconnexion.
#include <WiFi.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void connected_to_ap(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info) {
Serial.println("[+]
Connected to the WiFi network");
}
void disconnected_from_ap(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info) {
Serial.println("[-]
Disconnected from the WiFi AP");
WiFi.begin(ssid, password);
}
void got_ip_from_ap(WiFiEvent_t wifi_event, WiFiEventInfo_t wifi_info) {
Serial.print("[+]
Local ESP32 IP: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); //Optional
WiFi.onEvent(connected_to_ap, ARDUINO_EVENT_WIFI_STA_CONNECTED);
WiFi.onEvent(got_ip_from_ap, ARDUINO_EVENT_WIFI_STA_GOT_IP);
WiFi.onEvent(disconnected_from_ap, ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
}
void loop() {}
Sortie de la console :
Connecting
[-] Disconnected from the WiFi AP
[+] Connected to the WiFi network
[+] Local ESP32 IP:
192.168.43.167
[-] Disconnected from the WiFi AP
[-] Disconnected from the WiFi AP
[-] Disconnected from the WiFi AP
[-] Disconnected from the WiFi AP
[+] Connected to the WiFi network
Local ESP32 IP: 192.168.43.167
Application : Scan WiFi
Voici une application concrète qui permet de
scanner les réseaux WiFi des alentours :
#include "WiFi.h"
String get_encryption_type(wifi_auth_mode_t encryptionType) {
switch (encryptionType) {
case (WIFI_AUTH_OPEN):
return "Open";
case (WIFI_AUTH_WEP):
return "WEP";
case (WIFI_AUTH_WPA_PSK):
return "WPA_PSK";
case (WIFI_AUTH_WPA2_PSK):
return "WPA2_PSK";
case (WIFI_AUTH_WPA_WPA2_PSK):
return "WPA_WPA2_PSK";
case (WIFI_AUTH_WPA2_ENTERPRISE):
return "WPA2_ENTERPRISE";
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
}
void loop() {
Serial.println("uPesy
WiFi Scan Demo");
Serial.println("[*]
Scanning WiFi network");
//
WiFi.scanNetworks will return the number of networks found
int n = WiFi.scanNetworks();
Serial.println("[*]
Scan done");
if (n == 0) {
Serial.println("[-]
No WiFi networks found");
} else {
Serial.println((String)"[+] " + n + " WiFi
networks found\n");
for (int i = 0; i < n; ++i) {
// Print SSID, RSSI
and WiFi Encryption for each network found
Serial.print(i + 1);
Serial.print(":
");
Serial.print(WiFi.SSID(i));
Serial.print("
(");
Serial.print(WiFi.RSSI(i));
Serial.print("
dB) [");
Serial.print(get_encryption_type(WiFi.encryptionType(i)));
Serial.println("]");
delay(10);
}
}
Serial.println("");
// Wait a bit before
scanning again
delay(5000);
}

Programme qui scanne les box Wi-Fi
Créer un point d’accès Wi-Fi avec un ESP32
(Mis à jour le 05/01/2023)
Le mode Access Point permet d’utiliser l’ESP32 pour créer un réseau Wi-Fi
sur lequel on peut se connecter. C’est un peu comme le partage de connexion
Wi-Fi disponible sur les téléphones. Comme sur les téléphones, le
fonctionnement d’une box Wi-Fi est simulé : on parle de Soft AP (pour
point d’accès Wi-Fi “logiciel”). Il ne faut donc pas s’attendre à avoir
les mêmes performances qu’avec un routeur Wi-Fi classique, surtout sur un
microcontrôleur !
À noter également que contrairement au partage de connexion du téléphone,
l’ESP32 n’est pas connecté à Internet : on peut donc juste utiliser le
mode Access Point pour créer un réseau local Wi-Fi privé complètement isolé
d’internet.
Voici quelques utilisations du mode Access Point :
- On se connecte à l’ESP32 en mode Access Point
provisoirement pour rentrer les identifiants de sa box Wi-Fi et permettre
ainsi à l’ESP32 de se connecter à notre réseau Wi-Fi classique. La plupart
des objets connectés utilisent ce principe pour se connecter au Wi-Fi
domestique.
- Avoir un réseau séparé de son réseau
domestique et non relié à Internet.
- Pour pouvoir communiquer facilement entre
plusieurs ESP32 par Wi-Fi
- Avoir un serveur local sur un réseau Wi-Fi
isolé
Mettre l’ESP32 en mode Access Point (AP) :
Il suffit d’utiliser les fonctions WiFi.mode(WIFI_AP) et WiFi.softAP() pour
activer le mode Access Point. Voici un exemple très simple qui permet de créer
un réseau Wi-Fi avec une ESP32 :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = "super_strong_password";
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating
AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Astuce
Il ne faut pas oublier d’importer le module WiFi.h pour que le code fonctionne avec #include
<WiFi.h> .
Important
Si le mot de passe choisi fait moins de 8 caractères, le compilateur
renverra une erreur. Le mot de passe doit être au minimum de 8 jusqu’à 63
caractères.
Sortie du terminal
[*] Creating AP
[+] AP Created with IP Gateway
192.168.4.1
On peut ensuite se connecter au réseau WiFi en
rentrant le mot de passe. Dans cet exemple, c’est un ordinateur sur Windows 10
qui va se connecter sur l’ESP32.

Connexion au réseau Wi-Fi de l’ESP32
On peut aussi créer un réseau WiFi ouvert en
mettant NULL pour le
mot de passe :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = NULL;
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating
AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Le point d’accès apparaît bien comme un réseau
ouvert :

Connexion au réseau Wi-Fi de l’ESP32 sans mot de
passe
Astuce
L’IP affichée dans le terminal série correspond à l’IP locale du routeur
sur le nouveau réseau Wi-Fi.
On peut aussi customiser un peu plus le point
d’accès en précisant le canal Wi-Fi utilisé (plus d’informations sur les canaux
Wi-Fi sont disponibles sur Wikipédia ), la visibilité ou non du réseau ainsi que le nombre maximal
d’appareils qui peuvent être connectés en même temps.
#include <WiFi.h>
const char* ssid = "uPesy_AP"; // SSID Name
const char* password = "super_strong_password"; // SSID Password - Set to NULL to
have an open AP
const int channel = 10; // WiFi Channel
number between 1 and 13
const bool hide_SSID = false; // To disable SSID broadcast
-> SSID will not appear in a basic WiFi scan
const int max_connection = 2; // Maximum
simultaneous connected clients on the AP
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating
AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password, channel, hide_SSID, max_connection);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Une fois connecté au réseau Wi-Fi depuis un
appareil, on peut ensuite pinger le routeur, c’est-à-dire ici l’ESP32 dans
l’invite de commande Windows avec :
ping 192.168.4.1

Ping de l’ESP32 depuis le terminal Windows
Nous avons notre propre routeur Wi-Fi local sur un
ESP32 sur lequel on peut ajouter plusieurs appareils (ordinateur, téléphone,
ESP32, Raspberry Pi …)
Configuration avancée
L’adresse IP 192.168.4.1 du point d’accès peut être modifiée, au même titre que l’adresse IP
de la passerelle et du masque sous réseau. Il suffit d’utiliser la
fonction WiFi.softAPConfig() avant de
créer le point d’accès via la fonction WiFi.softAP . La fonction WiFi.softAPConfig(local_ip,
gateway, subnet) prend les paramètres suivant :
- IPAddress local_ip : L’adresse IP locale
de notre point d’accès dans le réseau qu’il va créer
- IPAddress gateway : L’adresse IP de la passerelle,
dans notre cas, cela sera la même que l’IP locale.
- subnet : Le masque de sous réseau du réseau créé par l’ESP32, en
général 255.255.255.0
Par exemple, pour avoir un point d’accès Wi-Fi,
dont son IP locale est 192.168.0.1 avec un masque de sous-réseau de 255.255.255.0 , le code serait de la forme :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = "super_strong_password";
IPAddress local_ip(192,168,0,1);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating
AP");
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip, gateway, subnet);
WiFi.softAP(ssid, password);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Sortie du terminal
[*] Creating AP
[+] AP Created with IP Gateway
192.168.0.1
Exemples d’application
Voici un exemple qui permet d’afficher une liste
des appareils connectés sur l’ESP32 avec leurs adresses MAC et leur adresse IP
locale. C’est une version simplifiée de celle que l’on peut avoir sur une box
Wi-Fi classique.
#include <WiFi.h>
#include "esp_wifi.h"
const char* ssid = "uPesy_AP"; // SSID Name
const char* password = "super_strong_password"; // SSID Password - Set to NULL to
have an open AP
const int channel = 10; // WiFi Channel
number between 1 and 13
const bool hide_SSID = false; // To disable SSID
broadcast -> SSID will not appear in a basic WiFi scan
const int max_connection = 2; // Maximum
simultaneous connected clients on the AP
void display_connected_devices()
{
wifi_sta_list_t wifi_sta_list;
tcpip_adapter_sta_list_t adapter_sta_list;
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
if (adapter_sta_list.num > 0)
Serial.println("-----------");
for (uint8_t i = 0; i < adapter_sta_list.num; i++)
{
tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
Serial.print((String)"[+] Device
" + i + " | MAC :
");
Serial.printf("%02X:%02X:%02X:%02X:%02X:%02X", station.mac[0], station.mac[1], station.mac[2], station.mac[3], station.mac[4], station.mac[5]);
Serial.println((String) " | IP " + ip4addr_ntoa(&(station.ip)));
}
}
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating
AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password, channel, hide_SSID, max_connection);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop()
{
display_connected_devices();
delay(5000);
}
Sortie du terminal
[+] Device 0 | MAC :
44:E2:42:08:D7:11 | IP 192.168.4.2
[+] Device 1 | MAC :
00:0A:F7:42:42:42 | IP 192.168.4.3
-----------
[+] Device 0 | MAC : 44:E2:42:08:D7:11
| IP 192.168.4.2
[+] Device 1 | MAC :
00:0A:F7:42:42:42 | IP 192.168.4.3
On pourrait aussi empêcher certains appareils de se
connecter en filtrant les adresses MAC. Par exemple autoriser uniquement les
ESP32 à se connecter dessus. En effet, on peut utiliser la fonction esp_wifi_deauth_sta(int
device_id) en précisant le numéro de l’appareil que l’on
veut enlever.
Astuce
La première personne qui m’envoie un exemple de code qui permet de faire un
filtrage des adresses mac sur le routeur WiFi crée par l’ESP32 verra sa
solution proposée ici !
Utiliser le mode STATION et AP en même temps
Il est possible d’avoir l’ESP32 qui fonctionne avec
les modes STATION et AP en même temps. C’est-à-dire que l’ESP32 est connecté à
une box Wi-Fi classique (mode STATION) avec aussi un point d’accès Wi-Fi
d’activé (mode AP). Ce mode est appelé WIFI_AP_STA .
Note
Il y a une interface réseau distincte pour chacun des modes. Puisque les
interfaces sont séparées, elles ont chacune une adresse IP différente.

Utiliser le mode STATION et AP en même temps
Une des applications possibles est de pouvoir
relier à Internet le réseau Wi-Fi local crée par l’ESP32 en mode Soft AP.

Exemple possible d’utilisation des 2 modes en
simultané
Le code Arduino mélange à la fois la gestion du
mode STATION et du mode AP. Le code est relativement simple lorsqu’on utilise
déjà les 2 modes séparément :
- On utilise le mode Wi-Fi WIFI_AP_STA
- On crée notre point d’accès Wi-Fi local (Soft AP)
- Puis on se connecte à la box Wi-Fi classique
Voici un exemple qui permet d’avoir les 2 modes en
même temps :
#include <WiFi.h>
const char* wifi_network_ssid = "Lounge";
const char* wifi_network_password = "cupcakes";
const char *soft_ap_ssid = "uPesy_AP";
const char *soft_ap_password = NULL;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_AP_STA);
Serial.println("\n[*] Creating ESP32
AP");
WiFi.softAP(soft_ap_ssid, soft_ap_password);
Serial.print("[+]
AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
WiFi.begin(wifi_network_ssid, wifi_network_password);
Serial.println("\n[*] Connecting to
WiFi Network");
while(WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(100);
}
Serial.print("\n[+] Connected to
the WiFi network with local IP : ");
Serial.println(WiFi.localIP());
}
void loop() {}
Sortie du terminal
[*] Creating ESP32 AP
[+] AP Created with IP Gateway
192.168.4.1
[*] Connecting to WiFi Network
.............................................................
[+] Connected to the WiFi network
with local IP : 192.168.85.37
Important
Il ne faut pas se tromper dans les identifiants :
- wifi_network correspond aux identifiants de la box Wi-Fi classique (Orange,
SFR, Free …)
- soft_ap correspond au identifiants du point d’accès que l’on va créer
avec l’ESP32. Il faudra rentrer ce mot de passe sur les appareils qui
voudront se connecter sur l’ESP32.