Notice: DFRobot will be on a short holiday from Apr 4-6. Orders placed during this time will be processed on Apr 7.
#include <esp_now.h>
#include <WiFi.h>
Then we will declare a variable with the broadcast address. For this simple tutorial, since we are focusing on the data structure used for the message, we will assume that we will broadcast the message.uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Then we will declare a struct to hold our message. We will declare a simple structure with two integer data members, for testing purposes. Note however that the total size of the message should not exceed 250 bytes, so you should take this in consideration when modeling your message.typedef struct test_struct {
int x;
int y;
} test_struct;Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
After this, to be able to send data to another device, we need to add a peer, like we did on the previous tutorial. In our case, the MAC address of our peer will correspond to the broadcast address.esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
After registering the peer, we will be able to send messages. But, before that, we will declare a variable of type test_struct to represent our message.test_struct test;
test.x = 10;
test.y = 20;
esp_err_t result = esp_now_send(
broadcastAddress,
(uint8_t *) &test,
sizeof(test_struct));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
The final code can be seen below.#include <esp_now.h>
#include <WiFi.h>
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
typedef struct test_struct {
int x;
int y;
} test_struct;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
test_struct test;
test.x = 10;
test.y = 20;
esp_err_t result = esp_now_send(
broadcastAddress,
(uint8_t *) &test,
sizeof(test_struct));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
}
void loop() {}The receiver code#include <esp_now.h>
#include <WiFi.h>
Then we will also declare our message struct, so the receiver can use it. For simplicity, we are declaring it in both the receiver and sender code. Nonetheless, in a real application scenario, the best approach would be declaring it in a header file and import it in both programs.typedef struct test_struct {
int x;
int y;
} test_struct;
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
To finish the setup function, we will register a function that will be executed when a ESP-NOW message is received. We will call this callback function onReceiveData and check its implementation below.void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
To finalize, we will check the implementation of the OnDataRecv function. Like we have seen in the previous tutorial, this function follows a pre-defined signature. It returns void and it receives the following 3 arguments: the MAC address of the sender, a pointer to the data received and the length of the data received.void OnDataRecv(const uint8_t * mac, const uint8_t *data, int len) {
// function implementation
}
Since we receive the pointer to the data with the uint8_t* data type, we need to cast it to test_struct*.test_struct* test =(test_struct*) data;
After that we will print the values of both data members of our message struct. Recall from the sender’s code that x should be equal to 10 and y should be equal to 20.Serial.println(test->x);
Serial.println(test->y);
The complete callback code can be seen below.void OnDataRecv(const uint8_t * mac, const uint8_t *data, int len) {
test_struct* test =(test_struct*) data;
Serial.println(test->x);
Serial.println(test->y);
}Note that this callback function runs from the WiFi task, which means we should not do lengthy operations on it. For simplicity, we are going to print the result to the serial port on the callback but, in a real application scenario, we should just signal the reception of the data and process it in another lower priority task.#include <esp_now.h>
#include <WiFi.h>
typedef struct test_struct {
int x;
int y;
} test_struct;
void OnDataRecv(const uint8_t * mac, const uint8_t *data, int len) {
test_struct* test =(test_struct*) data;
Serial.println(test->x);
Serial.println(test->y);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {}Testing the code