Dans cet article, nous allons vous montrer comment vous pouvez utiliser ESP-NOW pour échanger des données entre les cartes ESP8266 NodeMCU programmées avec Arduino IDE. ESP-NOW est un protocole de communication sans connexion développé par Espressif qui permet une transmission par paquets courts et peut être utilisé avec les cartes ESP8266 et ESP32.

Nous avons d’autres tutoriels sur ESP-NOW avec l’ESP8266 :
EDI Arduino
Nous programmerons le Carte ESP8266 NodeMCU en utilisant l’IDE Arduino, donc avant de poursuivre ce tutoriel, vous devez avoir le module complémentaire ESP8266 installé dans votre IDE Arduino. Suivez le guide suivant :
Remarque : nous avons un guide similaire pour l’ESP32 : Premiers pas avec ESP-NOW (ESP32 avec Arduino IDE).
Présentation d’ESP-NOW
La vidéo suivante montre une introduction à ESP-NOW. Cette vidéo a été enregistrée pour l’ESP32, mais la plupart des concepts s’appliquent également à la carte ESP8266 NodeMCU.

Selon le site Web d’Espressif, ESP-NOW est un « protocole développé par Espressif, qui permet à plusieurs appareils de communiquer entre eux sans utiliser le Wi-Fi. Le protocole est similaire à la connectivité sans fil 2,4 GHz à faible consommation (…) . L’appairage entre les appareils est nécessaire avant leur communication. Une fois l’appairage effectué, la connexion est sécurisée et peer-to-peer, sans qu’aucune poignée de main ne soit nécessaire.

Cela signifie qu’après avoir couplé un appareil avec un autre, la connexion est persistante. En d’autres termes, si soudainement une de vos cartes perd l’alimentation ou se réinitialise, lorsqu’elle redémarre, elle se connectera automatiquement à son pair pour continuer la communication.
ESP-NOW prend en charge les fonctionnalités suivantes :
- Communication unicast cryptée et non cryptée ;
- Appareils pairs mixtes chiffrés et non chiffrés ;
- Jusqu’à 250 octets de charge utile peuvent être transportés ;
- Envoi d’une fonction de rappel paramétrable pour informer la couche application de
succès ou échec de la transmission.
La technologie ESP-NOW présente également les limitations suivantes :
- Pairs cryptés limités. 10 pairs cryptés au maximum sont pris en charge en mode Station ; 6 au maximum en mode SoftAP ou SoftAP + Station ;
- Plusieurs pairs non chiffrés sont pris en charge, cependant, leur nombre total doit être inférieur à 20, y compris les pairs chiffrés ;
- La charge utile est limitée à 250 octets.
En termes simples, ESP-NOW est un protocole de communication rapide qui peut être utilisé pour échanger de petits messages (jusqu’à 250 octets) entre les cartes ESP8266.
ESP-NOW est très polyvalent et vous pouvez avoir une communication unidirectionnelle ou bidirectionnelle dans différentes configurations.
Communication unidirectionnelle ESP-NOW
Par exemple, dans une communication à sens unique, vous pouvez avoir des scénarios comme celui-ci :
- Une carte ESP8266 envoie des données à une autre carte ESP8266

Cette configuration est très facile à mettre en œuvre et c’est génial d’envoyer des données d’une carte à l’autre comme des lectures de capteurs ou des commandes ON et OFF pour contrôler les GPIO.
- Un ESP8266 « maître » envoyant des données à plusieurs « esclaves » ESP8266
Une carte ESP8266 envoyant des commandes identiques ou différentes à différentes cartes ESP8266. Cette configuration est idéale pour construire quelque chose comme une télécommande. Vous pouvez avoir plusieurs cartes ESP8266 dans la maison qui sont contrôlées par une carte ESP8266 principale.

- Un « esclave » ESP8266 recevant des données de plusieurs « maîtres »
Cette configuration est idéale si vous souhaitez collecter des données de plusieurs nœuds de capteurs dans une seule carte ESP8266. Celui-ci peut être configuré comme un serveur Web pour afficher les données de toutes les autres cartes, par exemple.

Remarque : dans la documentation ESP-NOW, il n’y a pas de « expéditeur/maître » et « récepteur/esclave ». Chaque carte peut être un émetteur ou un récepteur. Cependant, pour garder les choses claires, nous utiliserons les termes « expéditeur » et « récepteur » ou « maître » et « esclave ».
Communication bidirectionnelle ESP-NOW
Avec ESP-NOW, chaque carte peut être à la fois émetteur et récepteur. Ainsi, vous pouvez établir une communication bidirectionnelle entre les cartes.
Par exemple, vous pouvez avoir deux cartes communiquant entre elles.

Vous pouvez ajouter plus de cartes à cette configuration et avoir quelque chose qui ressemble à un réseau (toutes les cartes ESP8266 communiquent entre elles).

En résumé, ESP-NOW est idéal pour construire un réseau dans lequel plusieurs cartes ESP8266 peuvent échanger des données entre elles.
ESP8266 : Obtenir l’adresse MAC de la carte
Pour communiquer via ESP-NOW, vous devez connaître l’adresse MAC du récepteur ESP8266. C’est ainsi que vous savez à quel appareil vous enverrez les informations.
Chaque ESP8266 a une adresse MAC unique et c’est ainsi que nous identifions chaque carte pour lui envoyer des données à l’aide d’ESP-NOW (découvrez comment obtenir et modifier l’adresse MAC ESP8266).
Pour obtenir l’adresse MAC de votre carte, téléchargez le code suivant.
// Complete Instructions to Get and Change ESP MAC Address: https://Raspberryme.com/get-change-esp32-esp8266-mac-address-arduino/
#include <ESP8266WiFi.h>
void setup(){
Serial.begin(115200);
Serial.println();
Serial.print("ESP8266 Board MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop(){
}
Après avoir téléchargé le code, ouvrez le moniteur série à un débit de 115200 bauds et appuyez sur le bouton ESP8266 RESET. L’adresse MAC doit être imprimée comme suit :

Enregistrez l’adresse MAC de votre carte car vous en aurez besoin pour envoyer des données à la bonne carte via ESP-NOW.
Communication point à point unidirectionnelle ESP-NOW avec ESP8266
Pour vous familiariser avec la communication sans fil ESP-NOW, nous allons créer un projet simple qui montre comment envoyer un message d’un ESP8266 à un autre. Un ESP8266 agira comme un « expéditeur » et l’autre ESP8266 sera le « récepteur ».

Nous allons envoyer une structure qui contient une variable de type char, int, float, String et boolean. Ensuite, vous pouvez modifier la structure pour envoyer les types de variables adaptés à votre projet (comme les lectures de capteurs ou les variables booléennes pour activer ou désactiver quelque chose).
Pour une meilleure compréhension, nous appellerons « expéditeur » à ESP8266 #1 et « récepteur » à ESP8266 #2.
Voici ce que nous devrions inclure dans l’esquisse de l’expéditeur :
- Initialiser ESP-NOW ;
- Enregistrez une fonction de rappel lors de l’envoi de données – la fonction OnDataSent sera exécutée lorsqu’un message est envoyé. Cela peut nous dire si le message a été livré avec succès ou non ;
- Ajoutez un appareil homologue (le récepteur). Pour cela, vous devez connaître l’adresse MAC du récepteur ;
- Envoyez un message à l’appareil homologue.
Côté récepteur, le croquis doit comprendre :
- Initialiser ESP-NOW ;
- Enregistrez-vous pour une fonction de rappel de réception (OnDataRecv). Il s’agit d’une fonction qui sera exécutée à la réception d’un message.
- Dans cette fonction de rappel, enregistrez le message dans une variable pour exécuter n’importe quelle tâche avec ces informations.
ESP-NOW fonctionne avec des fonctions de rappel qui sont appelées lorsqu’un appareil reçoit un message ou lorsqu’un message est envoyé (vous obtenez si le message a été livré avec succès ou s’il a échoué).
Fonctions utiles ESP-NOW
Voici un résumé des fonctions ESP-NOW les plus essentielles :
| Nom et description de la fonction |
| esp_now_init() Initialise ESP-NOW. Vous devez initialiser le Wi-Fi avant d’initialiser ESP-NOW. Renvoie 0, si réussit. |
| esp_now_set_self_role(role) le rôle peut être : ESP_NOW_ROLE_IDLE = 0, ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE, ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX |
| esp_now_add_peer(uint8 mac_addr, uint8 role, uint8 channel, uint8 key, uint8 key_len) Appelez cette fonction pour coupler un appareil. |
| esp_now_send(uint8 mac_address, uint8 data, int len) Envoyer des données avec ESP-NOW. |
| esp_now_register_send_cb() Enregistre une fonction de rappel déclenchée lors de l’envoi de données. Lorsqu’un message est envoyé, une fonction est appelée – cette fonction indique si la livraison a réussi ou non. |
| esp_now_register_rcv_cb() Enregistre une fonction de rappel déclenchée lors de la réception de données. Lorsque des données sont reçues via ESP-NOW, une fonction est appelée. |
Pour plus d’informations sur ces fonctions :
Croquis de l’expéditeur ESP8266 NodeMCU (ESP-NOW)
Voici le code de la carte ESP8266 NodeMCU Sender. Copiez le code dans votre IDE Arduino, mais ne le téléchargez pas encore. Vous devez apporter quelques modifications pour que cela fonctionne pour vous.
/*
Rui Santos
Complete project details at https://Raspberryme.com/esp-now-esp8266-nodemcu-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 <ESP8266WiFi.h>
#include <espnow.h>
// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
// Create a struct_message called myData
struct_message myData;
unsigned long lastTime = 0;
unsigned long timerDelay = 2000; // send readings timer
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
// Set values to send
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = "Hello";
myData.e = false;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
lastTime = millis();
}
}
Comment fonctionne le code
Tout d’abord, incluez les bibliothèques ESP8266WiFi.h et espnow.h.
#include <ESP8266WiFi.h>
#include <espnow.h>
Dans la ligne suivante, vous devez insérer l’adresse MAC du récepteur ESP8266.
uint8_t broadcastAddress[] = {0x5C, 0xCF, 0x7F, 0x99, 0x9A, 0xEA};
Dans notre cas, l’adresse MAC du récepteur est : 5C:CF:7F:99:9A:EA, mais vous devez remplacer cette variable par votre propre adresse MAC.
Ensuite, créez une structure qui contient le type de données que nous voulons envoyer. Nous avons appelé cette structure struct_message et elle contient 5 types de variables différents. Vous pouvez modifier cela pour envoyer les types de variables que vous souhaitez.
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
Créez une nouvelle variable de type struct_message appelée myData qui stockera les valeurs des variables.
struct_message myData;
Ensuite, définissez la fonction OnDataSent(). Il s’agit d’une fonction de rappel qui sera exécutée lors de l’envoi d’un message. Dans ce cas, ce message imprime simplement si le message a été envoyé avec succès ou non.
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
Dans setup(), initialisez le moniteur série à des fins de débogage :
Serial.begin(115200);
Configurez l’appareil en tant que station Wi-Fi :
WiFi.mode(WIFI_STA);
Initialiser ESP-NOW :
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
Définissez le rôle ESP8266 :
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
Il accepte les rôles suivants : ESP_NOW_ROLE_CONTROLLER, ESP_NOW_ROLE_SLAVE, ESP_NOW_ROLE_COMBO, ESP_NOW_ROLE_MAX.
Après avoir initialisé ESP-NOW avec succès, enregistrez la fonction de rappel qui sera appelée lors de l’envoi d’un message. Dans ce cas, nous nous inscrivons à la fonction OnDataSent() créée précédemment.
esp_now_register_send_cb(OnDataSent);
Ensuite, associez-le à un autre appareil ESP-NOW pour envoyer des données :
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
Le esp_now_add_peer accepte les arguments suivants, dans cet ordre : adresse mac, rôle, canal Wi-Fi, clé et longueur de clé.
Dans la boucle (), nous enverrons un message via ESP-NOW toutes les 2 secondes (vous pouvez modifier ce temps de retard sur la variable timerDelay).
Tout d’abord, nous définissons les valeurs des variables comme suit :
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = "Hello";
myData.e = false;
N’oubliez pas que myData est une structure. Ici, nous assignons les valeurs que nous voulons envoyer à l’intérieur de la structure. Par exemple, la première ligne affecte un caractère, la deuxième ligne un nombre Int aléatoire, un Float, une String et une variable booléenne.
Nous créons ce type de structure pour vous montrer comment envoyer les types de variables les plus courants. Vous pouvez modifier la structure pour envoyer tout autre type de données.
Enfin, envoyez le message comme suit :
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
La boucle () est exécutée toutes les 2000 millisecondes (2 secondes).
if ((millis() - lastTime) > timerDelay) {
// Set values to send
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = "Hello";
myData.e = false;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
lastTime = millis();
}
Croquis du récepteur ESP8266 NodeMCU (ESP-NOW)
Téléchargez le code suivant sur votre Carte récepteur ESP8266 NodeMCU.
/*
Rui Santos
Complete project details at https://Raspberryme.com/esp-now-esp8266-nodemcu-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 <ESP8266WiFi.h>
#include <espnow.h>
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("String: ");
Serial.println(myData.d);
Serial.print("Bool: ");
Serial.println(myData.e);
Serial.println();
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
}
Comment fonctionne le code
Comme pour l’expéditeur, commencez par inclure les bibliothèques :
#include <esp_now.h>
#include <WiFi.h>
Créez une structure pour recevoir les données. Cette structure doit être la même que celle définie dans l’esquisse de l’expéditeur.
typedef struct struct_message {
char a[32];
int b;
float c;
String d;
bool e;
} struct_message;
Créez une variable struct_message appelée myData.
struct_message myData;
Créez une fonction de rappel qui sera appelée lorsque l’ESP8266 recevra les données via ESP-NOW. La fonction s’appelle onDataRecv() et doit accepter plusieurs paramètres comme suit :
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
Nous copions le contenu de la variable de données comingData dans la variable myData.
memcpy(&myData, incomingData, sizeof(myData));
Maintenant, la structure myData contient plusieurs variables à l’intérieur avec les valeurs envoyées par l’expéditeur ESP8266. Pour accéder à la variable a, par exemple, il suffit d’appeler myData.a.
Dans cet exemple, nous imprimons simplement les données reçues, mais dans une application pratique, vous pouvez imprimer les données sur un écran, par exemple.
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("String: ");
Serial.println(myData.d);
Serial.print("Bool: ");
Serial.println(myData.e);
Serial.println();
}
Dans setup(), initialisez la communication série à des fins de débogage.
Serial.begin(115200);
Configurez l’appareil en tant que station Wi-Fi.
WiFi.mode(WIFI_STA);
Initialiser ESP-NOW :
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
Définissez le rôle ESP8266 :
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
Enregistrez-vous pour une fonction de rappel qui sera appelée lorsque les données seront reçues. Dans ce cas, nous nous inscrivons à la fonction OnDataRecv() qui a été créée précédemment.
esp_now_register_recv_cb(OnDataRecv);
Test de la communication ESP-NOW
Téléchargez le croquis de l’expéditeur sur une carte et le croquis du récepteur sur l’autre carte. N’oubliez pas d’insérer l’adresse MAC du destinataire sur le croquis de l’expéditeur.
Maintenant, ouvrez deux fenêtres IDE Arduino. Un pour le destinataire et un autre pour l’expéditeur. Ouvrez le moniteur série pour chaque carte. Il doit s’agir d’un port COM différent pour chaque carte.
C’est ce que vous devriez obtenir du côté de l’expéditeur.

Et c’est ce que vous devriez obtenir du côté du récepteur. Notez que la variable Int change entre chaque lecture reçue (car nous l’avons définie sur un nombre aléatoire du côté de l’expéditeur).

Nous avons testé la portée de communication entre les deux cartes et nous sommes en mesure d’obtenir une communication stable jusqu’à 140 mètres (environ 459 pieds) en champ libre. Dans cette expérience, les deux antennes embarquées ESP8266 pointaient l’une vers l’autre.

Conclusion
Dans ce tutoriel, vous avez appris à utiliser ESP-NOW avec la carte ESP8266 NodeMCU. Maintenant, vous pouvez combiner l’esquisse de l’expéditeur et du récepteur afin d’avoir une communication bidirectionnelle (chaque carte agissant en tant que serveur et expéditeur en même temps). Vous pouvez également utiliser plusieurs cartes pour avoir une communication entre plusieurs cartes.
Les cartes ESP8266 et ESP32 peuvent communiquer entre elles en utilisant le protocole de communication ESP-NOW. Il vous suffit de télécharger les croquis appropriés sur chaque tableau. Pour apprendre à utiliser ESP-NOW avec l’ESP32, vous pouvez lire notre guide de démarrage ESP-NOW pour l’ESP32.
Nous espérons que vous avez trouvé ce tutoriel utile. Pour en savoir plus sur la carte ESP8266, assurez-vous de consulter nos ressources :
Merci d’avoir lu.
Apprenez l’histoire de Raspberry Pi à travers cette vidéo :

-
AZDelivery 3 x D1 Mini NodeMCU Lua avec ESP8266-12F Module WLAN CH340G Compatible avec Arduino incluant Un E-Book!
-
ELEGOO 3PCS Carte de Développement ESP-32 Type-C, 2,4 GHz WiFi + Bluetooth
