Programmez votre ESP8266 via les airs ….

Introduction :

… Oui c’est possible … Traditionnellement pour flasher (programmer) un Arduino ou un board à base d’ESP8266 comme un NodeMCU ou un Wemos, il faut le relier à votre PC via un câble USB. Pour la mise au point initiale du sketch, ce n’est pas un problème, par contre une fois le montage installé à distance de votre PC, il n’est par forcement très pratique de le rapatrier a coté de votre PC pour mettre à jour le code … A fortiori si sous avez plusieurs objets connectés au cloud dans votre maison dont vous souhaitez mettre à jour le code …

Pour vous faciliter la vie, il y a une solution, elle s’appelle la programmation OTA (Other The Air) c’est à dire par l’intermédiaire du réseau WIFI. Elle permet simplement la programmation de votre ESP8266 ou de votre Arduino à distance depuis votre PC sans utiliser de câble USB !!! Il y a juste quelques contraintes très simples à respecter que nous allons voir dans cet article.

C’est parti …

Préparation IDE Arduino :

Si ce n’est pas déjà fait, installer dans l’IDE (Integrated Development Environment) Arduino les librairies ESP8266 comme indiqué dans les articles précédents sur l’ESP8266 (https://phmarduino.wordpress.com/2016/01/14/demarrer-avec-lesp8266/). Cela permet bien sur de programmer des ESP8266 embarqués dans des boards ou pas et surtout dans notre cas cela permet de bénéficier de la librairie ArduinoOTA qui est intégrée par défaut dans la librairie des cartes ESP8266.

Installation python :

Mon PC étant sous Windows, je commence par installer python (en version 2 obligatoirement) qui est un prérequis pour la programmation OTA, celle-ci utilisant un script python.

Pour cela, il faut se rendre à l’adresse suivante pour le télécharger https://www.python.org/downloads/

Une fois le fichier Windows msi d’installation téléchargé, il suffit de l’exécuter en double cliquant dessus :

Lors du setup qui est alors lancé, sélectionner l’option ci-dessous :

Initialisation NodeMCU pour OTA :

Avant de pouvoir débrancher le câble série et programmer l’ESP à distance via le WIFI, il faut initialiser l’ESP par exemple avec le script fourni dans les exemples mis à disposition par l’IDE Arduino à savoir ArduinoOTA/BasicOTA.

Vous retrouverez dans ce code quelques unes des principales méthodes OTA disponibles présentées ci-dessous :

  • ArduinoOTA.setHostname() :
    • Elle permet d’attribuer un nom à l’ESP8266. Si vous avez beaucoup d’objets sur votre réseau, il sera plus facile ainsi de l’identifier par son nom pour le sélectionner lors de la mise à jour via les airs que par un identifiant construit par défaut automatiquement à partir du numéro de série,
  • ArduinoOTA.setPort() :
    • Par défaut le port de communication est le 8266. Il n’est pas très utile de la changer sauf à ce qu’il soit déjà utilisé sur votre réseau local,
  • ArduinoOTA.onStart() :
    • Code à exécuter au démarrage de la mise à jour OTA, on peut par exemple aller une LED pour visualiser ainsi le début de la programmation par les airs,
  • ArduinoOTA.onEnd() :
    • Code à exécuter à la fin de la mise à jour OTA, et ici on peut éteindre la LED allumée précédemment pour visualiser la fin de la programmation par les airs,
  • ArduinoOTA.onProgress() :
    • Code à exécuter pendant la mise à jour OTA pour suivre l’avancement de la programmation par exemple,
  • ArduinoOTA. onError() :
    • Code à exécuter cas d’erreur OTA.

Pour plus de sécurité, il est possible d’exiger qu’un mot de passe soit demandé lors des mises à jour. Pour cela il suffit d’ajouter simplement l’instruction suivante à votre sketch :

  • ArduinoOTA.setPassword(« mon mot de passe »)

 

Pour ma part j’ai utilisé le script ci-dessous dérivé de l’exemple disponible dans l’IDE ArduinoBasicOTA dans lequel j’ai juste rajouté le clignotement de la LED bleue (Built In LED) présente sur mon board NodeMCU afin de faire des tests de mise à jour OTA avec un changement de la fréquence de clignotement dont la mise à jour est facile à vérifier comme on le verra par la suite :

/*
  Skecth : pm_basic_ota_nodemcu_53
  Description : Initialisation OTA NodeMCU 53
  Auteur : PHMARDUINO
  Création : 20 juillet 2018
  Derniere mise a jour : 
*/

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

// A remplacer par le nom et le mot de passe de votre wifi
const char* ssid = "votre nom de wifi";
const char* password = "votre mot de passe wifi";

void setup() {
  pinMode(2, OUTPUT);  // builtin led pour le NodeMCU cad GPIO02 ou D4
  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();
  }

  // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setHostname("phm_esp8266_NodeMCU");

  // No authentication by default
  //ArduinoOTA.setPassword("toto");

  ArduinoOTA.onStart([]() {
    Serial.println("Starting ....  ");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.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();
  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


 

Une fois le sketch téléversé, vous devriez voir un nouveau port de type « Réseau » apparaitre désormais dans l’IDE Arduino avec soit le nom par défaut soit le cas échéant le nom que vous avez indiqué dans votre sketch avec l’instruction ArduinoOTA.setHostname() :

Dans la pratique, j’ai un peu galéré pour que ce nouveau port apparaisse dans l’IDE Arduino… J’avais beau appuyer sur le bouton « Reset » de mon NodeMCU, redémarrer mon NodeMCU, l’IDE Arduino, toujours rien … Pour que le port apparaisse il a fallu que je redémarre complétement mon PC !!!

Première mise à jour « par les airs » :

Une fois votre ESP initialisé pour OTA, pour pouvoir garder la fonctionnalité de mise à jour via le WIFI après chaque téléversement, il faut obligatoirement pour cela ajouter systématiquement les instructions suivantes dans votre code :

  • Dans les déclarations :

#include <WiFiUdp.h>

#include <ArduinoOTA.h>

  • Dans la partie “setup” :

ArduinoOTA.setHostname(« monEsp »);        // on donne un nom a notre module

ArduinoOTA.begin();                                    // initialisation de l’OTA

  • Dans la partie “loop” :

ArduinoOTA.handle();

Pour vérifier le bon fonctionnement de la programmation “par les airs”, il faut débrancher l’ESP de votre PC et le brancher à distance de votre PC sur le secteur avec un adaptateur pour smartphone par exemple.

Pour mon test je réutilise le script utilisé précédemment pour l’initialisation de l’OTA dans lequel je vais juste changer la fréquence de clignotement.

Ensuite, il faut changer le port de programmation pour remplacer le port série par le port réseau qui apparait avec le nom que vous avez choisi dans votre programme ESP (avec ArduinoOTA.setHostname) ici phm_esp8266_NodeMCU :

Ensuite lancer le téléversement qui doit fonctionner sans câble série entre votre PC et l’ESP !!!

Pour ma part la première fois, j’ai eu un petit souci de firewall que j’ai réglé en ajoutant l’autorisation d’accès suivante pour Python :

En effet, la mise à jour des sketchs en OTA via le réseau local est effectuée à l’aide du programme Python epspota.py que l’on voit ci-dessous et qui ne doit donc pas être bloqué par le firewall pour pouvoir accéder à l’ESP via le WIFI.

Pour aller plus loin :

Nous avons vu que nous pouvions programmer à distance nos cartes à base d’ESP8266 en supprimant le raccordement au PC via un câble USB. Mais du coup on ne peut plus bénéficier du moniteur série pour afficher des messages dans la console série ce qui est souvent bien pratique quand même….

Alors est-ce qu’il existe une solution pour pallier ce problème ???? Et bien oui et ce que nous allons voir maintenant 🙂

En fait pour disposer d’un port série disponible “via les airs” il suffit d’ajouter les éléments de code ci-dessous dans votre sketch :

Dans les “déclarations” du sketch :

WiFiServer TelnetServer(23); // Declaration Serveur Telnet

WiFiClient TelnetClient;     // Declaration Client Telnet

Dans la partie “setup” (Initialisations) du sketch :

 // Demarrage serveur Telnet

 TelnetServer.begin();

 TelnetServer.setNoDelay(true);

Dans la partie “loop” (boucle) du sketch :

 // Si nouvelle connection client Telnet

 if (TelnetServer.hasClient()) {

   TelnetClient = TelnetServer.available();       

   TelnetClient.flush();  // Nettoyage du buffer en entree

   TelnetClient.println(« Bonjour, client Telnet detecte !!!!! »);             

   TelnetClient.println(« ———————————–« );

 }

 

 // Si client Telnet toujours connecte

 if (TelnetClient || TelnetClient.connected()) {

   TelnetClient.print(« Temps actuel : « );

   TelnetClient.println(millis());

 }

Vous trouverez ci-dessous un exemple de code complet intégrant ces morceaux de code :

/*
  Skecth : pm_ota_telnet_53
  Description : Terminal serie distant
  Auteur : PHMARDUINO
  Création : 21 juillet 2018
  Derniere mise a jour : 
*/

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
 
// A remplacer par le nom et le mot de passe de votre wifi
const char* ssid = "votre nom de wifi";
const char* password = "votre mot de passe wifi";
  
WiFiServer TelnetServer(23); // Declaration Serveur Telnet
WiFiClient TelnetClient;     // Declaration Client Telnet
 
void setup() {
  Serial.begin(9600);
  // Connection au reseau WIFI
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  // Demarrage serveur Telnet 
  TelnetServer.begin();
  TelnetServer.setNoDelay(true);
 
  // Demarrage OTA et postionnement du nom
  ArduinoOTA.setHostname("mon_esp8266_grenier_53"); 
  ArduinoOTA.begin();
}
 
void loop() {
  ArduinoOTA.handle(); // recherche connexion OTA 
    Serial.println(millis()); // Temps ecoule depuis le demarrage de la carte em ms
  
  // Si nouvelle connection client Telnet
  if (TelnetServer.hasClient()) {
    TelnetClient = TelnetServer.available();       
    TelnetClient.flush();  // Nettoyage du buffer en entree
    TelnetClient.println("Bonjour, client Telnet detecte ici !!!!!");             
    TelnetClient.println("*----------------------------------------*");
  }

  // Si client Telnet toujours connecte
  if (TelnetClient || TelnetClient.connected()) {
    TelnetClient.print("Temps actuel : ");
    TelnetClient.println(millis());
  }
    
  delay(2000);  // Delai de deux secondes
}

 

Une fois le code téléversé, pour faire un test de bon fonctionnement il suffit d’utiliser un terminal série comme putty par exemple.

Vous devez renseigner dans celui-ci l’adresse IP locale attribuée par votre box à votre montage, ici par exemple celle de mon NodeMCU à savoir 192.168.0.17 (C’est celle qui apparait dans la liste des ports de type Réseau dans l’IDE Arduino) :

Les résultats obtenus sont les suivants :

 

On voit que mon NodeMCU a bien détécté une demande de mon client telnet putty … et il affiche dans le terminal série « via les airs » le temps écoulé depuis le démarrage de la carte à chaque passage dans la boucle …

 

Et enfin pour terminer :

Dans un de mes sketchs de remontée de données dans le cloud ou j’avais mis en place la programmation OTA, j’avais à chaque tentative de mise à jour de mon sketch par les airs une erreur “No device, No anwser” qui à priori est due au Timeout par défaut trop court (10 secondes en ligne 96) dans le programme espota.py par rapport au delai de 20 secondes que j’ai mis dans mon sketch entre deux remontées de données dans le Cloud.

J’ai donc modifié le Timeout dans le programme python espota.py pour le porter à 30 secondes comme on peut le voir ci-dessous en ligne 96 :

Ensuite la mise à jour OTA a enfin recommencé à fonctionner normalement 🙂

Publicités

2 réflexions au sujet de « Programmez votre ESP8266 via les airs …. »

  1. Toutes mes excuses pour la manipulation erronée précédente. Je reprends …

    Bonjour.

    Tout d’abord merci pour votre blog qui, par rapport à d’autres traitant du même thème, à la particularité d’être très précis sur des points pratiques ou de détail qui nous « pourrissent » bien la vie lors des ajouts de fonctions ou des mises au point (c’est le cas de la question du timeout dans python …).

    Je pratique les mises à jour OTA depuis quelques semaines et celles-ci sont importantes pour moi car mes modules se trouvent souvent installés dans des endroits assez peu accessibles. Parlant de « mes modules », j’aborde le début de mon problème actuel : entre mes mises au point sur table et mes modules en service (les IP de chaque module sont fixes), mon IDE Arduino commence à perdre son latin dans les ports réseau. Ce faisant, il attribue dans sa liste des ports accessibles, des modules (nommés via l’instruction « ArduinoOTA.setHostname ») à une IP réseau utilisée sur un autre module. Ne pouvant ou ne sachant plus trouver le bon couple « nom de module / IP » dans les ports réseau de l’IDE, je ne peux plus faire les mises à jour OTA utiles.

    Est-il possible de « forcer manuellement » l’IDE à travailler sur un couple « nom / IP » ?

    Merci et bonne journée.

    J'aime

    1. Bonjour,
      Merci pour vos commentaires.
      Il s’agit peut-être d’un bug de l’IDE Arduino.
      Si vous n’avez pas la dernière version, il serait intéressant de faire un upgrade pour voir si le problème persiste.
      Je vais faire quelques essais pour voir si je rencontre le même problème.

      J'aime

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s