En entradas anteriores, hemos cubierto los conceptos básicos de ESP-NOW, cómo configurar una comunicación 1 a 1 para enviar una variable simple, y cómo enviar una estructura de datos (struct).
En esta entrada, vamos a profundizar en el uso de ESP-NOW para enviar un string en una comunicación 1 a 1.
Enviar un string es una forma sencilla de mandar información. Pero además, nos va a “desbloquear” poder enviar datos en formato Json.
Eso lo veremos en las próximas entradas, al igual que cómo manejar comunicaciones 1 a muchos, muchos a 1, y muchos a muchos. Pero por ahora, nos centraremos en cómo enviar un string.
Enviando un string
Enviar un string no es demasiado distinto de enviar una struct (al final string es un objeto, que es similar a un struct).
Simplemente tenemos que saber convertir el string en un paquete de bytes para poderlo enviar. Por ejemplo, asi,
String payload = "MY STRING";
esp_err_t result = esp_now_send(MAC_RECEIVER_1, (uint8_t*)payload.c_str(), payload.length());
Y, ser capaces de componer un string a partir de los ratos recibidos. Lo cuál, podríamos hacer así.
String payload;
payload.reserve(len);
for(auto i = 0; i < len; i++)
{
payload += (char)data[i];
}
Así de fácil podemos enviar y recibir strings por a través de ESP-NOW.
Ejemplo completo
Vamos a ver el ejemplo completo 👇
El código del emisor realiza las siguientes tareas:
- Inicialización de ESP-NOW: Se inicializa ESP-NOW y se registra un callback para saber si el mensaje se envió correctamente.
- Registro del peer: Se registra la dirección MAC del receptor como un “peer” (par) en la red ESP-NOW.
- Envío del mensaje: Se crea un string
payload
y se envía al receptor utilizandoesp_now_send
. El string se convierte a un array de bytes utilizandopayload.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);
}
El código del receptor realiza las siguientes tareas:
- Inicialización de ESP-NOW: Se inicializa ESP-NOW y se registra un callback para manejar los mensajes recibidos.
- Recepción del mensaje: Cuando se recibe un mensaje, se reconstruye el string a partir de los bytes recibidos y se imprime en el monitor serial.
#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*);