In previous entries, we have covered the basics of ESP-NOW, how to set up a 1-to-1 communication to send a simple variable, and how to send a data structure (struct).
In this entry, we will delve into using ESP-NOW to send a string in a 1-to-1 communication.
Sending a string is a simple way to send information. Moreover, it will “unlock” our ability to send data in JSON format.
We will see that in upcoming entries, as well as how to handle 1-to-many, many-to-1, and many-to-many communications. But for now, we will focus on how to send a string.
Sending a string
Sending a string is not too different from sending a struct (after all, a string is an object, which is similar to a struct).
We just need to know how to convert the string into a byte packet to send it. For example, like this,
String payload = "MY STRING";
esp_err_t result = esp_now_send(MAC_RECEIVER_1, (uint8_t*)payload.c_str(), payload.length());
And, we need to be able to compose a string from the received bytes. We could do that like this.
String payload;
payload.reserve(len);
for(auto i = 0; i < len; i++)
{
payload += (char)data[i];
}
This is how easily we can send and receive strings through ESP-NOW.
Complete example
Let’s see the complete example 👇
The sender code performs the following tasks:
- ESP-NOW Initialization: ESP-NOW is initialized and a callback is registered to know if the message was sent successfully.
- Peer Registration: The MAC address of the receiver is registered as a “peer” in the ESP-NOW network.
- Message Sending: A string
payload
is created and sent to the receiver usingesp_now_send
. The string is converted to a byte array usingpayload.c_str()
.
#include <esp_now.h>
#include <WiFi.h>
#include "const.h"
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 SendMessage()
{
String payload = "MY STRING";
esp_err_t result = esp_now_send(MAC_RECEIVER_1, (uint8_t*)payload.c_str(), payload.length());
if(result == ESP_OK)
{
Serial.println("Sent with success");
}
else
{
Serial.println("Error sending the data");
}
}
void static RegisterPeeks()
{
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, MAC_RECEIVER_1, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if(esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
}
else
{
Serial.print("Registered peer ");
}
}
void static InitEspNow()
{
if(esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
}
else
{
esp_now_register_send_cb(OnDataSent);
RegisterPeeks();
}
}
void setup()
{
Serial.begin(115200);
delay(2000);
WiFi.mode(WIFI_STA);
InitEspNow();
}
void loop()
{
SendMessage();
delay(2000);
}
The receiver code performs the following tasks:
- ESP-NOW Initialization: ESP-NOW is initialized and a callback is registered to handle received messages.
- Message Reception: When a message is received, the string is reconstructed from the received bytes and printed to the serial monitor.
#include <esp_now.h>
#include <WiFi.h>
#include "const.h"
void OnMessageReceived(const uint8_t* mac, const uint8_t* data, int len)
{
Serial.printf("Packet received from: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.printf("Bytes received: %d\n", len);
String payload;
payload.reserve(len);
for(auto i = 0; i < len; i++)
{
payload += (char)data[i];
}
Serial.println(payload);
}
void InitEspNow()
{
if(esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
else
{
esp_now_register_recv_cb(OnMessageReceived);
}
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
InitEspNow();
}
void loop()
{
}
const uint8_t MAC_SENDER_1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const uint8_t MAC_RECEIVER_1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const uint8_t* SENDERS_MACS[] = { MAC_RECEIVER_1 };
const uint8_t SENDERS_COUNT = sizeof(SENDERS_MACS) / sizeof(uint8_t*);
const uint8_t* RECEIVERS_MACS[] = { MAC_SENDER_1 };
const uint8_t RECEIVERS_COUNT = sizeof(RECEIVERS_MACS) / sizeof(uint8_t*);