ESP-NOW : Recevoir des données de plusieurs cartes ESP32 (plusieurs à un)

ESP-NOW : Recevoir des données de plusieurs cartes ESP32 (plusieurs à un)

Ce tutoriel montre comment configurer une carte ESP32 pour recevoir des données de plusieurs cartes ESP32 via le protocole de communication ESP-NOW (configuration plusieurs à un). Cette configuration est idéale si vous souhaitez collecter les données de plusieurs nœuds de capteurs dans une seule carte ESP32. Les cartes seront programmées à l’aide de l’IDE Arduino.

ESP-NOW avec ESP32 : recevez des données de plusieurs cartes plusieurs à une

Nous avons d’autres guides liés à ESP-NOW qui pourraient vous intéresser :

Aperçu du projet

Ce didacticiel montre comment configurer une carte ESP32 pour recevoir des données de plusieurs cartes ESP32 via le protocole de communication ESP-NOW (configuration plusieurs à un) comme indiqué dans la figure suivante.

ESP-NOW avec ESP32 Recevoir des données de plusieurs cartes (plusieurs à un) Présentation du projet
  • Une carte ESP32 agit comme un récepteur/esclave ;
  • Plusieurs cartes ESP32 agissent en tant qu’expéditeurs/maîtres. Nous avons testé cet exemple avec 5 cartes émettrices ESP32 et cela a bien fonctionné. Vous devriez pouvoir ajouter plus de cartes à votre configuration ;
  • La carte émettrice reçoit un message d’accusé de réception indiquant si le message a été délivré avec succès ou non ;
  • La carte réceptrice ESP32 reçoit les messages de tous les expéditeurs et identifie quelle carte a envoyé le message ;
  • A titre d’exemple, nous allons échanger des valeurs aléatoires entre les cartes. Vous devez modifier cet exemple pour envoyer des commandes ou des relevés de capteur (échangez les relevés de capteur à l’aide d’ESP-NOW).

Noter: dans la documentation ESP-NOW, il n’y a pas de « expéditeur/maître » et de « 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 ».

Conditions préalables

Nous allons programmer les cartes ESP32 à l’aide de l’IDE Arduino, donc avant de poursuivre ce tutoriel, assurez-vous que ces cartes sont installées dans votre IDE Arduino.

Pièces requises

Pour suivre ce tutoriel, vous avez besoin de plusieurs cartes ESP32. Tous les modèles ESP32 devraient fonctionner. Nous avons expérimenté différents modèles de cartes ESP32 et tout a bien fonctionné (Carte ESP32 DOITTTGO T-Journal, ESP32 avec carte OLED et ESP32-CAM).

Vous pouvez utiliser les liens précédents ou accéder directement à MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

1644023526 929 ESP NOW Recevoir des donnees de plusieurs cartes ESP32 plusieurs a

Obtention de l’adresse MAC de la carte du récepteur

Pour envoyer des messages via ESP-NOW, vous devez connaître l’adresse MAC de la carte réceptrice. Chaque carte a une adresse MAC unique (découvrez comment obtenir et modifier l’adresse MAC ESP32).

Téléchargez le code suivant sur votre carte récepteur ESP32 pour obtenir son adresse MAC.

// Complete Instructions to Get and Change ESP MAC Address: https://Raspberryme.com/get-change-esp32-esp8266-mac-address-arduino/

#ifdef ESP32
  #include <WiFi.h>
#else
  #include <ESP8266WiFi.h>
#endif

void setup(){
  Serial.begin(115200);
  Serial.println();
  Serial.print("ESP Board MAC Address:  ");
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}

Afficher le code brut

Après avoir téléchargé le code, appuyez sur le bouton RST/EN et l’adresse MAC devrait s’afficher sur le moniteur série.

Adresse MAC de la carte ESP32 avec moniteur série Arduino IDE

Code d’expéditeur ESP32 (ESP-NOW)

Le destinataire peut identifier chaque expéditeur par son adresse MAC unique. Cependant, traiter différentes adresses MAC du côté du récepteur pour identifier quelle carte a envoyé quel message peut être délicat.

Ainsi, pour faciliter les choses, nous identifierons chaque carte avec un numéro unique (identifiant) qui commence à 1. Si vous avez trois cartes, l’une aura le numéro d’identification 1, l’autre le numéro 2 et enfin le numéro 3. L’ID sera envoyé au récepteur avec les autres variables.

A titre d’exemple, nous allons échanger une structure qui contient le tableau identifiant nombre et deux nombres aléatoires X et y comme le montre la figure ci-dessous.

ESP-NOW avec ESP32 reçoit des données de plusieurs cartes (plusieurs à un) Exemple de données

Téléchargez le code suivant sur chacun de vos tableaux d’envoi. N’oubliez pas d’incrémenter le identifiant numéro pour chaque carte émettrice.

/*********
  Rui Santos
  Complete project details at https://Raspberryme.com/esp-now-many-to-one-esp32/
  
  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 <WiFi.h>

// REPLACE WITH THE RECEIVER'S 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 {
    int id; // must be unique for each sender board
    int x;
    int y;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// Create peer interface
esp_now_peer_info_t peerInfo;

// 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() {
  // Init Serial Monitor
  Serial.begin(115200);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    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_register_send_cb(OnDataSent);
  
  // Register peer
  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;
  }
}
 
void loop() {
  // Set values to send
  myData.id = 1;
  myData.x = random(0,50);
  myData.y = random(0,50);

  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
   
  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  delay(10000);
}

Afficher le code brut

Comment fonctionne le code

Inclure le Wifi et esp_now bibliothèques.

#include <esp_now.h>
#include <WiFi.h>

Insérez l’adresse MAC du récepteur sur la ligne suivante.

uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x15, 0xC7, 0xFC};

Ensuite, créez une structure qui contient les données que nous voulons envoyer. Nous avons appelé cette structure struct_message et il contient trois variables entières : le plateau identifiant, X et y. Vous pouvez changer cela pour envoyer les types de variables que vous voulez (mais n’oubliez pas de changer cela du côté récepteur également).

typedef struct struct_message {
  int id; // must be unique for each sender board
  int x;
  int y;
} struct_message;

Créer une nouvelle variable de type struct_message que l’on appelle mes données qui stockera les valeurs des variables.

struct_message myData;

Fonction de rappel OnDataSent()

Ensuite, définissez le OnDataSent() une fonction. Il s’agit d’une fonction de rappel qui sera exécutée lors de l’envoi d’un message. Dans ce cas, cette fonction imprime si le message a été livré avec succès ou non.

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");
}

mettre en place()

Dans le mettre en place()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() != ESP_OK) {
  Serial.println("Error initializing ESP-NOW");
  return;
}

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, inscrivez-vous au OnDataSent() fonction créée précédemment.

esp_now_register_send_cb(OnDataSent);

Ajouter un appareil pair

Pour envoyer des données à une autre carte (le récepteur), vous devez la coupler en tant que pair. Les lignes suivantes enregistrent et ajoutent un nouveau pair.

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;
}

boucler()

Dans le boucler()nous enverrons un message via ESP-NOW toutes les 10 secondes (vous pouvez modifier ce délai).

Attribuez une valeur à chaque variable.

myData.id = 1;
myData.x = random(0,50);
myData.y = random(0,50);

N’oubliez pas de changer l’identifiant de chaque carte émettrice.

Rappelez-vous que mes données est une structure. Attribuez ici les valeurs que vous souhaitez envoyer à l’intérieur de la structure. Dans ce cas, nous envoyons simplement le identifiant et valeurs aléatoires X et y. Dans une application pratique, ceux-ci doivent être remplacés par des commandes ou des lectures de capteur, par exemple.

Envoyer un message ESP-NOW

Enfin, envoyez le message via ESP-NOW.

// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
 
if (result == ESP_OK) {
  Serial.println("Sent with success");
}
else {
  Serial.println("Error sending the data");
}

Code récepteur ESP32 (ESP-NOW)

Téléchargez le code suivant sur votre carte récepteur ESP32. Le code est préparé pour recevoir des données de trois cartes différentes. Vous pouvez facilement modifier le code pour recevoir des données d’un nombre différent de cartes.

/*********
  Rui Santos
  Complete project details at https://Raspberryme.com/esp-now-many-to-one-esp32/
  
  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 <WiFi.h>

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
  int id;
  int x;
  int y;
}struct_message;

// Create a struct_message called myData
struct_message myData;

// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;
struct_message board3;

// Create an array with all the structures
struct_message boardsStruct[3] = {board1, board2, board3};

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
  char macStr[18];
  Serial.print("Packet received from: ");
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.println(macStr);
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
  // Update the structures with the new incoming data
  boardsStruct[myData.id-1].x = myData.x;
  boardsStruct[myData.id-1].y = myData.y;
  Serial.printf("x value: %d \n", boardsStruct[myData.id-1].x);
  Serial.printf("y value: %d \n", boardsStruct[myData.id-1].y);
  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() != ESP_OK) {
    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_register_recv_cb(OnDataRecv);
}
 
void loop() {
  // Acess the variables for each board
  /*int board1X = boardsStruct[0].x;
  int board1Y = boardsStruct[0].y;
  int board2X = boardsStruct[1].x;
  int board2Y = boardsStruct[1].y;
  int board3X = boardsStruct[2].x;
  int board3Y = boardsStruct[2].y;*/

  delay(10000);  
}

Afficher le code brut

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 {
  int id;
  int x;
  int y;
} struct_message;

Créer un struct_message variable appelée mes données qui contiendra les données reçues.

struct_message myData;

Ensuite, créez un struct_message variable pour chaque carte, afin que nous puissions affecter les données reçues à la carte correspondante. Ici, nous créons des structures pour trois cartes émettrices. Si vous avez plus de cartes émettrices, vous devez créer plus de structures.

struct_message board1;
struct_message board2;
struct_message board3;

Créez un tableau contenant toutes les structures du tableau. Si vous utilisez un nombre différent de cartes, vous devez changer cela.

struct_message boardsStruct[3] = {board1, board2, board3};

onDataRecv()

Créez une fonction de rappel qui est appelée lorsque l’ESP32 reçoit 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) {

Obtenez l’adresse MAC de la carte :

char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
         mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);

Copiez le contenu du entrantDonnées variable de données dans la mes données variable.

memcpy(&myData, incomingData, sizeof(myData));

Maintenant le mes données structure contient plusieurs variables avec les valeurs envoyées par l’un des expéditeurs ESP32. On peut identifier quelle carte envoie le paquet par son ID : myData.id.

De cette façon, nous pouvons affecter les valeurs reçues aux cartes correspondantes sur le planchesStruct déployer:

boardsStruct[myData.id-1].x = myData.x;
boardsStruct[myData.id-1].y = myData.y;

Par exemple, imaginez que vous recevez un paquet de la carte avec l’identifiant 2. La valeur de myData.idvaut 2.

Donc, vous voulez mettre à jour les valeurs de planche2 structure. le planche2 structure est l’élément d’indice 1 sur la planchesStruct déployer. C’est pourquoi nous soustrayons 1, car les tableaux en C ont une indexation de 0. Cela peut aider si vous regardez l’image suivante.

1644023526 639 ESP NOW Recevoir des donnees de plusieurs cartes ESP32 plusieurs a

mettre en place()

Dans le mettre en place()initialisez le moniteur série.

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;
}

Enregistrez-vous pour une fonction de rappel qui sera appelée lorsque les données seront reçues. Dans ce cas, nous nous inscrivons au OnDataRecv() fonction créée précédemment.

esp_now_register_recv_cb(OnDataRecv);

Les lignes suivantes commentées sur la boucle illustrent ce que vous devez faire si vous souhaitez accéder aux variables de chaque structure de carte. Par exemple, pour accéder au X valeur de planche1:

int board1X = boardsStruct[0].x;

Manifestation

Téléchargez le code de l’expéditeur sur chacun de vos tableaux d’envoi. N’oubliez pas de donner un identifiant différent à chaque carte.

Téléchargez le code du récepteur sur la carte du récepteur ESP32. N’oubliez pas de modifier la structure pour correspondre au nombre de cartes émettrices.

Sur le moniteur série des expéditeurs, vous devriez recevoir un message « Delivery Success » si les messages sont livrés correctement.

ESP-NOW Envoi de paquets Succès de livraison Moniteur série ESP32

Sur la carte réceptrice, vous devriez recevoir les paquets de toutes les autres cartes. Dans ce test, nous recevions des données de 5 cartes différentes.

ESP-NOW reçoit des données de plusieurs cartes ESP32 Serial Monitor

Conclusion

Dans ce didacticiel, vous avez appris à configurer un ESP32 pour recevoir des données de plusieurs cartes ESP32 à l’aide d’ESP-NOW (configuration plusieurs à un).

Par exemple, nous avons échangé des nombres aléatoires. Dans une application réelle, ceux-ci peuvent être remplacés par des lectures ou des commandes de capteur réelles. C’est idéal si vous souhaitez collecter des données à partir de plusieurs nœuds de capteurs. Vous pouvez aller plus loin dans ce projet et créer un serveur Web sur la carte du récepteur pour afficher les messages reçus.

Pour utiliser le Wi-Fi pour créer un serveur Web et utiliser ESP-NOW simultanément, vous devez configurer l’ESP32 à la fois comme station Wi-Fi et comme point d’accès. De plus, vous devez définir un canal Wi-Fi différent : un pour ESP-NOW et l’autre pour la station. Vous pouvez suivre le tutoriel suivant :

Nous avons d’autres tutoriels liés à ESP-NOW que vous pourriez aimer :

En savoir plus sur ESP32 avec nos ressources :

Merci d’avoir lu.