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:49] – [Résumé des fonctions les plus utiles] 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. | ||
| - | Chaque étape listée | + | À Chaque étape listée |
| - | **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' | ||
| + | {{ : | ||