ESP32 OTA : téléverser son code en Wi-Fi sans câble (ArduinoOTA)
ESP32 OTA : téléverse ton code en Wi-Fi sans câble USB. Port réseau ArduinoOTA, page web ElegantOTA, mot de passe, schéma de partition et envois coupés.
L'OTA de l'ESP32 (Over-The-Air, mise à jour "par les airs") consiste à téléverser un nouveau code sur ta carte par Wi-Fi, sans brancher de câble USB. Imagine un capteur fixé au plafond, un contrôleur d'arrosage dans le jardin ou une carte relais cachée dans un tableau électrique : au lieu de sortir l'escabeau, démonter la carte et la brancher à l'ordinateur pour chaque petite correction, tu envoies la nouvelle version depuis l'Arduino IDE ou le navigateur en quelques secondes. La carte écrit le nouveau programme dans sa mémoire en arrière-plan, le vérifie et redémarre toute seule.
Dans ce guide, tu vas apprendre pas à pas comment l'OTA fonctionne à l'intérieur de l'ESP32, trois méthodes différentes (ArduinoOTA pour l'Arduino IDE, ElegantOTA pour le navigateur et HTTPUpdate pour récupérer depuis un serveur), comment choisir le bon schéma de partition, protéger l'envoi par mot de passe, ce qui se passe si le téléversement est interrompu et comment ne pas perdre l'OTA dans ton prochain sketch. Tout le code a été compilé et testé avec le core Arduino de l'ESP32.

Qu'est-ce que l'OTA de l'ESP32 et comment ça marche ?
La mémoire flash de l'ESP32 n'est pas un bloc unique ; elle est découpée en zones par une carte appelée table de partitions. Une table compatible OTA contient deux zones identiques pour le programme : app0 (ota_0) et app1 (ota_1). Pendant que la carte tourne depuis l'une, le nouveau programme est écrit dans l'autre. Une petite partition otadata retient quelle zone sera lancée au prochain démarrage. Ainsi, le programme en cours n'est jamais touché pendant l'envoi, et la carte n'abandonne pas l'ancien programme tant que le nouveau code n'est pas entièrement écrit et vérifié.
- Le nouveau programme (le fichier .bin compilé) arrive sur la carte par Wi-Fi, morceau par morceau.
- L'ESP32 écrit chaque morceau dans la partition de programme qui n'est pas utilisée ; pendant ce temps, le code actuel continue son travail.
- Une fois le fichier complet reçu, l'en-tête de l'image et sa somme de contrôle sont vérifiés ; un fichier corrompu ou incomplet est refusé.
- Si la vérification réussit, otadata est mis à jour : la nouvelle partition sera lancée au prochain démarrage.
- La carte redémarre avec le nouveau programme. La mise à jour suivante ira dans l'autre partition ; les deux zones sont utilisées à tour de rôle.
| Méthode | D'où envoies-tu le code ? | Idéal pour | Bibliothèque supplémentaire |
|---|---|---|---|
| ArduinoOTA | Depuis le port réseau de l'Arduino IDE | Développer à ton bureau, sur le même réseau | Aucune (fournie avec le core) |
| ElegantOTA | En choisissant un .bin sur la page /update du navigateur | Faire mettre à jour quelqu'un sans IDE, envoyer depuis un téléphone | ElegantOTA |
| HTTPUpdate | La carte télécharge elle-même un .bin sur un serveur | Beaucoup d'appareils, appareils distants, mises à jour automatiques | Aucune (fournie avec le core) |
Schéma de partition (partition scheme) et taille de la flash
C'est la condition de l'OTA la plus souvent oubliée : il faut une deuxième zone libre pour y écrire le nouveau programme. C'est pourquoi le plus gros programme que tu peux envoyer en OTA est plus petit que la moitié de la flash. Tu choisis la table de partitions dans l'Arduino IDE via Outils > Partition Scheme. Sur les cartes ESP32 DevKit courantes avec 4 Mo de flash (ESP32 Dev Module), les options sont :
| Partition Scheme | Zone programme | OTA | Système de fichiers (SPIFFS/LittleFS) |
|---|---|---|---|
| Default 4MB with spiffs | 2 × 1,25 Mo (1 310 720 octets) | Oui | 1,375 Mo |
| Minimal SPIFFS (1.9MB APP with OTA) | 2 × 1,875 Mo (1 966 080 octets) | Oui | 128 Ko |
| No OTA (2MB APP/2MB SPIFFS) | 1 × 2 Mo | Non | 1,875 Mo |
| Huge APP (3MB No OTA/1MB SPIFFS) | 1 × 3 Mo | Non | 896 Ko |
| Minimal (1.3MB APP/700KB SPIFFS) | 1 × 1,25 Mo (pour cartes à 2 Mo de flash) | Non | 640 Ko |
La place occupée par ton programme apparaît dans la sortie de compilation : notre premier exemple avec Wi-Fi et ArduinoOTA affiche "Sketch uses 758685 bytes (57%) ... Maximum is 1310720 bytes". Ce maximum correspond à la taille d'une seule zone programme du schéma choisi. Si l'occupation dépasse 90 %, attends-toi à passer bientôt à Minimal SPIFFS. Autre règle importante : la table de partitions ne peut pas être modifiée en OTA. Si tu as changé de schéma, ce téléversement doit se faire en USB ; les mises à jour OTA suivantes fonctionneront avec la nouvelle table. Sur les cartes à 8 Mo ou 16 Mo de flash (comme beaucoup de modèles ESP32-S3), choisir la bonne taille dans le menu Flash Size te donne des zones OTA bien plus grandes.
Pour voir depuis quelle partition ta carte tourne réellement et combien de place reste pour l'OTA, téléverse le petit sketch ci-dessous. Il ne demande aucune bibliothèque et utilise directement les fonctions OTA d'ESP-IDF :
1#include <esp_ota_ops.h>
2
3void setup() {
4 Serial.begin(115200);
5 delay(1000);
6 const esp_partition_t* running = esp_ota_get_running_partition();
7 const esp_partition_t* next = esp_ota_get_next_update_partition(NULL);
8
9 Serial.printf("Flash boyutu / Flash size: %u KB\n", ESP.getFlashChipSize() / 1024);
10 Serial.printf("Program boyutu / Sketch size: %u KB\n", ESP.getSketchSize() / 1024);
11 Serial.printf("OTA icin bos alan / Free space for OTA: %u KB\n", ESP.getFreeSketchSpace() / 1024);
12 Serial.printf("Calisan bolum / Running partition: %s (0x%06x)\n", running->label, running->address);
13 if (next != NULL) {
14 Serial.printf("Siradaki OTA bolumu / Next OTA partition: %s (0x%06x)\n", next->label, next->address);
15 } else {
16 Serial.println("OTA bolumu yok: bolum tablosunu degistir / No OTA partition: change the partition scheme");
17 }
18}
19
20void loop() {
21}Avec le schéma par défaut, après le premier téléversement USB la sortie indique "Running partition: app0 (0x010000)" et "Next OTA partition: app1 (0x150000)". Si tu relances le code après une mise à jour OTA, tu verras qu'il tourne maintenant depuis app1. La valeur de ESP.getFreeSketchSpace() donne la taille du plus gros programme que tu peux envoyer en OTA ; si ton nouveau .bin est plus gros, la mise à jour ne démarre pas.
Méthode 1 : téléversement sans fil depuis l'Arduino IDE avec ArduinoOTA
La bibliothèque ArduinoOTA est fournie avec le core ESP32, rien à installer. Dès que la carte rejoint le réseau, elle s'annonce via mDNS ; l'Arduino IDE la détecte et ajoute un port réseau au menu Port. Quand tu cliques sur Téléverser, l'IDE envoie le programme par ce port réseau au lieu de l'USB. Sur l'ESP32, le service OTA écoute par défaut le port 3232. Le sketch suivant se connecte au Wi-Fi, lance l'OTA avec un mot de passe et fait clignoter la LED intégrée comme preuve :
1#include <WiFi.h>
2#include <ArduinoOTA.h>
3
4const char* WIFI_SSID = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
5const char* WIFI_PASS = "AgSifresi"; // Wi-Fi şifren / your Wi-Fi password
6const int LED_PIN = 2; // çoğu DevKit'te dahili LED / onboard LED on most DevKits
7
8unsigned long lastBlink = 0;
9
10void setup() {
11 Serial.begin(115200);
12 pinMode(LED_PIN, OUTPUT);
13
14 WiFi.mode(WIFI_STA);
15 WiFi.begin(WIFI_SSID, WIFI_PASS);
16 while (WiFi.status() != WL_CONNECTED) { // bağlanana kadar bekle / wait until connected
17 delay(500);
18 Serial.print(".");
19 }
20 Serial.println();
21 Serial.print("IP: ");
22 Serial.println(WiFi.localIP());
23
24 ArduinoOTA.setHostname("bluegrays-esp32"); // IDE'de görünen ad / name shown in the IDE
25 ArduinoOTA.setPassword("ota1234"); // yükleme parolası / upload password
26
27 ArduinoOTA.onStart([]() {
28 // Güncelleme başlıyor: motorları, röleleri güvenli konuma al / update starting: put motors and relays in a safe state
29 String type = (ArduinoOTA.getCommand() == U_FLASH) ? "program" : "dosya sistemi / filesystem";
30 Serial.println("OTA basladi / started: " + type);
31 });
32 ArduinoOTA.onEnd([]() {
33 Serial.println("\nOTA bitti, yeniden baslatiliyor / done, rebooting");
34 });
35 ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
36 Serial.printf("Ilerleme / Progress: %u%%\r", progress * 100 / total);
37 });
38 ArduinoOTA.onError([](ota_error_t error) {
39 Serial.printf("Hata / Error[%u]: ", error);
40 if (error == OTA_AUTH_ERROR) Serial.println("parola / auth failed");
41 else if (error == OTA_BEGIN_ERROR) Serial.println("baslatilamadi, yer yok / begin failed, no space");
42 else if (error == OTA_CONNECT_ERROR) Serial.println("baglanti / connect failed");
43 else if (error == OTA_RECEIVE_ERROR) Serial.println("veri alinamadi / receive failed");
44 else if (error == OTA_END_ERROR) Serial.println("bitirilemedi / end failed");
45 });
46
47 ArduinoOTA.begin(); // OTA hizmetini başlat / start the OTA service
48}
49
50void loop() {
51 ArduinoOTA.handle(); // her turda çağır, unutma / call on every pass, never forget
52
53 // delay() yerine millis(): OTA isteklerini kaçırmamak için / millis() instead of delay() so OTA requests aren't missed
54 if (millis() - lastBlink >= 500) {
55 lastBlink = millis();
56 digitalWrite(LED_PIN, !digitalRead(LED_PIN));
57 }
58}| Ligne | À quoi sert-elle ? |
|---|---|
| ArduinoOTA.setHostname("bluegrays-esp32") | Le nom affiché dans la liste des ports de l'IDE et sur le réseau. Si tu as plusieurs cartes, donne un nom différent à chacune. |
| ArduinoOTA.setPassword("ota1234") | Sans mot de passe, n'importe qui sur ton réseau peut téléverser du code sur ta carte. L'IDE demande ce mot de passe avant l'envoi. |
| onStart / onEnd | S'exécutent au début et à la fin de la mise à jour. L'endroit idéal pour arrêter les moteurs, couper les relais ou afficher "Mise à jour" sur un écran. |
| onProgress | Donne le pourcentage ; tu peux dessiner une barre de progression sur un LCD ou un OLED. |
| onError | Indique le type d'erreur : mot de passe, manque de place, connexion, réception ou finalisation. |
| ArduinoOTA.handle() | Vérifie les requêtes OTA entrantes. Si elle n'est pas appelée souvent dans loop(), la carte ne peut pas répondre à l'IDE. |
Pas à pas : ton premier téléversement OTA
- Modifie les valeurs WIFI_SSID et WIFI_PASS du code pour ton réseau. L'ESP32 ne se connecte qu'aux réseaux 2,4 GHz.
- Dans le menu Outils, choisis ta carte (par ex. ESP32 Dev Module) et un Partition Scheme avec OTA (Default ou Minimal SPIFFS).
- Fais le premier téléversement avec le câble USB. C'est obligatoire, car la carte n'a pas encore de code OTA.
- Ouvre le Moniteur série à 115200 bauds et note l'adresse IP affichée par la carte.
- Débranche le câble USB et, si tu veux, alimente la carte avec une autre source. Après 10 à 20 secondes, une ligne comme "bluegrays-esp32 at 192.168.1.x" apparaît sous ports réseau dans Outils > Port ; sélectionne-la.
- Change la vitesse de la LED dans le code de 500 à 100 et clique sur Téléverser. Quand l'IDE demande le mot de passe, tape "ota1234".
- Dans la fenêtre de sortie, tu verras le pourcentage d'avancement puis une ligne comme "Done" ou "Result: OK". La carte redémarre et la LED clignote maintenant vite.
Une limite à connaître : le port réseau sert uniquement au téléversement, le Moniteur série ne fonctionne pas sans fil. Pour voir les messages de la carte, rebranche l'USB ou affiche l'état sur une page web, un écran ou via des messages MQTT. Quand tu développes à ton bureau, tu peux aussi laisser la carte en USB tout en téléversant par le réseau ; tu as ainsi des envois rapides et le Moniteur série en même temps.
Protection par mot de passe et sécurité
Une carte avec le service OTA ouvert est une porte par laquelle n'importe qui sur ton réseau peut téléverser du code. Dans ArduinoOTA, setPassword() garde le mot de passe en clair dans le code ; si tu partages ton code, tu peux fournir le hachage MD5 du mot de passe avec setPasswordHash(), ainsi le mot de passe lui-même n'apparaît pas dans le source. ElegantOTA protège la page /update par un identifiant et un mot de passe (HTTP Basic Auth).
- Donne à chaque appareil un mot de passe différent et difficile à deviner : des valeurs comme "1234" ou "admin" sont les premières essayées.
- N'expose pas la carte sur Internet : ouvrir l'OTA ou la page /update vers l'extérieur avec une redirection de port sur la box est un vrai risque ; ces méthodes passent par du HTTP non chiffré.
- Utilise HTTPUpdate pour les appareils distants : comme c'est la carte qui demande la mise à jour, une connexion sortante suffit ; si tu télécharges via Internet, préfère HTTPS avec WiFiClientSecure.
- Passe dans un état sûr pendant la mise à jour : dans onStart, arrête les moteurs et coupe les relais de chauffage et de pompe. Le redémarrage prend quelques secondes et les broches peuvent rester indéfinies pendant ce temps.
Méthode 2 : envoyer un .bin depuis le navigateur avec ElegantOTA
ElegantOTA ajoute une jolie page /update au serveur web qui tourne sur l'ESP32. Tu ouvres cette page depuis ton téléphone ou n'importe quel ordinateur sans Arduino IDE, tu choisis le fichier .bin compilé et tu l'envoies ; la barre de progression s'affiche dans le navigateur. C'est la méthode la plus pratique quand tu confies l'appareil à quelqu'un d'autre ou que tu le mets à jour sur place.
- Dans l'Arduino IDE, ouvre le Gestionnaire de bibliothèques, cherche ElegantOTA (Ayush Sharma) et installe-la.
- Modifie le code ci-dessous et téléverse-le la première fois en USB.
- Ouvre dans ton navigateur l'adresse affichée dans le Moniteur série (par ex. http://192.168.1.42/update) et connecte-toi avec l'identifiant "admin" et le mot de passe "ota1234".
- Laisse le mode Firmware sélectionné et glisse-dépose le fichier .bin ; à la fin de l'envoi, la carte redémarre toute seule.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <ElegantOTA.h>
4
5const char* WIFI_SSID = "AgAdi"; // Wi-Fi adın / your Wi-Fi name
6const char* WIFI_PASS = "AgSifresi"; // Wi-Fi şifren / your Wi-Fi password
7
8WebServer server(80);
9unsigned long otaProgressMillis = 0;
10
11void onOTAStart() {
12 Serial.println("OTA basladi / OTA started"); // röleleri kapat / switch relays off
13}
14
15void onOTAProgress(size_t current, size_t final) {
16 if (millis() - otaProgressMillis > 1000) { // saniyede bir yaz / print once per second
17 otaProgressMillis = millis();
18 Serial.printf("%u / %u bayt / bytes\n", current, final);
19 }
20}
21
22void onOTAEnd(bool success) {
23 Serial.println(success ? "OTA basarili / OTA successful" : "OTA hatasi / OTA failed");
24}
25
26void setup() {
27 Serial.begin(115200);
28 WiFi.mode(WIFI_STA);
29 WiFi.begin(WIFI_SSID, WIFI_PASS);
30 while (WiFi.status() != WL_CONNECTED) {
31 delay(500);
32 Serial.print(".");
33 }
34 Serial.println();
35 Serial.print("Adres / Address: http://");
36 Serial.print(WiFi.localIP());
37 Serial.println("/update");
38
39 server.on("/", []() {
40 server.send(200, "text/plain", "BlueGrays ESP32 - surum / version 1.0");
41 });
42
43 ElegantOTA.begin(&server, "admin", "ota1234"); // /update sayfası + kullanıcı/parola / /update page + user/password
44 ElegantOTA.onStart(onOTAStart);
45 ElegantOTA.onProgress(onOTAProgress);
46 ElegantOTA.onEnd(onOTAEnd);
47
48 server.begin();
49}
50
51void loop() {
52 server.handleClient(); // web isteklerini işle / handle web requests
53 ElegantOTA.loop(); // başarılı yüklemeden sonra yeniden başlatır / reboots after a successful upload
54}Par défaut, ElegantOTA fonctionne avec la classe synchrone WebServer fournie avec le core ; les appels server.handleClient() et ElegantOTA.loop() dans loop() sont donc indispensables. Si ton projet utilise déjà ESPAsyncWebServer, tu peux mettre l'option ELEGANTOTA_USE_ASYNC_WEBSERVER de la bibliothèque à 1 et l'utiliser avec le serveur asynchrone ; nous expliquons la mise en place du serveur asynchrone dans l'article Serveur web asynchrone et WebSocket avec l'ESP32. Le mode Filesystem de la page met à jour l'image LittleFS ou SPIFFS (fichiers de la page web, fichiers de réglages) au lieu du programme.
Obtenir le fichier .bin : exporter le binaire compilé
Pour ElegantOTA et HTTPUpdate, il te faut le fichier du programme compilé. Dans l'Arduino IDE, lance Croquis > Exporter les binaires compilés (Sketch > Export Compiled Binary). L'IDE compile le programme et dépose plusieurs fichiers dans un dossier build à l'intérieur du dossier du sketch. Un seul convient à l'OTA :
| Fichier | Contenu | Utilisé en OTA ? |
|---|---|---|
| monprojet.ino.bin | L'application seule (ton programme) | Oui, c'est le fichier à envoyer |
| monprojet.ino.bootloader.bin | Bootloader (chargeur de démarrage) | Non |
| monprojet.ino.partitions.bin | Table de partitions | Non |
| monprojet.ino.merged.bin (core 3.x) | Bootloader, table et programme réunis | Non, il ne s'écrit qu'en USB à l'adresse 0x0 |
Méthode 3 : mises à jour automatiques depuis un serveur avec HTTPUpdate
Imagine que tu as cinq cartes capteurs réparties dans la maison. Au lieu de les mettre à jour une par une depuis l'IDE, tu déposes le nouveau .bin sur un serveur et les cartes le téléchargent elles-mêmes. La bibliothèque HTTPUpdate fournie avec le core ESP32 fait ça en une seule ligne. Dans l'exemple ci-dessous, la mise à jour démarre quand tu appuies sur le bouton BOOT (GPIO 0) de la carte :
1#include <WiFi.h>
2#include <HTTPUpdate.h>
3
4const char* WIFI_SSID = "AgAdi";
5const char* WIFI_PASS = "AgSifresi";
6// Bilgisayarındaki ya da sunucundaki .bin dosyası / the .bin file on your computer or server
7const char* FIRMWARE_URL = "http://192.168.1.50:8000/firmware.bin";
8const int BUTTON_PIN = 0; // karttaki BOOT butonu / the BOOT button on the board
9
10void setup() {
11 Serial.begin(115200);
12 pinMode(BUTTON_PIN, INPUT_PULLUP);
13 WiFi.begin(WIFI_SSID, WIFI_PASS);
14 while (WiFi.status() != WL_CONNECTED) delay(500);
15 Serial.println("Hazir: guncellemek icin BOOT'a bas / Ready: press BOOT to update");
16}
17
18void loop() {
19 if (digitalRead(BUTTON_PIN) == LOW) { // butona basıldı / button pressed
20 WiFiClient client;
21 httpUpdate.rebootOnUpdate(true); // başarılıysa yeniden başlat / reboot on success
22 t_httpUpdate_return ret = httpUpdate.update(client, FIRMWARE_URL);
23
24 switch (ret) {
25 case HTTP_UPDATE_FAILED:
26 Serial.printf("Hata / Error (%d): %s\n", httpUpdate.getLastError(),
27 httpUpdate.getLastErrorString().c_str());
28 break;
29 case HTTP_UPDATE_NO_UPDATES:
30 Serial.println("Guncelleme yok / No update");
31 break;
32 case HTTP_UPDATE_OK:
33 Serial.println("Tamam / OK"); // buraya genelde gelinmez, kart yeniden başlar / usually not reached, the board reboots
34 break;
35 }
36 delay(1000);
37 }
38}Pour essayer, place le .bin dans un dossier de ton ordinateur sous le nom firmware.bin et lance python3 -m http.server 8000 dans ce dossier ; remplace l'adresse IP du code par l'IP locale de ton ordinateur. En usage réel, tu remplaces le bouton par une minuterie : par exemple, une fois par heure, la carte lit un petit fichier "version.txt" et, si le numéro de version du serveur est plus grand que le sien, elle lance la mise à jour. Ainsi, elle ne tombe pas non plus dans une boucle où elle télécharge le même fichier et redémarre sans fin.
Que se passe-t-il si la connexion coupe pendant l'OTA ?
Réponse courte : ta carte ne sera pas briquée. Comme le nouveau programme est écrit dans la partition inutilisée et que la partition de démarrage ne change qu'après vérification du fichier complet, un envoi interrompu laisse la carte tourner avec l'ancien programme. Tu verras "Error Uploading" dans l'IDE, OTA_RECEIVE_ERROR avec ArduinoOTA ou un échec avec ElegantOTA ; règle le problème et recommence l'envoi. Si le courant est coupé en plein envoi, c'est pareil : la carte démarre sur l'ancien programme. Le seul vrai risque, c'est un nouveau programme défectueux : si tu envoies un programme qui ne se connecte pas au Wi-Fi ou qui ne contient pas le code OTA, il te faudra le câble pour la prochaine mise à jour.
- Signal Wi-Fi faible : si l'envoi bloque vers 30 à 60 %, rapproche la carte de la box ou utilise un module avec antenne externe. Si WiFi.RSSI() dans le Moniteur série est pire que -75 dBm, attends-toi à des coupures ; plus de détails dans L'ESP32 ne se connecte pas au Wi-Fi.
- Alimentation insuffisante : l'écriture en flash et l'émission Wi-Fi tirent du courant en même temps. Un port USB faible ou un câble fin peuvent faire redémarrer la carte pendant l'envoi ; cela apparaît comme une erreur de brownout. Utilise une alimentation 5 V solide capable de fournir au moins 500 mA.
- Longues attentes dans loop() : des pauses comme delay(5000) retardent l'appel à handle() et l'IDE affiche "No response from the ESP". Gère le temps avec millis().
- Pare-feu : avec ArduinoOTA, au début de l'envoi, l'ESP32 se reconnecte à ton ordinateur. Si le pare-feu Windows ou un antivirus bloque cette connexion entrante, l'envoi échoue tout de suite ; autorise les réseaux privés dans la fenêtre qui s'affiche au premier essai.
Garder l'OTA dans chaque nouveau sketch
La déception la plus fréquente avec l'OTA est celle-ci : tu envoies en OTA un projet complètement différent, ce projet ne contient pas de code ArduinoOTA, et la carte n'apparaît plus comme port réseau. Le nouveau programme remplace entièrement l'ancien ; l'OTA n'est pas quelque chose qui "reste sur la carte", chaque programme doit l'emporter avec lui. Pour ne pas remonter sur l'escabeau jusqu'à l'appareil du plafond, prends ces habitudes :
- Utilise un modèle : place la connexion Wi-Fi et les réglages ArduinoOTA dans une fonction séparée (par ex. setupOTA()) et commence chaque nouveau projet avec ce fichier.
- Mets l'appel à handle() tout en haut de loop() et ne laisse jamais dans loop() une boucle qui bloque longtemps.
- Reconnecte-toi si le Wi-Fi tombe : utilise WiFi.setAutoReconnect(true) ou vérifie régulièrement la connexion ; une carte sans connexion ne peut pas recevoir de mise à jour.
- Ajoute une fenêtre de maintenance aux projets en deep sleep : une carte endormie n'entend pas la requête OTA. Écris un mode qui attend l'OTA pendant 60 secondes avant de dormir si un bouton est appuyé au démarrage ou si un indicateur MQTT est arrivé. Pour les modes de veille, lis l'article ESP32 Deep Sleep.
- Teste d'abord sur une deuxième carte à ton bureau : avant d'envoyer vers l'appareil installé, fais tourner le même code sur une carte à côté de toi ; s'il se connecte au Wi-Fi et apparaît comme port réseau, l'envoi est sûr.
- Affiche un numéro de version : garde une constante FW_VERSION en haut du code et affiche-la sur la page web ou l'écran ; tu sauras toujours quelle version tourne sur quelle carte.
OTA sur ESP8266 et Raspberry Pi Pico W
Le code ArduinoOTA et ElegantOTA de ce guide fonctionne aussi, avec de petites modifications, sur les cartes ESP8266 (NodeMCU, Wemos D1 Mini) : on utilise ESP8266WiFi.h au lieu de WiFi.h, ESP8266WebServer au lieu de WebServer, et le port OTA est 8266. Sur les cartes ESP8266 à 4 Mo de flash, choisis dans le menu Flash Size une option qui laisse assez d'espace programme pour l'OTA. Sur le Raspberry Pi Pico W, le core arduino-pico prend en charge ArduinoOTA ; le nouveau programme y est d'abord téléchargé dans le système de fichiers LittleFS puis copié à sa place au démarrage. Sur le Pico W, il faut donc réserver dans le menu Flash Size un système de fichiers plus grand que ton programme. MicroPython n'a pas d'outil OTA tout prêt ; on peut écrire de petits scripts qui téléchargent et remplacent des fichiers .py par le réseau, mais ce n'est pas une mise à jour vérifiée à deux partitions comme sur l'ESP32.
Idées de projets avec l'OTA
- Capteur au plafond ou au mur : modifie les seuils d'une carte qui mesure température, humidité et mouvement sans toucher à un câble.
- Relais domotique : mets à jour en OTA les règles horaires de la carte relais du tableau électrique ; place les relais dans un état sûr dans onStart.
- Appareils Home Assistant : ajoute de nouvelles fonctions par le réseau à des capteurs reliés à Home Assistant via MQTT.
- Contrôleur d'arrosage du jardin : change les heures d'arrosage et le seuil d'humidité du sol sans ouvrir le boîtier étanche.
- Barre de progression sur LCD : affiche la valeur d'onProgress en pourcentage et en barre sur un LCD 16x2 ; le projet ESP32 OTA de BlueGrays fait exactement cela.
- Mise à jour d'une flotte : fais vérifier chaque nuit par plusieurs cartes, avec HTTPUpdate, si une nouvelle version est disponible sur le même serveur.
Erreurs fréquentes et solutions
| Symptôme | Cause probable | Solution |
|---|---|---|
| Pas de port réseau dans le menu Port | Carte sur un autre réseau, mDNS bloqué, le code n'appelle pas ArduinoOTA.begin() | Utilise le même réseau 2,4 GHz, redémarre l'IDE, vérifie que l'IP s'affiche dans le Moniteur série |
| "No response from the ESP" | Long delay() dans loop(), carte occupée ou pare-feu | Utilise millis() au lieu de delay(), autorise l'IDE dans le pare-feu |
| "Authentication Failed" | Mauvais mot de passe OTA | Saisis la valeur de setPassword du code ; si tu l'as oublié, téléverse une fois en USB |
| "Not Enough Space" / Begin Failed | Schéma Huge APP ou No OTA, le programme ne tient pas dans la deuxième zone | Choisis Minimal SPIFFS et téléverse une fois en USB ; allège le programme |
| L'envoi s'arrête à mi-chemin | Signal faible, chute de tension, connexion perdue | Rapproche la carte de la box, utilise une alimentation 5 V solide, réessaie ; l'ancien programme continue de tourner |
| La carte ne rejoint pas le réseau après l'envoi | Le nouveau code n'a ni Wi-Fi ni OTA, mauvais SSID | Corrige en USB ; désormais, commence chaque projet avec le modèle OTA |
| "Wrong Magic Byte" ou erreur d'activation dans ElegantOTA | merged.bin, bootloader.bin ou un fichier compilé pour une autre puce a été choisi | N'envoie que le fichier monprojet.ino.bin |
L'OTA est la clé pour sortir tes projets ESP32 du bureau et les installer pour de vrai : une fois bien configuré, corrections, nouvelles fonctions et changements de seuil arrivent sans fil en quelques secondes. Dans l'application BlueGrays, tu trouveras le projet ESP32 OTA Update (avec l'IP et la progression affichées sur un LCD) ainsi que les projets connexion Wi-Fi, Async Web Server, mDNS et NTP, chacun avec son schéma de câblage et son code pas à pas.
Questions fréquentes
Qu'est-ce que l'OTA de l'ESP32 ?
L'OTA (Over-The-Air) consiste à charger un nouveau programme sur l'ESP32 par Wi-Fi au lieu d'un câble USB. La carte écrit le nouveau code dans une partition programme libre, le vérifie et redémarre avec la nouvelle version. Le premier sketch compatible OTA doit être téléversé une fois en USB.
Pourquoi le port réseau de l'ESP32 n'apparaît-il pas dans l'Arduino IDE ?
Les causes les plus fréquentes : l'ordinateur et la carte sont sur des réseaux différents, un réseau invité isole les appareils, ou l'appel ArduinoOTA.begin() du code n'est jamais exécuté. Vérifie dans le Moniteur série que la carte a obtenu une IP, redémarre l'IDE et patiente quelques secondes.
Quel partition scheme choisir pour l'OTA de l'ESP32 ?
Sur les cartes à 4 Mo de flash, choisis Default (zone programme de 2 × 1,25 Mo) ou, si ton programme est gros, Minimal SPIFFS (2 × 1,875 Mo). Huge APP et No OTA n'ont pas de deuxième zone programme, l'OTA ne fonctionne donc pas avec eux. Le premier téléversement après un changement de schéma doit se faire en USB.
Une mise à jour OTA interrompue peut-elle briquer l'ESP32 ?
Non. Le nouveau programme est écrit dans une partition vide et la partition de démarrage ne change qu'une fois tout le fichier vérifié. Si la connexion ou le courant sont coupés, la carte démarre sur l'ancien programme et tu peux simplement relancer l'envoi.
Peut-on utiliser le Moniteur série pendant un téléversement OTA ?
Le port réseau ne sert qu'à téléverser du code ; le Moniteur série ne fonctionne pas sans fil. Pour voir les messages, tu peux laisser la carte branchée en USB ou afficher les informations sur une page web, un écran ou via MQTT.
Comment définir un mot de passe OTA sur l'ESP32 ?
Avec ArduinoOTA, appelle ArduinoOTA.setPassword("motdepasse") avant begin() ; l'IDE demande ce mot de passe avant l'envoi. Si tu ne veux pas qu'il apparaisse dans le code, fournis son hachage MD5 avec setPasswordHash(). Avec ElegantOTA, tu protèges la page avec begin(&server, "utilisateur", "motdepasse").
Projets à réaliser après cet article
Voir tous les projets
Mise à jour OTA de l'ESP32 — Installation sans fil du firmware (avec écran LCD)
Dans ce projet, vous allez apprendre à installer un nouveau firmware sur l'ESP32 via Wi-Fi, sans câble USB. Grâce à la bibliothèque ArduinoOTA, l'ESP32 devient visible sur le réseau et apparaît automatiquement sous le nom bluegrays-ota dans l'onglet « Network port » de l'IDE Arduino. La première installation s'effectue via USB, puis toutes les mises à jour se font sans fil — une fonctionnalité essentielle pour les appareils sur le terrain. L'écran LCD I2C affiche l'état du Wi-Fi, l'adresse I

Connexion Wi-Fi STA ESP32 (avec écran LCD)
Dans ce projet, nous connectons l'ESP32 au réseau Wi-Fi domestique en mode Station (STA) de manière sécurisée et tolérante aux pannes. Nous isolons SSID/mot de passe dans un fichier secrets.h pour empêcher leur fuite sur Git, mettons en place une reconnexion automatique, et affichons le niveau RSSI et l'adresse IP sur un écran LCD I2C. La LED intégrée sert d'indicateur d'état.

Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)
Dans ce projet, nous transformons l'ESP32 en un serveur web asynchrone que vous pouvez contrôler depuis votre téléphone ou votre ordinateur connecté au même réseau Wi-Fi. Grâce à la bibliothèque ESPAsyncWebServer, le serveur peut traiter plusieurs requêtes simultanément (contrairement au classique WebServer.h qui se bloque sur une seule requête). Depuis votre navigateur, vous pourrez vous connecter à l'adresse IP de l'ESP32, puis allumer et éteindre la LED co

ESP32 mDNS : accès à l'appareil via bluegrays-esp.local (avec écran LCD)
Dans ce projet, en ajoutant un service mDNS (Multicast DNS) à l'ESP32, nous permettons d'accéder à l'appareil via un nom d'hôte lisible, tel que bluegrays-esp.local, plutôt qu'à l'aide d'une adresse IP. Même si l'adresse IP attribuée par le DHCP venait à changer, vous pourrez toujours accéder à l'appareil sous le même nom. En exécutant également un petit serveur web sur l'appareil, nous envoyons des commandes de contrôle des LED depuis un navigateur via l'adresse http://bluegrays-esp.local/.

Compteur ESP32 WebSocket (2 boutons + écran LCD + affichage Web en temps réel)
Dans ce projet, deux boutons reliés à l'ESP32 (GPIO 5 incrémente, GPIO 4 décrémente) modifient un compteur. La valeur se met à jour instantanément sur un écran LCD I2C 16x2 et, grâce au support WebSocket d'ESPAsyncWebServer, dans tous les navigateurs connectés sans recharger la page. Au lieu du polling HTTP, une seule connexion persistante est utilisée et l'ESP32 envoie la nouvelle valeur à tous avec ws.textAll().

ESP32 : heure réelle depuis Internet via NTP
L'ESP32 se connecte au Wi-Fi et récupère l'heure réelle avec une précision de la milliseconde depuis des serveurs NTP (Network Time Protocol). Grâce à configTzTime(), le fuseau horaire de la Turquie (TRT, UTC+3) est appliqué automatiquement et le passage DST est géré via la chaîne POSIX TZ. L'heure est affichée sur le moniteur série et sur un écran LCD I2C en option. configTzTime() démarre le service SNTP ; des resynchronisations périodiques ont lieu tant que l'accès au réseau est disponible

ESP32 HTTPClient + API météo (avec écran LCD)
Dans ce projet, nous effectuons un appel REST à l'API météo (wttr.in) via Internet à l'aide de l'ESP32 et de la bibliothèque HTTPClient.h. À l’aide d’ArduinoJson v7, nous analysons la réponse JSON renvoyée et affichons les informations relatives à la ville, à la température, à l’humidité, à la météo et au vent sur un écran LCD I2C, en turc et en anglais. wttr.in est gratuit et ne nécessite pas de clé API : il suffit de saisir le nom d’une ville pour obtenir les conditions météo en temps réel d

Mode veille profonde de l'ESP32 — Économie de batterie (OLED + compteur RAM RTC)
Le mode « Deep Sleep » de l'ESP32 réduit la consommation de courant à environ 10 µA en désactivant le processeur et la plupart des périphériques, ce qui revêt une importance cruciale pour les appareils IoT fonctionnant sur batterie. Dans ce projet, nous utilisons trois sources de réveil différentes : une minuterie (timer, 15 s), une broche externe (EXT0 — bouton GPIO 33) et un capteur tactile (T0/GPIO 4). Les variables marquées avec RTC_DATA_ATTR sont conservées pendant le mode Deep Sleep — le
Autres articles
Application BlueGrays
Réalise ce montage pas à pas sur ton téléphone
Schéma, code et liste des composants sur un seul écran. Plus de 200 projets Arduino, ESP32 et Pico à réaliser.
Scanne avec ton téléphone
Pointe l’appareil photo vers le code : la boutique d’applications de ton téléphone s’ouvre.
ou ouvre la boutique

