Ya hemos visto que es el ESP-NOW, una tecnología de Espressif para comunicar inalámbricamente ESP32 (sin necesitar Wi-Fi).
Ahora vamos a empezar a ver cómo utilizarlo este primer ejemplo. De momento, vamos a ver cómo mandar un único valor primitivo (un float) entre dos dispositivos.
En las siguientes entradas lo iremos complicando, con comunicación de muchos a muchos, enviando JSON, etc. Pero de momento, para empezar, es suficiente.
Configurando el ESP32
Antes de poder usar ESP-NOW debemos añadir las bibliotecas necesarias.
#include <WiFi.h>
#include <esp_now.h>
A continuación, debemos configurar el ESP32 para funcionar en el modo adecuado. Para ello, debemos utilizar el siguiente código en el setup()
:
void setup() {
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error al iniciar ESP-NOW");
return;
}
esp_now_register_send_cb(onDataSent);
esp_now_register_recv_cb(onDataReceived);
}
WiFi.mode(WIFI_STA)
: Configura el ESP32 en modo cliente Wi-Fi, para que pueda conectarse a un punto de acceso Wi-Fi.esp_now_init()
: Inicializa la librería ESP-NOW.esp_now_register_send_cb()
: Registra una función de callback que se ejecutará cuando se envíen datos a otro dispositivo ESP32.esp_now_register_recv_cb()
: Registra una función que se ejecutará cuando se reciban datos de otro dispositivo ESP32.
Enviar datos
Para que un ESP32 pueda mandar información a otro, primero tenemos que “registrar” la MAC del dispositivo con el que queremos comunicar. Lo haríamos así
void static RegisterPeeks()
{
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, RECEIVER_MAC_ADDRESS, 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 ");
}
}
Ahora, podemos enviar través de ESP-NOW en cualquier parte de nuestro código. Para enviar datos a otro dispositivo ESP32, utilizamos la función esp_now_send()
:
uint8_t dataToSend = 42; // Datos que queremos enviar
esp_now_send(otherDeviceMacAddress, &dataToSend, sizeof(dataToSend));
otherDeviceMacAddress
: La dirección MAC del otro dispositivo ESP32 al que queremos enviar los datos.&dataToSend
: Puntero a los datos que queremos enviar.sizeof(dataToSend)
: El tamaño de los datos que estamos enviando.
Recibir datos
Para recibir datos, debemos definir las funciones de callback onDataSent()
y onDataReceived()
que se ejecutarán cuando se envíen o reciban datos a través de ESP-NOW:
void onDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
// Código a ejecutar cuando se envían datos a otro dispositivo ESP32
}
void onDataReceived(uint8_t *mac_addr, uint8_t *data, uint8_t len) {
// Código a ejecutar cuando se reciben datos de otro dispositivo ESP32
}
Ejemplo completo
Vamos a verlo todo junto en un ejemplo completo de cómo configurar y utilizar la comunicación ESP-NOW entre dos ESP32.
Os lo he separado por archivitos para que lo tengáis ordenado y listo para usar en vuestro proyecto (tendréis que sustituir las MAC en el fichero de constantes).
// sender
#include <esp_now.h>
#include <WiFi.h>
#include "const.h"
void OnDataSent(const uint8_t* mac_addr, esp_now_send_status_t status)
{
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void SendMessage()
{
float myFloat = 123.456;
uint8_t payload[sizeof(float)];
memcpy(payload, &myFloat, sizeof(float));
esp_err_t result = esp_now_send(MAC_RECEIVER_1, (uint8_t*)&payload, sizeof(float));
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();
delayMicroseconds(200);
}
// receiver
#include <esp_now.h>
#include <WiFi.h>
#include "const.h"
void OnMessageReceived(const uint8_t* mac, const uint8_t* data, int len)
{
float receivedFloat;
memcpy(&receivedFloat, incomingData, sizeof(float));
Serial.println(receivedFloat);
}
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 };