como-usar-esp-now-en-esp32

Configuración Básica de ESP-NOW con ESP32

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.

esp32-espnow-one-to-one

Un emisor y un receptor

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