howto:arduino-esp:esp-now

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
Prochaine révisionLes deux révisions suivantes
howto:arduino-esp:esp-now [2021/10/09 15:33] – [Tester et aller plus loin] guillaumehowto:arduino-esp:esp-now [2021/10/12 09:51] – [Principe de communication] guillaume
Ligne 2: Ligne 2:
  
 ESP-NOW est un protocole d'échange de données entre **ESP-32** (ou ESP8266) que l'on peut programmer avec l'IDE Arduino. C'est un protocole développé par Espressif, le fabricant des puces ESP, et qui permet d'échanger de courts paquets de données directement et simplement. Il est possible de réaliser des échanges entre plusieurs ESP dans les deux sens (émission et réception) sans intermédiaire central (sans routeur).   ESP-NOW est un protocole d'échange de données entre **ESP-32** (ou ESP8266) que l'on peut programmer avec l'IDE Arduino. C'est un protocole développé par Espressif, le fabricant des puces ESP, et qui permet d'échanger de courts paquets de données directement et simplement. Il est possible de réaliser des échanges entre plusieurs ESP dans les deux sens (émission et réception) sans intermédiaire central (sans routeur).  
- 
-Ce qui va suivre s'inspire très fort de l'excellent article de **Random Nerd Tutorials**: [[https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/]]. 
- 
-{{:howto:arduino-esp:screenshot_20211009_152829.png|}} 
  
 ===== Le protocole ESP-NOW ===== ===== Le protocole ESP-NOW =====
-Tel qu'il est décrit sur le site d'Espressif, le protocole ESP-NOW permet d'échanger des paquets sans Wifi, s'approchant en cela du système utilisé par les objets connectés en 2.4Ghz (souris ou claviers sans fil, en particulier). L'appairage entre modules est nécessaire (nous verrons plus loin qu'il faut utiliser l'adresse MAC des ESP), mais une fois que cet appairage est réalisé la connexion s'effectue très rapidement, sans "handshake". Dis plus simplement, lorsque l'appairage est effectué, on peut éteindre ou redémarrer un module, la reconnexion sera automatique et immédiate. +Tel qu'il est décrit sur le site d'Espressif, le protocole ESP-NOW permet d'échanger des paquets sans routeur Wifi, s'approchant en cela du système utilisé par les objets connectés en 2.4Ghz (souris ou claviers sans fil, en particulier). L'appairage entre modules est nécessaire (nous verrons plus loin qu'il faut utiliser l'adresse MAC des ESP), mais une fois que cet appairage est réalisé la connexion s'effectue très rapidement, sans "handshake". Dis plus simplement, lorsque l'appairage est effectué, on peut éteindre ou redémarrer un module, la reconnexion sera automatique et immédiate. 
  
-Il est possible de réaliser un schéma ou un module central envoie des informations à de nombreux autres modules (//one to many//), ou au contraire de nombreux modules envoient à un module central (//many to one//), mais aussi un réseau maillé ou chaque module peut envoyer à tous les autres.+Il est possible de réaliser un schéma où un module central envoie des informations à de nombreux autres modules (//one to many//), ou au contraire de nombreux modules envoient à un module central (//many to one//), mais aussi un réseau maillé ou chaque module peut envoyer à tous les autres. Chaque module, au sein d'un réseau, peut-être à le fois émetteur //ET// récepteur
  
 Il est possible de chiffrer les communications, et de mélanger des communications chiffrées ou non dans un même réseau. Le nombre de modules doit rester en dessous de 10 lorsque l'on utilise le chiffrement et 20 lorsque l'on échange en clair.  Il est possible de chiffrer les communications, et de mélanger des communications chiffrées ou non dans un même réseau. Le nombre de modules doit rester en dessous de 10 lorsque l'on utilise le chiffrement et 20 lorsque l'on échange en clair. 
  
-Il n'est possible d'échanger que 250 octets au maximum à chaque envoi. Une fonction de rappel peut être envoyée pour confirmer la bonne réception. +Il n'est possible d'échanger que 250 octets au maximum à chaque envoi. Une fonction de rappel peut être déclenchée pour confirmer la bonne réception ou l'envoi des données
  
 ===== Connaître l'adresse MAC ===== ===== Connaître l'adresse MAC =====
Ligne 21: Ligne 17:
 Il est possible de changer de manière logicielle l'adresse MAC de l'ESP, mais cela ne survit pas à un reboot, il faut donc l'inclure dans le code exécuté à chaque fois (tuto [[https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/|ici]]). Il est possible de changer de manière logicielle l'adresse MAC de l'ESP, mais cela ne survit pas à un reboot, il faut donc l'inclure dans le code exécuté à chaque fois (tuto [[https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/|ici]]).
  
-Uploader le code suivant dans chaque ESP, noter soigneusement le résultat qui va s'afficher dans la console.+Téléverser le code suivant dans chaque ESP, et noter soigneusement le résultat qui va s'afficher dans la console.
  
 <code> <code>
Ligne 36: Ligne 32:
 } }
 </code>    </code>   
 +
 +Cette étape manuelle permettra d'appairer facilement chaque module. Néanmoins, il est à noter qu'une méthode très astucieuse permet de se passer de cette manip préalable, et de connecter de manière automatique chaque module. Néanmoins, elle est un peu plus complexe. L'idée est la suivante: les "récepteurs" émettent un réseau wifi dont le SSID comporte une chaîne prédéfinie (par exemple, "RECEPTION". L'émetteur scanne les réseaux Wifi environnants, et lorsqu'il détecte un SSID commençant par "RECEPTION", il en récupère l'adresse MAC, avant de créer l'appairage. C'est de cette manière que fonctionnent les deux exemples //Master// et //Slave// que l'on trouvera dans les exemples ESP32>ESP-NOW de l'IDE Arduino.
  
 ===== Principe de communication ===== ===== Principe de communication =====
  
-Pour commencer, nous allons simplement envoyer des informations d'un ESP vers un autre. Par commodité, nous les appellerons "Émetteur" et "Récepteur"+Pour commencer, nous allons simplement envoyer des informations d'un ESP vers un autre. Par commodité, nous les appellerons donc "Émetteur" et "Récepteur"
  
 **Côté émetteur:** **Côté émetteur:**
    * Initialiser ESP-NOW.    * Initialiser ESP-NOW.
-   * Enregistrer une fonction de rappel, qui sera exécutée quant un message est envoyé. Cela nous permettra de vérifier la bonne livraison du message.+   * Enregistrer une fonction de rappel, qui sera exécutée quant un message est envoyé. Cela nous permettra de vérifier la bonne transmission du message.
    * On ajoute l'adresse MAC du récepteur, pour l'appairage.    * On ajoute l'adresse MAC du récepteur, pour l'appairage.
    * On envoie le message.    * On envoie le message.
Ligne 52: Ligne 50:
    * Dans cette fonction de rappel, on sauve le contenu du message dans une variable pour en faire quelque chose.    * Dans cette fonction de rappel, on sauve le contenu du message dans une variable pour en faire quelque chose.
  
-===== Résumé des fonctions les plus utiles =====+À Chaque étape listée ci-dessus va correspondre une fonction spécifique à l'utilisation du protocole:
  
-**esp_now_init()** Initialise ESP-NOW. Il faut initialiser le wifi avant d'initialiser ESP-NOW.\\   +**esp_now_init()** Initialiser ESP-NOW. Il faut initialiser le wifi avant d'initialiser ESP-NOW.\\   
 **esp_now_add_peer()** On appelle cette fonction pour appairer un ESP, on passe son adresse MAC en argument.\\    **esp_now_add_peer()** On appelle cette fonction pour appairer un ESP, on passe son adresse MAC en argument.\\   
 **esp_now_send()** Envoie des données avec ESP-NOW.\\    **esp_now_send()** Envoie des données avec ESP-NOW.\\   
Ligne 162: Ligne 160:
 uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64}; uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};
 </code> </code>
-Pensez évidemment à remplacer l'adresse MAC par celle spécifique de votre ESP.+Pensez évidemment à remplacer l'adresse MAC par celle spécifique de votre ESP récepteur.
  
-Ensuite, il faut créer une structure qui contiendra les données envoyées. Elle s'appelera *struct_messageet contiendra 4 types de variables différents. Il faudra modifier cette partie pour l'adapter aux spécificités de votre pojet.+Ensuite, il faut créer une structure qui contiendra les données envoyées. Elle s’appellera //struct_message// et contiendra 4 types de variables différents. Il faudra par la suite modifier cette partie pour l'adapter aux spécificités de votre projet. Pour en savoir un peu plus sur l'utilisation des structures, je vous renvoie à cette page de [[https://www.locoduino.org/spip.php?article107|Locoduino]].
 <code> <code>
 typedef struct struct_message { typedef struct struct_message {
Ligne 174: Ligne 172:
 </code> </code>
  
-On créé ensuite une variable de type *struct_messageet que l'on appelera *myData*. Cette variable servira à stocker... des variables, celles à envoyer.+On créé ensuite une variable de type //struct_message// et que l'on appellera //myData//. Cette variable servira à stocker... des variables, celles à envoyer.
 <code> <code>
 struct_message myData; struct_message myData;
Ligne 187: Ligne 185:
 </code> </code>
  
-Viens maintenant le moment de créer notre fonction *setup()*, après avoir initialisé la communication série avec *Serial.begin(115200)*, nous allons allumer le wifi de l'ESP, puis initialiser ESP-NOW:+Viens maintenant le moment de créer notre fonction //setup()//dans laquelle, après avoir initialisé la communication série avec //Serial.begin(115200)//, nous allons allumer le wifi de l'ESP, puis initialiser ESP-NOW:
  
 <code> <code>
Ligne 218: Ligne 216:
 </code> </code>
  
-Enfin, la boucle *loop()va envoyer un message toutes les deux secondes, contenant des valeurs arbitraires, mais que vous pourrez relier par la suite à des capteurs, par exemple.+Enfin, la boucle //loop()// va envoyer un message toutes les deux secondes, contenant des valeurs arbitraires, mais que vous pourrez relier par la suite à des capteurs, par exemple.
  
 D'abord, donc, initialisons les variables: D'abord, donc, initialisons les variables:
Ligne 228: Ligne 226:
 </code> </code>
  
-Pour mémoire, myData est une structure. Nous assignons donc nos valeurs, aux membres qui sont de différents types. Pour en savoir un peu plus sur l'utilisation des structures, je vous renvoie à cette page de [[https://www.locoduino.org/spip.php?article107|Locoduino]]. Cette manière de travailler permet d'envoyer en un seul bloc les différentes données, de l amanière suivante:+Pour mémoire, myData est une structure. Nous assignons donc nos valeurs, aux membres qui sont de différents types. Cette manière de travailler permet d'envoyer en un seul bloc les différentes données, de la manière suivante:
  
 <code> <code>
Ligne 244: Ligne 242:
 } }
 </code> </code>
- 
-The loop() is executed every 2000 milliseconds (2 seconds). 
- 
-delay(2000); 
  
 ===== Code du récepteur ===== ===== Code du récepteur =====
Ligne 319: Ligne 313:
 </code> </code>
  
-Le code se passe presque d'explications, les étapes sont à peu de chose près les mêmes que celles de l'émetteur, à la différence que la fonction de rappel va être exécutée à la réception d'un message. Par conséquent, l'orsqu'il arrive, il faut copier le contenu de la structure qui arrive dans la variable que nous avons déclarée pour pouvoir en exploiter le contenu:+Le code se passe presque d'explications, les étapes sont à peu de chose près les mêmes que celles de l'émetteur, à la différence que la fonction de rappel va être exécutée à la réception d'un message. Par conséquent, lorsqu'il arrive, il faut copier le contenu de la structure reçue dans la variable que nous avons déclarée pour pouvoir en exploiter le contenu:
 <code> <code>
 memcpy(&myData, incomingData, sizeof(myData)); memcpy(&myData, incomingData, sizeof(myData));
 </code> </code>
 +
 +Autre évidence, mais qu'il est bon de rappeler, les membres de la structure doivent être communs entre l'émetteur et le récepteur.
  
 ===== Tester et aller plus loin ===== ===== Tester et aller plus loin =====
  
-Lorsque vous regarderez les console série des deux esp, vous constaterez que les messages sont bien expédiés, bien reçus et leur contenu correctement interpreté côté récepteur. Les différentes sources trouvées sur le net parlent d'une portée en extérieur supérieur à 200 mètres, avec les deux antennes pointant l'une vers l'autre. À tester, les essais réalisés autour de notre projet de compteur ont plutôt été concluants jusqu'à 100 mètres environ. +Lorsque vous regarderez les console série des deux ESP, vous constaterez que les messages sont bien expédiés, bien reçus et leur contenu correctement interpreté côté récepteur. Les différentes sources trouvées sur le net parlent d'une portée en extérieur supérieur à 200 mètres, avec les deux antennes pointant l'une vers l'autre. À tester, les essais réalisés autour de notre [[howto:arduino-esp:esp-now_compteurs|projet de compteur]] ont plutôt été concluants jusqu'à 100 mètres environ. 
  
-Nous vous renvoyons aux exemples disponibles dans la bibliothèque Arduino, et à nouveaux aux articles de** Random Nerd Tutorials** (ce site est une mine d'or) pour étudier les réseaux avec plusieurs nœuds, et les [[https://randomnerdtutorials.com/esp-now-two-way-communication-esp32/|échanges bi-directionnels]].+Nous vous renvoyons aux exemples disponibles dans la bibliothèque Arduino.
  
  
  • howto/arduino-esp/esp-now.txt
  • Dernière modification : 2021/10/22 13:47
  • de guillaume