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
howto:arduino-esp:esp-now [2021/10/12 09:48] guillaumehowto:arduino-esp:esp-now [2021/10/22 13:47] (Version actuelle) – [Tester et aller plus loin] guillaume
Ligne 50: 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 60: Ligne 60:
 ===== Code de l'émetteur =====    ===== Code de l'émetteur =====   
  
-Ci-dessous, le code tel que proposé par Rui Santos, de Random Nerd Tutorials:+Ci-dessous, le code commenté:
  
 <code> <code>
-/+// Référence technique: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html
-  Rui Santos +
-  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/ +
-   +
-  Permission is hereby granted, free of charge, to any person obtaining a copy +
-  of this software and associated documentation files. +
-   +
-  The above copyright notice and this permission notice shall be included in all +
-  copies or substantial portions of the Software. +
-*/+
  
 +// Inclure les librairies
 #include <esp_now.h> #include <esp_now.h>
 #include <WiFi.h> #include <WiFi.h>
  
-// REPLACE WITH YOUR RECEIVER MAC Address +// Stockage de l'adresse MAC du récepteur pour usage ultérieur. Remplacer les 'FF' par les valeur notées plus avant. 
-uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};+uint8_t MAC_recepteur[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  
-// Structure example to send data +// La variable qui sera envoyée au récepteur (nous générerons une valeur aléatoire pour l'exemple) 
-// Must match the receiver structure +float maValeurEnvoyee; 
-typedef struct struct_message + 
-  char a[32]+// La fonction de rappel qui nous assurera de la bonne livraison du message 
-  int b; +void quand_donnees_Envoyees(const uint8_t *mac_addr, esp_now_send_status_t status) 
-  float c; +  Serial.print("\r\nDernier paquet envoyé:\t")
-  bool d+  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Succès" : "Échec")
-struct_message;+}
  
-// Create a struct_message called myData +// Une variable qui servira à stocker les réglages concernant le récepteur 
-struct_message myData;+esp_now_peer_info_t infosRecepteur;
  
-// callback when data is sent 
-void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { 
-  Serial.print("\r\nLast Packet Send Status:\t"); 
-  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); 
-} 
    
 void setup() { void setup() {
-  // Init Serial Monitor+  // On initie la comm série à 115200 Bauds
   Serial.begin(115200);   Serial.begin(115200);
    
-  // Set device as a Wi-Fi Station+  // On démarre le Wifi en mode Station
   WiFi.mode(WIFI_STA);   WiFi.mode(WIFI_STA);
  
-  // Init ESP-NOW+  // Puis on initialise ESP-NOW
   if (esp_now_init() != ESP_OK) {   if (esp_now_init() != ESP_OK) {
-    Serial.println("Error initializing ESP-NOW");+    Serial.println("Erreur d'initialisation ESP-NOW");
     return;     return;
   }   }
  
-  // Once ESPNow is successfully Initwe will register for Send CB to +  // Si ESP-NOW a correctement démarréil est temps d'enregistrer la fonction de rappel: 
-  // get the status of Trasnmitted packet +  esp_now_register_send_cb(quand_donnees_Envoyees);
-  esp_now_register_send_cb(OnDataSent);+
      
-  // Register peer +  // Tout est prêt pour l'appairage avec notre récepteur: 
-  esp_now_peer_info_t peerInfo; +  memcpy(infosRecepteur.peer_addr, MAC_recepteur, 6);
-  memcpy(peerInfo.peer_addr, broadcastAddress, 6)+
-  peerInfo.channel = 0;   +
-  peerInfo.encrypt = false;+
      
-  // Add peer         +  // On définit un canal (0 utilisera automatiquement le même canal que celui utilisé par le wifi) 
-  if (esp_now_add_peer(&peerInfo) != ESP_OK){ +  infosRecepteur.channel = 0;   
-    Serial.println("Failed to add peer");+ 
 +  // On ne chiffre pas les échanges 
 +  infosRecepteur.encrypt = false; 
 +   
 +  // Appairage         
 +  if (esp_now_add_peer(&infosRecepteur) != ESP_OK){ 
 +    Serial.println("Échec de l'appairage");
     return;     return;
   }   }
Ligne 129: Ligne 118:
    
 void loop() { void loop() {
-  // Set values to send 
-  strcpy(myData.a, "THIS IS A CHAR"); 
-  myData.b = random(1,20); 
-  myData.c = 1.2; 
-  myData.d = false; 
      
-  // Send message via ESP-NOW +  // On définit la valeur de la variable à envoyer à l'aide d'un générateur aléatoire 
-  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));+  maValeurEnvoyee = random(1,20); 
 +   
 +  // On envoie le message 
 +  esp_err_t resultat = esp_now_send(MAC_recepteur, (uint8_t *) &maValeurEnvoyee, sizeof(maValeurEnvoyee));
        
-  if (result == ESP_OK) { +  if (resultat == ESP_OK) { 
-    Serial.println("Sent with success");+    Serial.println("Envoi OK");
   }   }
   else {   else {
-    Serial.println("Error sending the data");+    Serial.println("Erreur envoi");
   }   }
-  delay(2000); 
-} 
-</code> 
  
-Quelques explications: +  // On effectue cette opération toutes les secondes 
- +  delay(1000);
-D'abord, inclure les librairies: +
-<code> +
-#include <esp_now.h> +
-#include <WiFi.h> +
-</code> +
- +
-Ensuite, nous stockons dans une variable l'adresse MAC du récepteur: +
-<code> +
-uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64}; +
-</code> +
-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’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> +
-typedef struct struct_message { +
-  char a[32]; +
-  int b; +
-  float c; +
-  bool d; +
-} struct_message; +
-</code> +
- +
-On créé ensuite une variable de type //struct_message// et que l'on appellera //myData//. Cette variable servira à stocker... des variables, celles à envoyer. +
-<code> +
-struct_message myData; +
-</code> +
- +
-Enfin, nous allons définir notre fonction de rappel, qui sera exécutée automatiquement lorsqu'un message aura été envoyé. Ici, on affiche seulement la réussite ou l'échec de la livraison. +
-<code> +
-void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { +
-  Serial.print("\r\nLast Packet Send Status:\t"); +
-  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); +
-+
-</code> +
- +
-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> +
-WiFi.mode(WIFI_STA); +
-if (esp_now_init() != ESP_OK) { +
-  Serial.println("Error initializing ESP-NOW"); +
-  return; +
-+
-</code> +
- +
-On enregistre ensuite la fonction de rappel, créée précédemment: +
- +
-<code> +
-esp_now_register_send_cb(OnDataSent); +
-</code> +
- +
-Nous devons ensuite appairer notre émetteur avec son récepteur, en définissant son adresse MAC: +
-<code> +
-//Register peer +
-esp_now_peer_info_t peerInfo; +
-memcpy(peerInfo.peer_addr, broadcastAddress, 6); +
-peerInfo.channel = 0; +
-peerInfo.encrypt = false; +
- +
-//Add peer +
-if (esp_now_add_peer(&peerInfo) != ESP_OK){ +
-  Serial.println("Failed to add peer"); +
-  return; +
-+
-</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. +
- +
-D'abord, donc, initialisons les variables: +
-<code> +
-strcpy(myData.a, "THIS IS A CHAR"); +
-myData.b = random(1,20); +
-myData.c = 1.2; +
-myData.d = false; +
-</code> +
- +
-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> +
-esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); +
-</code> +
- +
-On peut vérifier que le message a bien été envoyé: +
- +
-<code> +
-if (result == ESP_OK) { +
-  Serial.println("Sent with success"); +
-+
-else { +
-  Serial.println("Error sending the data");+
 } }
 </code> </code>
Ligne 245: Ligne 139:
 ===== Code du récepteur ===== ===== Code du récepteur =====
  
-Voici le programme à uploader dans l'ESP qui servira de récepteur.+Voici le code du récepteur, commenté en détail:
  
 <code> <code>
-/+// Inclure les librairies
-  Rui Santos +
-  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/ +
-   +
-  Permission is hereby granted, free of charge, to any person obtaining a copy +
-  of this software and associated documentation files. +
-   +
-  The above copyright notice and this permission notice shall be included in all +
-  copies or substantial portions of the Software. +
-*/ +
 #include <esp_now.h> #include <esp_now.h>
 #include <WiFi.h> #include <WiFi.h>
  
-// Structure example to receive data +// La variable qui sera envoyée au récepteur (nous générerons une valeur aléatoire pour l'exemple) 
-// Must match the sender structure +float maValeurRecue;
-typedef struct struct_message { +
-    char a[32]; +
-    int b; +
-    float c; +
-    bool d; +
-} struct_message; +
- +
-// Create a struct_message called myData +
-struct_message myData;+
  
-// callback function that will be executed when data is received +// La fonction de rappel qui nous assurera de la bonne livraison du message 
-void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { +void quand_donnees_Recues(const uint8_t * mac, const uint8_t *data_reception, int taille) { 
-  memcpy(&myDataincomingData, sizeof(myData));+  memcpy(&maValeurRecuedata_reception, sizeof(maValeurRecue));
   Serial.print("Bytes received: ");   Serial.print("Bytes received: ");
-  Serial.println(len); +  Serial.println(taille); 
-  Serial.print("Char: "); +  Serial.print("valeur reçue: "); 
-  Serial.println(myData.a); +  Serial.println(maValeurRecue);
-  Serial.print("Int: "); +
-  Serial.println(myData.b); +
-  Serial.print("Float: "); +
-  Serial.println(myData.c); +
-  Serial.print("Bool: "); +
-  Serial.println(myData.d);+
   Serial.println();   Serial.println();
 } }
    
 void setup() { void setup() {
-  // Initialize Serial Monitor+  // On initie la comm série à 115200 Bauds
   Serial.begin(115200);   Serial.begin(115200);
-   +  
-  // Set device as a Wi-Fi Station+  // On démarre le Wifi en mode Station
   WiFi.mode(WIFI_STA);   WiFi.mode(WIFI_STA);
  
-  // Init ESP-NOW+  // Puis on initialise ESP-NOW
   if (esp_now_init() != ESP_OK) {   if (esp_now_init() != ESP_OK) {
-    Serial.println("Error initializing ESP-NOW");+    Serial.println("Erreur d'initialisation ESP-NOW");
     return;     return;
   }   }
 +
 +  // Si ESP-NOW a correctement démarré, il est temps d'enregistrer la fonction de rappel:
 +  esp_now_register_recv_cb(quand_donnees_Recues);
      
-  // Once ESPNow is successfully Init, we will register for recv CB to 
-  // get recv packer info 
-  esp_now_register_recv_cb(OnDataRecv); 
 } }
    
 void loop() { void loop() {
 +  
 } }
 </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, 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> 
-memcpy(&myData, incomingData, sizeof(myData)); 
-</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 [[howto:arduino-esp:esp-now_compteurs|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 interprété 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.+Nous vous renvoyons aux exemples disponibles dans la bibliothèque Arduino pour aller plus loin !
  
 +===== Sources de l'article=====
 +{{ :howto:arduino-esp:esp-now_programmes.zip |}}
  
  • howto/arduino-esp/esp-now.txt
  • Dernière modification : 2021/10/22 13:47
  • de guillaume