Une fonctionnalité très pratique dans le domaine des IoT est la possibilité de programmer un microcontrôleur connecté , comme un ESP32, via Wifi. Cette technique est appelée Transmission aérienne ou Over-The-Air (OTA) Programming.
Matériel
- NodeMCU ESP32
- Ordinateur
- Réseau WiFi
Principe de fonctionnement
En principe, un programme est téléversé sur le NodeMCU ESP32 par une connexion série avec le port USB. L’ordinateur communique le programme au microcontrôleur. Lorsque deux appareils sont connectés au même réseau Wifi, ils peuvent communiquer ensemble. On peut donc téléverser un code grâce au réseau Wifi sans avoir à se connecter à chaque microcontrôleur.
Il est aussi possible de téleverser un code sur le NodeMCU lorsqu’il est configuré comme Point d’Accès Wifi. Dans ce cas, l’ordinateur, utilisé pour la programmation, doit être connecté au réseau du NodeMCU. Le code complet est donné à la fin de ce tutoriel.
Ajouter le firmware ArduinoOTA
La librairie ArduinoOTA est disponible à l’installation du gestionnaire d’ESP32. Pour pourvoir mettre en place la programmation OTA, vous devez installer le firmware. Pour cela, vous pouvez utiliser l’exemple BasicOTA.ino disponible dans l’IDE Arduino.
Veillez à remplacer ssid et password par les identifiants de votre réseau WiFi.
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char* ssid = "*******"; const char* password = "********"; unsigned long previousMillis; void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] //ArduinoOTA.setHostname("esp3232"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); }
Veillez à noter l’adresse IP local de l’appareil (ici: 192.168.1.33).
Une fois ce code téléverser par voie série, vous serez en capacité de téléverser un code via Wifi. Appuyer sur le bouton RST ou EN de votre ESP et redémarrer l’IDE Arduino.
Modifier votre programme avant de le téléverser
Nous plaçons le code d’initialisation dans la fonction initOTA(). Il sera ensuite facile de la copier pour d’autre projet. Et nous allons rajouter un affichage sur le port série pour vérifier que le code a bien été modifié.
ATTENTION: Le code relatif à l’initialisation de ArduinoOTA doit être présent dans tous les codes que vous téléversez ou vous perdrez la possibilité de faire de la transmission aérienne.
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char* ssid = "******"; const char* password = "********"; unsigned long previousMillis; void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } initOTA(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); if (millis() - previousMillis >= 500) { previousMillis = millis(); Serial.println(F("Code has been update")); } } void initOTA() { // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] ArduinoOTA.setHostname("ESP32"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); }
Un fois votre code modifié, sous « Outil> Port », sélectionnez votre carte dans les ports réseau. (si le port réseau ne s’affiche pas voir chapitre suivant ci-dessous)
Vous pouvez alors téléverser votre code comme vous le feriez avec la communication série.
Sélectionnez à nouveau le port série, puis ouvrez le moniteur série pour vérifier que le code a bien été modifié.
Si le Port Réseau ne s’affiche pas dans l’IDE Arduino
Si le port réseau n’est pas présent dans les options de l’IDE Arduino, il vous faudra effectué une petite manipulation. Vous devez vous rendre dans le Centre Réseau et Partage
Puis aller dans « Modifier les paramètres de la carte »
Cliquez droit sur votre réseau puis aller dans propriétés
Vous pouvez ensuite décocher l’option « Protocole Internet version 6 (TCP/IPv6) ».
Si vous retourner sur l’IDE Arduino après l’avoir redémarré, dans « Outil > Port » vous devriez voir l’option port réseau s’afficher.
Vous pouvez de nouveau cocher le protocole IPv6 un fois que votre port réseau est reconnu.
Bonus: Affichage de message série en OTA
La possibilité de téléverser un programme par Wifi est très appréciable mais, il est bon de noter, que l’on perd la capacité de debugger avec le moniteur série. Il est possible de créer une interface Web sur laquelle on peut afficher des informations provenant du NodeMCU ESP32.
Nous allons voir ici l’utilisation de la librairie RemoteDebug qui va nous permettre de nous connecter en telnet au microcontrôleur et récupérer les messages envoyés.
- Commencez par installer la librairie en téléchargeant le ZIP ou via le gestionnaire de bibliothèque.
- Créez un objet RemoteDebug Debug; après avoir inclus la librairie
- Initialisez le debug avec Debug.begin(« ESP32 »);
- Puis remplacer tout les Serial.print par Debug.print
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> #include <RemoteDebug.h> const char* ssid = "*******"; const char* password = "*******"; RemoteDebug Debug; unsigned long previousMillis; void setup() { Serial.begin(115200); Serial.println("Booting"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } // init remote debug Debug.begin("ESP32"); initOTA(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); Debug.handle(); if (millis() - previousMillis >= 500) { previousMillis = millis(); Debug.println(F("Code has been update")); } } void initOTA() { // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] ArduinoOTA.setHostname("ESP32"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); }
Pour visualiser les messages envoyer via RemoteDebug, nous allons utiliser le logciel PuTTy que nous avons vu plusieurs fois déjà. Pour cette application, nous allons configurer PuTTy en telnet en utilisant l’adresse IP récupérée sur le moniteur série.
Bonus 2: Programmation OTA en mode Access Point
Il est possible d’utiliser le réseau créer par le NodeMCU ESP32 en mode Access Point. Pour cela vous pouvez télecharger le code suivant via le port série. Vous devrez ensuite connecter votre ordinateur au réseau du NodeMCU pour pouvoir téleverser un nouveau code par Wifi.
#include <WiFi.h> #include <ESPmDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char *ssid = "AC-ESP32"; const char *passphrase = "123456789"; IPAddress local_IP(192,168,4,22); IPAddress gateway(192,168,4,9); IPAddress subnet(255,255,255,0); unsigned long previousMillis; void setup() { Serial.begin(115200); Serial.println("Booting"); //AP config Serial.print("Setting soft-AP configuration ... "); Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!"); Serial.print("Setting soft-AP ... "); Serial.println(WiFi.softAP(ssid,passphrase) ? "Ready" : "Failed!"); initOTA(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); if (millis() - previousMillis >= 500) { previousMillis = millis(); Serial.println(F("Code has been update via Wifi")); } } void initOTA() { // Port defaults to 3232 // ArduinoOTA.setPort(3232); // Hostname defaults to esp3232-[MAC] ArduinoOTA.setHostname("ESP32"); // No authentication by default // ArduinoOTA.setPassword("admin"); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); ArduinoOTA .onStart([]() { String type; if (ArduinoOTA.getCommand() == U_FLASH) type = "sketch"; else // U_SPIFFS type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() Serial.println("Start updating " + type); }) .onEnd([]() { Serial.println("\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); }
Bonjour, Merci pour ce tutoriel, 2 questions cependant :
– le code mdifié est bien dans le loop après le code ArduinoOTA.handle ?
– est-il possible d’envisager un ESP32 en Access Point pour utiliser ce code ? mon idée serait de creer un intranet en Wifi avec un ensemble de capteur et une ESP32 cam.
Bonjour,
– oui tout à fait
– Je ne l’ai pas testé mais je ne vois pas pourquoi cela ne fonctionnerai pas. Il faudra connecté l’ordinateur au réseau de l’ESP pour pouvoir téléverser le code
Bonjour, il est possible de téléverser en OTA en mode Access Point
Salut, merci beaucoup pour ce tutoriel, j’ai une préoccupation concernant la téléversement après la modification, il est possible que le code soi téléverser sans fil ?
Merci
Bonjour, c’est l’objectif du tutoriel de pouvoir téléverser le code sans fil.
quelle est votre préoccupation?
Merci de m’avoir répondu, je viens de comprendre là au dessus, je voulais aussi savoir si je peu aussi créer un point d’accès avec mon ESP32 et mon ordinateur est connecter à ce réseau que je créé donc je peux aussi téléverser ?
Merci
Bonjour,
Oui c’est tout à fait possible. J’ai mis à jour le tutoriel.
Bonjour,
Merci beaucoup
Bonjour, le port réseau n’afficher pas en mode accès point
merci de revoir ça !
Ça fonctionnait lorsque j’ai testé. As-tu connecté l’ordinateur au reseau de l’ESP? As-tu mis a jour les adresses IP pour qu’elles correspondent au réseau utilisé ?
Oui j’ai connecter l’ordinateur au réseau de l’esp, et là l’ordinateur à eu automatiquement l’adresse IP corresponds au réseau utilisé mais le port réseau n’afficher toujours pas
Merci !
Bonsoir ! Vous pouvez faire un tuto sur TTG0-call V1-3 ESP32 Module sans fil GPRS pour montre s’il peut se connecter directement à l’internet par la carte SIM sans passer par routeur !
Merci d’avance
Malheureusement, je n’ai pas ce module en stock.
Bonsoir
Ok, merci de m’avoir répondu
Alors pour programmer l’écran TFT RA 8875 avec un Esp32 comment pourrais-je faire ?
S’il vous plaît aide moi car certains bibliothèque ne répond pas
Merci et bonne soirée
Bonsoir,
vous pouvez essayer de modifier les librairies pour qu’elles soient compatibles avec un ESP32.
Sinon vous pouvez essayer cette version https://github.com/sumotoy/RA8875
bonjour
le réseau s’affiche bien , je trouve bien mon esp32 en port réseau
le 1er téleversement ok j’ai les même message que chez vous et mon adresse ip
mais quand je branche mon esp32 sur une batterie , et que je veux envoyer la modif .. j’ai cette erreur
« Le croquis utilise 812034 octets (25%) de l’espace de stockage de programmes. Le maximum est de 3145728 octets.
Les variables globales utilisent 42824 octets (13%) de mémoire dynamique, ce qui laisse 284856 octets pour les variables locales. Le maximum est de 327680 octets.
Sending invitation to 192.168.1.2 ………
Une erreur est survenue lors du transfert du croquis
.
19:38:53 [ERROR]: No response from the ESP »
Merci pour votre aide
Bonjour,
êtes-vous sur que l’ESP est bien alimenté?
peut-être faut-il définir une adresse IP fixe