Différences
Ci-dessous, les différences entre deux révisions de la page.
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] – guillaume | howto:arduino-esp:esp-now [2025/05/21 10:08] (Version actuelle) – modification externe 127.0.0.1 | ||
---|---|---|---|
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' |
- | **esp_now_init()** | + | **esp_now_init()** |
**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' | ===== Code de l' | ||
- | Ci-dessous, le code tel que proposé par Rui Santos, de Random Nerd Tutorials: | + | Ci-dessous, le code commenté: |
< | < | ||
- | /* | + | // Référence technique: |
- | 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 < | #include < | ||
#include < | #include < | ||
- | // REPLACE WITH YOUR RECEIVER | + | // Stockage de l' |
- | uint8_t | + | uint8_t |
- | // Structure example to send data | + | // La variable qui sera envoyée au récepteur (nous générerons une valeur aléatoire pour l' |
- | // Must match the receiver structure | + | float maValeurEnvoyee; |
- | typedef struct struct_message | + | |
- | | + | // La fonction de rappel qui nous assurera de la bonne livraison du message |
- | | + | void quand_donnees_Envoyees(const uint8_t *mac_addr, esp_now_send_status_t status) |
- | float c; | + | |
- | bool d; | + | |
- | } 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(" | ||
- | Serial.println(status == ESP_NOW_SEND_SUCCESS ? " | ||
- | } | ||
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 |
if (esp_now_init() != ESP_OK) { | if (esp_now_init() != ESP_OK) { | ||
- | Serial.println(" | + | Serial.println(" |
return; | return; | ||
} | } | ||
- | // Once ESPNow is successfully Init, we will register for Send CB to | + | // Si ESP-NOW a correctement démarré, il est temps d' |
- | // 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' |
- | esp_now_peer_info_t peerInfo; | + | memcpy(infosRecepteur.peer_addr, |
- | memcpy(peerInfo.peer_addr, | + | |
- | 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(& | + | infosRecepteur.channel = 0; |
- | Serial.println(" | + | |
+ | // On ne chiffre pas les échanges | ||
+ | infosRecepteur.encrypt = false; | ||
+ | |||
+ | // Appairage | ||
+ | if (esp_now_add_peer(& | ||
+ | Serial.println(" | ||
return; | return; | ||
} | } | ||
Ligne 129: | Ligne 118: | ||
void loop() { | void loop() { | ||
- | // Set values to send | ||
- | strcpy(myData.a, | ||
- | myData.b = random(1, | ||
- | myData.c = 1.2; | ||
- | myData.d = false; | ||
| | ||
- | // Send message | + | // On définit la valeur de la variable à envoyer à l'aide d'un générateur aléatoire |
- | esp_err_t | + | maValeurEnvoyee = random(1, |
+ | |||
+ | // On envoie le message | ||
+ | esp_err_t | ||
- | if (result | + | if (resultat |
- | Serial.println(" | + | Serial.println(" |
} | } | ||
else { | else { | ||
- | Serial.println(" | + | Serial.println(" |
} | } | ||
- | delay(2000); | ||
- | } | ||
- | </ | ||
- | Quelques explications: | + | |
- | + | | |
- | D' | + | |
- | < | + | |
- | #include < | + | |
- | #include < | + | |
- | </code> | + | |
- | + | ||
- | Ensuite, nous stockons dans une variable l' | + | |
- | < | + | |
- | uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64}; | + | |
- | </code> | + | |
- | Pensez évidemment à remplacer l' | + | |
- | + | ||
- | Ensuite, il faut créer une structure qui contiendra les données envoyées. Elle s’appellera // | + | |
- | < | + | |
- | typedef struct struct_message { | + | |
- | char a[32]; | + | |
- | int b; | + | |
- | float c; | + | |
- | bool d; | + | |
- | } struct_message; | + | |
- | </ | + | |
- | + | ||
- | On créé ensuite une variable de type // | + | |
- | < | + | |
- | struct_message myData; | + | |
- | </ | + | |
- | + | ||
- | Enfin, nous allons définir notre fonction de rappel, qui sera exécutée automatiquement lorsqu' | + | |
- | < | + | |
- | void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { | + | |
- | Serial.print(" | + | |
- | Serial.println(status == ESP_NOW_SEND_SUCCESS ? " | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Viens maintenant le moment de créer notre fonction // | + | |
- | + | ||
- | < | + | |
- | WiFi.mode(WIFI_STA); | + | |
- | if (esp_now_init() != ESP_OK) { | + | |
- | Serial.println(" | + | |
- | return; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | On enregistre ensuite la fonction de rappel, créée précédemment: | + | |
- | + | ||
- | < | + | |
- | esp_now_register_send_cb(OnDataSent); | + | |
- | </ | + | |
- | + | ||
- | Nous devons ensuite appairer notre émetteur avec son récepteur, en définissant son adresse MAC: | + | |
- | < | + | |
- | //Register peer | + | |
- | esp_now_peer_info_t peerInfo; | + | |
- | memcpy(peerInfo.peer_addr, | + | |
- | peerInfo.channel = 0; | + | |
- | peerInfo.encrypt = false; | + | |
- | + | ||
- | //Add peer | + | |
- | if (esp_now_add_peer(& | + | |
- | Serial.println(" | + | |
- | return; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Enfin, la boucle //loop()// va envoyer un message | + | |
- | + | ||
- | D' | + | |
- | < | + | |
- | strcpy(myData.a, | + | |
- | myData.b = random(1, | + | |
- | myData.c = 1.2; | + | |
- | myData.d = false; | + | |
- | </ | + | |
- | + | ||
- | 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' | + | |
- | + | ||
- | < | + | |
- | esp_err_t result = esp_now_send(broadcastAddress, | + | |
- | </ | + | |
- | + | ||
- | On peut vérifier que le message a bien été envoyé: | + | |
- | + | ||
- | < | + | |
- | if (result == ESP_OK) { | + | |
- | Serial.println(" | + | |
- | } | + | |
- | else { | + | |
- | | + | |
} | } | ||
</ | </ | ||
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: |
< | < | ||
- | /* | + | // Inclure les librairies |
- | Rui Santos | + | |
- | Complete project details at https:// | + | |
- | + | ||
- | 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 < | #include < | ||
#include < | #include < | ||
- | // Structure example to receive data | + | // La variable qui sera envoyée au récepteur (nous générerons une valeur aléatoire pour l' |
- | // Must match the sender structure | + | float maValeurRecue; |
- | typedef struct struct_message { | + | |
- | char a[32]; | + | |
- | int b; | + | |
- | | + | |
- | 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(& | + | memcpy(& |
Serial.print(" | Serial.print(" | ||
- | Serial.println(len); | + | Serial.println(taille); |
- | Serial.print(" | + | Serial.print(" |
- | Serial.println(myData.a); | + | Serial.println(maValeurRecue); |
- | Serial.print(" | + | |
- | Serial.println(myData.b); | + | |
- | Serial.print(" | + | |
- | Serial.println(myData.c); | + | |
- | Serial.print(" | + | |
- | 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 |
if (esp_now_init() != ESP_OK) { | if (esp_now_init() != ESP_OK) { | ||
- | Serial.println(" | + | Serial.println(" |
return; | return; | ||
} | } | ||
+ | |||
+ | // Si ESP-NOW a correctement démarré, il est temps d' | ||
+ | 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() { | ||
+ | | ||
} | } | ||
</ | </ | ||
- | |||
- | Le code se passe presque d' | ||
- | < | ||
- | memcpy(& | ||
- | </ | ||
- | |||
- | Autre évidence, mais qu'il est bon de rappeler, les membres de la structure doivent être communs entre l' | ||
===== 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 | + | 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 |
- | Nous vous renvoyons aux exemples disponibles dans la bibliothèque Arduino. | + | Nous vous renvoyons aux exemples disponibles dans la bibliothèque Arduino |
+ | ===== Sources de l' | ||
+ | {{ : | ||