ESP32. Comment se connecter au réseau WiFi local avec du code Arduino • Domotique et objets connectés à faire soi-même

Le kit de développement ESP-IDF pour ESP32 contient la classe WiFi qui offre tous les outils nécessaires pour se connecter au réseau WiFi. Contrairement à l’ESP8266, la librairie porte le même nom que la librairie d’origine Arduino. 

Le fonctionnement est identique à la librairie ESP8266WiFi dédiée aux ESP8266

Installer le SDK ESP-IDF pour ESP32 sur IDE Arduino et PlatformIO

La librairie WiFi est installée en même temps que le kit pour les cartes de développement ESP32 appelé ESP-IDF.

Si vous débutez avec les cartes de développement ESP32 vous devez d’abord installer le kit de développement ESP-IDF. Voici deux tutoriels pour débuter en fonction de votre éditeur de code

Suivez les instructions de ce tutoriel pour l’IDE Arduino

Et celui-ci pour PlatformIO (idéalement avec VSCode)

Différents modes de connexion WiFi disponibles

La librairie WiFi pour ESP32 propose plusieurs modes de connexion Wi-Fi. Le code source est disponible sur GitHub .

Station Le mode Station (STA) est utilisé pour connecter le module ESP32 à un point d’accès Wi-Fi. C’est le mode par défaut.

Point d’accès (Access Point) transforme l’ESP32 en point d’accès (AP), c’est à dire que d’autres appareils peuvent de connecter sur l’ESP32. Ce mode de fonctionnement est  aussi appelé point d’accès logiciel (soft-AP).

Attention, dans ce mode l’ESP32 n’est pas connecté à internet. Dans ce mode, on créé une page HTML qui permettra de saisir des paramètres de connexion à un réseau WiFi ou ce que l’on veut d’autre. C’est par exemple le mode utilisé par ESP Easy Mega.

On pourra utiliser ce mode dans différents cas

  • Pour développer des accessoires domotiques ou des objets connectés sans compiler “en dur” les paramètres de connexion au réseau WiFi. Pour faire ça, je vous conseille plutôt d’utiliser la librairie WiFiManager dont s’est la spécialité.
  • Echanger des données entre deux (ou plus) modules ESP32 sans avoir besoin d’un routeur WiFi.

Autres modes : client, serveur, UDP

Client n’est pas un mode de connexion au sens strict. On crée des clients qui peuvent accéder aux services fournis par un serveur afin d’envoyer, de recevoir et de traiter des données.

Server permet de démarrer un petit serveur Web sur l’ESP32

UDP permet d’envoyer et de recevoir des messages  UDP (User Datagram Protocol). L’UDP utilise un modèle de transmission simple «envoyer et oubliez» sans garantie de livraison, de commande ou de protection contre les doublons. En contrepartie, la transmission de données est ultra-rapide. On pourra par exemple utiliser l’UDP pour développer un télécommande WiFi pour piloter un drone, bras robotique, voiture RC.

Code Arduino pour connecter un ESP32 au réseau WiFi

Voici un exemple de code qui permet de se connecter au réseau WiFi local.

Avant de téléverser le code, remplacer l’identifiant du réseau Wi-Fi enter_your_ssid et le mot de passe enter_your_password dans le code

#include  

const char* ssid = "saisir_votre_identifiant_reseau";           
const char* password = "saisir_votre_mot_de_passe_reseau"; 

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.begin(ssid, password);

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {}

Comment fonctionne le code ?

L’utilisation de la librairie WiFi est ultra simple. Il suffit de connaître l’identifiant du réseau WiFi sur lequel on souhaite connecter le module ESP32 ainsi que le mot de passe. La méthode WiFi.begin() prend deux paramètres qui sont l’identifiant réseau et le mot de passe

WiFi.begin(ssid, password);

La méthode WiFi.status permet de connaître à tout moment l’état de la connexion. La méthode renvoie un code compris entre 0 et 6 auquel correspond une constante dont voici la signification

  • 0: WL_IDLE_STATUS lorsque le Wi-Fi est en train de changer d’état
  • 1: WL_NO_SSID_AVAIL si le SSID configuré ne peut pas être atteint
  • 3: WL_CONNECTED une fois la connexion établie
  • 4: WL_CONNECT_FAILED si le mot de passe est incorrect
  • 6: WL_DISCONNECTED si le module n’est pas configuré en mode station

Dans la plupart, il suffit de se connecter à la mise sous tension dans le setup()

while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
}

Remarques :

  • Ce code fonctionne également en sortie de veille.
  • Ce code ne prévoie pas la mise en veille du module si le réseau WiFi n’est pas disponible ce qui risque de drainer la batterie

Pour gérer correctement la re-connexion automatique en cas de perte de signal WiFi, je vous conseille de vous tourner vers la librairie WiFiManager qui gère automatiquement les re-connexions.

Attribuer une adresse IP fixe à un ESP32

Lorsqu’on développe un objet connecté au WiFi avec un ESP32, ESP8266 ou ESP-01 (ou n’importe quel autre micro-contrôleur d’ailleurs), il est beaucoup plus pratique d’attribuer une adresse IP fixe. On pourra ainsi toujours se connecter à l’objet sur le réseau local même en cas de changement de routeur ou de box internet.

Tout est expliqué en détail dans ce tutoriel.

Mettre en veille (deep-sleep) l’ESP32 si le réseau WiFi n’est pas disponible

Si votre projet nécessite absolument d’être connecté au réseau WiFi pour fonctionner, il est pas préférable de mettre l’ESP32 en veille et de tenter régulièrement de se reconnecter. De cette façon on ne drainera pas la batterie inutilement.

Créer un nouveau croquis et coller le code ci-dessous.

#include   
#include 

const char* ssid = "saisir_votre_identifiant_reseau";           
const char* password = "saisir_votre_mot_de_passe_reseau";  
#define wifi_max_try 10             // Nombre de tentative au resau WiFI
#define duration_deep_sleep 10      // sinon active le deep-sleep jusqu a la prochaine tentative de reconnexion

void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

void print_wifi_error(){
  switch(WiFi.status()) 
  {
    case WL_IDLE_STATUS : Serial.println("WL_IDLE_STATUS"); break;
    case WL_NO_SSID_AVAIL : Serial.println("WL_NO_SSID_AVAIL"); break;
    case WL_CONNECT_FAILED : Serial.println("WL_CONNECT_FAILED"); break;
    case WL_DISCONNECTED : Serial.println("WL_DISCONNECTED"); break;
    default : Serial.printf("No know WiFi error"); break;
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println();
  
  //Explique la raison du reveil de l ESP32
  print_wakeup_reason();
  
  // Tente une connexion au reseau WiFi
  WiFi.begin(ssid, password);

  Serial.print("Connecting");
  int count_try = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    count_try++;    // Incremente le compteur de tentative de connexion
    if ( count_try >= wifi_max_try ) {
      // On a depasse le nombre de tentatives 
      Serial.println("\n");
      Serial.println("Impossible to establish WiFi connexion");
      
      print_wifi_error();
      Serial.println("Sleep a little and retry later, bye");
      
      // On programme un reveil
      esp_sleep_enable_timer_wakeup(duration_deep_sleep * 1000000);
      // Et on met au lit le processeur 
      esp_deep_sleep_start();
    }
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
   
}

Contrairement à l’ESP8266, il n’y a aucun circuit particulier à prévoir pour mettre en sommeil le processeur. Différents modes de mise en veille sont disponibles. Tout est expliqué en détail dans cet article

Comment fonctionne ce code

On ajoute un compteur qui est incrémenté à chaque passage dans le while (ici toutes les 500ms)

int count_try = 0;

Dès que le compteur est égal (ou dépasse) au nombre de tentatives, on programme un réveil à l’aide de la méthode esp_sleep_enable_timer_wakeup(durée).

esp_sleep_enable_timer_wakeup(duration_deep_sleep * 1000000);

Et on demande au processeur de s’endormir (Zzzz)

esp_deep_sleep_start();

La méthode WiFi.status() du SDK ESP-IDF permet de connaître à tout moment l’état de la connexion WiFi

  • WL_IDLE_STATUS en cours de connexion
  • WL_CONNECTED la connexion est établie
  • WL_NO_SSID_AVAIL aucun point d’accès indiqué dans la liste n’est disponible
  • WL_CONNECT_FAILED échec de connexion. Probablement que le mot de passe est mauvais ou un filtrage par adresse MAC a été mis en place sur le routeur.
  • WL_DISCONNECTED déconnecté

Enfin, la méthode esp_sleep_get_wakeup_cause() permet de connaître la dernière cause de réveil à l’aide des constantes suivantes :

  • ESP_SLEEP_WAKEUP_TIMER Minuteur, timer
  • ESP_SLEEP_WAKEUP_TOUCHPAD touche tactile
  • ESP_SLEEP_WAKEUP_EXT0 ou ESP_SLEEP_WAKEUP_EXT1
  • ESP_SLEEP_WAKEUP_ULP réveillé par le co-processeur ULP
  • ESP_SLEEP_WAKEUP_GPIO réveillé par le GPIO
  • ESP_SLEEP_WAKEUP_UART réveillé par le port série

Pour cela, il suffit d’appeler quand c’est nécessaire la méthode print_wakeup_reason() pour connaître l’origine du réveil.

Librairie WiFiMulti, laisser l’ESP32 choisir son réseau WiFi

Pour terminer le tutoriel, la librairie WiFiMulti permet de définir plusieurs réseaux WiFi et laisse le choix à l’ESP32 de se connecter au réseau en fonction de la disponibilité et de la force du signal.

Voici un exemple de code pour tester la librairie WiFiMulti. Le fonctionnement est identique à celle de l’ESP8266.

#include 
#include 
#include 

WiFiMulti wifiMulti;

void setup()
{
    Serial.begin(115200);
    delay(10);

    wifiMulti.addAP("saisir_nom_reseau_1", "saisir_motdepasse_reseau_1");
    wifiMulti.addAP("saisir_nom_reseau_2", "saisir_motdepasse_reseau_2");

    Serial.println("Connecting Wifi...");
    if(wifiMulti.run() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }
}

void loop()
{
    if(wifiMulti.run() != WL_CONNECTED) {
        Serial.println("WiFi not connected!");
        delay(1000);
    }
}

Elle est très simple à utiliser. On commence par créer un objet wifiMulti.

WiFiMulti wifiMulti;

On ajoute les différents points d’accès dans une liste à l’aide de la classe wifiMulti.addAP()

wifiMulti.addAP("saisir_nom_reseau_1", "saisir_motdepasse_reseau_1");
wifiMulti.addAP("saisir_nom_reseau_2", "saisir_motdepasse_reseau_2");

Enfin, on ouvre la connexion avec la méthode wifimulti.run().

wifiMulti.run()

On dispose des mêmes clés pour tester le bon fonctionnement de la connexion :

  • WL_CONNECTED la connexion est établie
  • WL_NO_SSID_AVAIL aucun point d’accès indiqué dans la liste n’est disponible
  • WL_CONNECT_FAILED échec de connexion. Probablement que le mot de passe est mauvais ou un filtrage par adresse MAC a été mis en place sur le routeur.
  • WL_DISCONNECTED déconnecté

Projets et tutoriels

D’autres projets et tutoriels sur les objets connectés qui utilisent une connexion WiFi

Mises à jour

22/09/2020 Publication de l’article

English version

Avez-vous aimé cet article ?

[Total: 0 Moyenne: 0]