¿Estás buscando una forma de establecer comunicación sin Wi-Fi entre tus dispositivos IoT de forma eficiente y sencilla? ¡Entonces el protocolo ESP-NOW es la solución perfecta para ti! En este artículo, te guiaremos paso a paso en cómo empezar a utilizar ESP-NOW en tu ESP32 con Arduino IDE. ¡No te lo pierdas!
Aprenda a usar ESP-NOW para intercambiar datos entre placas ESP32 programadas con Arduino IDE. ESP-NOW es un protocolo de comunicación sin conexión con transmisión de paquetes cortos desarrollado por Espressif. Este protocolo permite que varios dispositivos se comuniquen entre sí fácilmente.
Tenemos más tutoriales para ESP-NOW con el ESP32:
- ESP-NOW Comunicación bidireccional entre placas ESP32
- ESP-NOW con ESP32: envía datos a múltiples placas (uno a muchos)
- ESP-NOW con ESP32: reciba datos de múltiples placas (muchos a uno)
- ESP32: Panel de control del sensor del servidor web ESP-NOW (ESP-NOW + Wi-Fi)
IDE de Arduino
nosotros los programamos placa ESP32 con Arduino IDE, por lo que antes de continuar con este tutorial debes tener el complemento ESP32 instalado en tu Arduino IDE. Siga las siguientes instrucciones:
- Instalación de la Placa ESP32 en el IDE Arduino (Instrucciones para Windows, Mac OS X y Linux)
Nota: Tenemos una guía similar para la placa ESP8266 NodeMCU: Primeros pasos con ESP-NOW (ESP8266 NodeMCU con Arduino IDE)
Introducción de ESP-NOW
A continuación se muestra un vídeo de introducción al protocolo ESP-NOW (pruebe el proyecto que se muestra en este vídeo):
Según el sitio web de Espressif, ESP-NOW es un «Protocolo desarrollado por Espressif que permite que múltiples dispositivos se comuniquen entre sí sin WiFi. El protocolo es similar a la conexión inalámbrica de 2,4 GHz de bajo consumo (…). Se requiere emparejamiento antes de que los dispositivos puedan comunicarse. Una vez que se completa el emparejamiento, la conexión es segura y de igual a igual sin necesidad de un apretón de manos..”
Esto significa que una vez que se empareja un dispositivo, la conexión es permanente. En otras palabras, si una de sus placas pierde energía repentinamente o se reinicia, se conectará automáticamente con el par al reiniciar para continuar la comunicación.
ESP-NOW admite las siguientes funciones:
- Comunicaciones unicast cifradas y no cifradas;
- Dispositivos pares mixtos cifrados y no cifrados;
- Hasta 250 bytes Se puede transportar carga útil;
- Envío de una función de devolución de llamada que se puede configurar para informar a la capa de aplicación del éxito o fracaso de la transmisión.
Además, la tecnología ESP-NOW tiene las siguientes limitaciones:
- Pares cifrados limitados. En modo estación, se admiten un máximo de 10 pares cifrados; en modo estación SoftAP o SoftAP +, un máximo de 6;
- Se admiten varios pares no cifrados, pero su número total debe ser inferior a 20, incluidos los pares cifrados.
- La carga útil está limitada a 250 bytes..
En pocas palabras, ESP-NOW es un protocolo de comunicación rápido que permite intercambiar mensajes pequeños (hasta 250 bytes) entre placas ESP32.
ESP-NOW es muy versátil y le permite tener comunicación unidireccional o bidireccional en varias configuraciones.
Comunicación unidireccional ESP-NOW
Por ejemplo, pueden ocurrir los siguientes escenarios con la comunicación unidireccional:
- Una placa ESP32 envía datos a otra placa ESP32.
Esta configuración es muy fácil de implementar y es excelente para enviar datos de una tarjeta a otra, como valores de sensores o comandos ON y OFF para controlar GPIO.
- Un ESP32 “maestro” envía datos a varios “esclavos” ESP32
Una placa ESP32 envía comandos iguales o diferentes a diferentes placas ESP32. Esta configuración es ideal para construir algo parecido a un control remoto. Puedes tener varias placas ESP32 en casa controladas por una placa ESP32 principal.
- Un “esclavo” ESP32 que recibe datos de múltiples “maestros”.
Esta configuración es ideal si desea recopilar datos de múltiples nodos de sensores en una placa ESP32. Por ejemplo, esto se puede configurar como un servidor web para mostrar datos de todos los demás tableros.
Nota: En la documentación de ESP-NOW no hay términos como “remitente/maestro” y “receptor/esclavo”. Cada placa puede ser un transmisor o un receptor. Sin embargo, en aras de la claridad, utilizamos los términos «remitente» y «receptor» o «maestro» y «esclavo».
Comunicación bidireccional ESP-NOW
Con ESP-NOW, cada placa puede ser transmisor y receptor al mismo tiempo. Esto le permite establecer comunicación bidireccional entre las placas.
Por ejemplo, dos tarjetas pueden comunicarse entre sí.
Aprender como: Intercambie valores de sensores mediante comunicación bidireccional ESP-NOW.
Puede agregar más tarjetas a esta configuración y obtener algo que parece una red (todas las tarjetas ESP32 se comunican entre sí).
En resumen, ESP-NOW es ideal para construir una red en la que varias placas ESP32 puedan intercambiar datos entre sí.
ESP32: Obtener la dirección MAC de la placa
Para comunicarse a través de ESP-NOW, necesita la dirección MAC del receptor ESP32De esta manera sabrás a qué dispositivo estás enviando los datos.
Cada ESP32 tiene una dirección MAC única y así es como identificamos cada tarjeta para poder enviarle datos usando ESP-NOW (aprenda cómo obtener y cambiar la dirección MAC de ESP32).
Para obtener la dirección MAC de su placa, cargue el siguiente código.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include <esp_wifi.h>
void readMacAddress(){
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02xn",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop(){
}
Después de cargar el código, abra el monitor serie con una velocidad de baudios de 115200 y presione el botón ESP32 RST/EN. La dirección MAC debe imprimirse de la siguiente manera:
Guarde la dirección MAC de su placa, ya que la necesitará para enviar datos a la placa correcta a través de ESP-NOW.
Comunicación punto a punto unidireccional ESP-NOW
Para ayudarlo a comenzar con la comunicación inalámbrica ESP-NOW, crearemos un proyecto simple que muestra cómo enviar un mensaje de un ESP32 a otro. Un ESP32 es el «remitente» y el otro ESP32 es el «destinatario».
Enviamos una estructura que contiene una variable de tipo carbonizarse, En t, flotarY valor booleano. Luego puede modificar la estructura para enviar los tipos de variables apropiadas para su proyecto (por ejemplo, valores de sensores o variables booleanas para activar o desactivar algo).
Para una mejor comprensión, llamamos “transmisor” ESP32 No. 1 y “receptor” ESP32 No. 2.
Esto es lo que debemos incluir en el esquema del remitente:
- inicializar ESP-AHORA;
- Registre una función de devolución de llamada al enviar datos: el Cuando se envían datos La función se ejecuta cuando se envía un mensaje. Esto nos permite determinar si el mensaje se entregó correctamente o no.
- Agregue un dispositivo par (el receptor). Para hacer esto, necesita conocer la dirección MAC del destinatario.
- Envíe un mensaje al dispositivo par.
En el lado receptor, el boceto debe contener:
- inicializar ESP-AHORA;
- Regístrese para recibir la función de devolución de llamada (Al recibir datos). Esta es una función que se ejecuta cuando se recibe un mensaje.
- Dentro de esta función de devolución de llamada, almacena el mensaje en una variable para realizar cualquier tarea con esa información.
ESP-NOW funciona con funciones de devolución de llamada que se llaman cuando un dispositivo recibe un mensaje o cuando se envía un mensaje (que le indica si el mensaje se entregó correctamente o no).
Funciones útiles de ESP-NOW
Aquí hay una descripción general de las funciones ESP-NOW más importantes:
Nombre y descripción de la función |
esp_now_init() Inicializa ESP-NOW. Debes inicializar Wi-Fi antes de inicializar ESP-NOW. |
esp_now_add_peer() Llame a esta función para emparejar un dispositivo y pasar la dirección MAC del par como argumento. |
esp_now_send() Envía datos con ESP-NOW. |
esp_now_register_send_cb() Registre una función de devolución de llamada que se active cuando se envíen datos. Cuando se envía un mensaje, se llama a una función que indica si la entrega fue exitosa o no. |
esp_now_register_recv_cb() Registre una función de devolución de llamada que se active cuando se reciban datos. Cuando se reciben datos a través de ESP-NOW, se llama a una función. |
Para obtener más información sobre estas funciones, consulte la Documentación de ESP-NOW en Lea los documentos.
Bosquejo del transmisor ESP32 (ESP-NOW)
Aquí está el código para eso. Placa transmisora ESP32. Copie el código a su IDE de Arduino, pero no lo cargue todavía. Deberá realizar algunos cambios para que funcione para usted.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// Create a struct_message called myData
struct_message myData;
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("rnLast Packet Send Status:t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
// Set values to send
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = false;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
delay(2000);
}
Así es como funciona el código
Primero: cerrar el esp_now.h Y WiFi.h Bibliotecas.
#include <esp_now.h>
#include <WiFi.h>
En la siguiente línea debes insertar la dirección MAC del receptor ESP32.
uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};
En nuestro caso, la dirección MAC del destinatario es: 30:AE:A4:07:0D:64pero necesitas reemplazar esta variable con tu propia dirección MAC.
Luego crea una estructura que contenga el tipo de datos que queremos enviar. A esta estructura la llamamos Mensaje de estructura y contiene 4 tipos de variables diferentes. Puede cambiar esto para enviar otros tipos de variables.
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
Luego crea una nueva variable de tipo Mensaje de estructura Se llama… mis datos que almacena los valores de las variables.
struct_message myData;
Crear una variable de tipo esp_now_peer_info_t para almacenar información sobre el par.
esp_now_peer_info_t peerInfo;
A continuación, defina el Datos enviados() Función. Esta es una función de devolución de llamada que se ejecuta cuando se envía un mensaje. En este caso, esta función simplemente indica si el mensaje se entregó correctamente o no.
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("rnLast Packet Send Status:t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
En el configuración()Inicialice el monitor serie para fines de depuración:
Serial.begin(115200);
Configure el dispositivo como una estación WiFi:
WiFi.mode(WIFI_STA);
Inicializar ESP-NOW:
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
Después de inicializar ESP-NOW con éxito, registramos la función de devolución de llamada que se llamará cuando se envíe un mensaje. En este caso nos registramos para el Datos enviados() función creada previamente.
esp_now_register_send_cb(OnDataSent);
Después de eso, necesitamos emparejarnos con otro dispositivo ESP-NOW para enviar datos. Esto es lo que hacemos en las siguientes líneas:
//Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
//Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
En el Cinta()enviamos un mensaje vía ESP-NOW cada 2 segundos (puedes cambiar este tiempo de retraso).
Primero configuramos los valores de las variables de la siguiente manera:
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1,20);
myData.c = 1.2;
myData.d = false;
Recuerdalo mis datos es una estructura. Aquí asignamos los valores que queremos enviar dentro de la estructura. Por ejemplo, la primera línea asigna un carácter, la segunda línea asigna un int aleatorio, un flotante y una variable booleana.
Creamos este tipo de estructura para mostrarle cómo enviar los tipos de variables más comunes. Puedes cambiar la estructura para enviar otros tipos de datos.
Finalmente envía el mensaje de la siguiente manera:
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
Compruebe si el mensaje se envió correctamente:
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
El Cinta() se ejecuta cada 2000 milisegundos (2 segundos).
delay(2000);
Bosquejo del receptor ESP32 (ESP-NOW)
Descargue el siguiente código a su Placa receptora ESP32.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("Bool: ");
Serial.println(myData.d);
Serial.println();
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
}
Así es como funciona el código
De manera similar al remitente, comience a integrar las bibliotecas:
#include <esp_now.h>
#include <WiFi.h>
Cree una estructura para recibir los datos. Esta estructura debe ser idéntica a la estructura definida en el esquema del transmisor.
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
Crear un… Mensaje de estructura Nombre de la variable mis datos.
struct_message myData;
Cree una función de devolución de llamada que se llamará cuando el ESP32 reciba los datos a través de ESP-NOW. La función se llama onDataRecv() y debería aceptar múltiples parámetros como este:
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
Copiamos el contenido del datos entrantes variable de datos en el mis datos Variable.
memcpy(&myData, incomingData, sizeof(myData));
Ahora este mis datos La estructura contiene varias variables con los valores enviados por el transmisor ESP32. Para acceder a la variable APor ejemplo, solo necesitamos llamar misdatos.a.
En este ejemplo simplemente imprimimos los datos recibidos, pero en una aplicación práctica puedes imprimir los datos en una pantalla, por ejemplo.
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("Bool: ");
Serial.println(myData.d);
Serial.println();
En el configuración()inicialice el monitor serie.
Serial.begin(115200);
Configure el dispositivo como una estación WiFi.
WiFi.mode(WIFI_STA);
Inicializar ESP-NOW:
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
Regístrese para que se llame a una función de devolución de llamada cuando se reciban datos. En este caso nos registramos para el OnDataRecv() Función que fue creada previamente.
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
Probando la comunicación ESP-NOW
Cargue el boceto del transmisor en la placa del transmisor ESP32 y el boceto del receptor en la placa del receptor ESP32.
Ahora abra dos ventanas de Arduino IDE. Uno para el receptor y otro para el transmisor. Abra el monitor serie para cada tarjeta. Debería haber un puerto COM diferente para cada tarjeta.
Esto es lo que deberías obtener en la página del remitente.
Y eso es lo que deberías obtener del lado receptor. Tenga en cuenta que la variable Int cambia entre cada lectura recibida (porque la configuramos en un número aleatorio en el lado del remitente).
Probamos el alcance de comunicación entre las dos placas y pudimos lograr una comunicación estable de hasta 220 metros (aproximadamente 722 pies) en campo abierto. En este experimento, ambas antenas integradas del ESP32 se alinearon entre sí.
Envolver
Hemos intentado que nuestros ejemplos sean lo más simples posible para ayudarlo a comprender cómo funciona todo. Existen otras funciones relacionadas con ESP-NOW que pueden resultar útiles en sus proyectos, como por ejemplo: Por ejemplo: administrar pares, eliminar pares, buscar dispositivos esclavos, etc. Para ver un ejemplo completo, consulte su IDE de Arduino en archivo > Ejemplos > ESP32 > ESPNow y seleccione uno de los bocetos de muestra.
Esperamos que esta introducción a ESP-NOW le haya resultado útil. Como ejemplo introductorio simple, le mostramos cómo enviar datos como una estructura de un ESP32 a otro. La idea es sustituir los valores de la estructura por valores de sensores o estados GPIO, por ejemplo.
Además, con ESP-NOW cada placa puede ser transmisor y receptor al mismo tiempo. Una placa puede enviar datos a varias placas y también recibir datos de varias placas.
También tenemos un tutorial sobre ESP-NOW con ESP8266: Introducción a ESP-NOW (ESP8266 NodeMCU con Arduino IDE).
Para obtener más información sobre la placa ESP32, asegúrese de consultar nuestros recursos:
- ESP-NOW Comunicación bidireccional entre placas ESP32
- Aprenda ESP32 con Arduino IDE (curso en vídeo + libro electrónico);
- Programación MicroPython con ESP32 y ESP8266
- Más recursos de ESP32…
Gracias por leer.
Introducción a ESP-NOW
Aprenda a utilizar ESP-NOW para intercambiar datos entre placas ESP32 programadas con Arduino IDE. ESP-NOW es un protocolo de comunicación sin conexión desarrollado por Espressif que permite la transmisión de paquetes cortos. Este protocolo permite que múltiples dispositivos se comuniquen entre sí de manera sencilla.
Preguntas Frecuentes
-
¿Qué es ESP-NOW?
ESP-NOW es un protocolo desarrollado por Espressif que permite a múltiples dispositivos comunicarse entre sí sin necesidad de utilizar Wi-Fi. El protocolo es similar a la conectividad inalámbrica de baja potencia de 2.4 GHz…
-
¿Cómo puedo iniciar con ESP-NOW en ESP32 con Arduino IDE?
Para comenzar a utilizar ESP-NOW en ESP32 con Arduino IDE, debe tener instalado el complemento ESP32 en su Arduino IDE. Siga la guía de instalación…
-
¿Cuáles son las limitaciones de ESP-NOW?
ESP-NOW tiene algunas limitaciones, como el soporte para un número limitado de dispositivos cifrados, un límite en el tamaño de la carga útil, etc…
-
¿Qué tipo de comunicación puedo establecer con ESP-NOW?
ESP-NOW es muy versátil y puede configurarse para tener comunicación unidireccional o bidireccional. Por ejemplo, puede enviar datos desde una placa ESP32 a otra…
Referencias Externas
¡Qué buena introducción al ESP-NOW! Me parece genial que hayan compartido este tutorial para los que estamos empezando a explorar con el ESP32. ¡Voy a probarlo! ¡Gracias!
¡Vaya guía tan clara y útil! Me encanta la manera en que explican todo sobre ESP-NOW en el ESP32 con Arduino IDE. Definitivamente voy a probarlo. ¡Gracias por el aporte!
¡Qué fantástico tutorial! Me encanta cómo explican paso a paso cómo comenzar a utilizar ESP-NOW en el ESP32 con Arduino IDE. Definitivamente lo probaré. ¡Gracias por la info!
¡Interesante tutorial! Me gustaría probarlo en mi ESP32. ¡Gracias por compartir!