ESP-NOW Comunicación bidireccional entre placas ESP32

ESP-NOW es una tecnología de comunicación inalámbrica que permite una conexión bidireccional entre dos placas ESP32 de forma sencilla y eficiente. En este artículo, exploraremos cómo utilizar ESP-NOW para establecer una comunicación fluida entre dispositivos, abriendo un mundo de posibilidades para proyectos de IoT y automatización. ¡Sigue leyendo para descubrir cómo implementar esta poderosa herramienta en tus propios desarrollos!

En esta guía, le mostraremos cómo establecer una comunicación bidireccional entre dos placas ESP32 utilizando el protocolo de comunicación ESP-NOW. Por ejemplo, dos placas ESP32 intercambian valores de sensores (con un alcance en campo abierto de hasta 220 metros).

ESP-NOW Comunicación bidireccional entre placas ESP32

Mira el vídeo de introducción

Para obtener una introducción al protocolo ESP-NOW, mire el siguiente video:

Si desea obtener más información sobre ESP-NOW, puede leer esta guía: Primeros pasos con ESP-NOW (ESP32 con Arduino IDE).

Introducción de ESP-NOW

ESP-AHORA es un protocolo de comunicación sin conexión desarrollado por Espressif que permite la transmisión de paquetes cortos. Este protocolo permite que varios dispositivos se comuniquen entre sí sin WiFi.

ESP-NOW Comunicación bidireccional entre placas ESP32

Este 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 puede realizar comunicación unidireccional o bidireccional en varias configuraciones.

En este tutorial te mostraremos cómo establecer comunicación bidireccional entre dos placas ESP32.

ESP-NOW Comunicación bidireccional entre placas ESP32

Nota: Lea nuestra Guía de introducción a ESP-NOW para obtener una introducción completa al protocolo ESP-NOW con ESP32.

Descripción del proyecto

El siguiente diagrama proporciona una descripción general de alto nivel del proyecto que crearemos.

ESP-NOW Comunicación bidireccional entre placas ESP32
  • En este proyecto utilizamos dos placas ESP32. Cada placa está conectada a una pantalla OLED y un sensor BME280.
  • Cada placa recibe los valores de temperatura, humedad y presión de los sensores correspondientes.
  • Cada placa envía sus valores medidos a la otra placa vía ESP-NOW.
  • Cuando una placa recibe las medidas, las muestra en la pantalla OLED.
  • Después de enviar las lecturas, la placa muestra en la pantalla OLED si el mensaje se entregó correctamente.
  • Cada tarjeta debe conocer la dirección MAC de la otra tarjeta para poder enviar el mensaje.

En este ejemplo utilizamos comunicación bidireccional entre dos placas. Sin embargo, puede agregar más placas a esta configuración y hacer que todas las placas se comuniquen entre sí.

requisitos

Antes de continuar con este proyecto, asegúrese de revisar los siguientes requisitos previos.

Complemento ESP32 Arduino IDE

Programamos el ESP32 con Arduino IDE. Por lo tanto, antes de continuar con este tutorial, debes tener instalado el complemento ESP32 en tu IDE de Arduino. Siga las siguientes instrucciones:

  • Instalación de la Placa ESP32 en el IDE Arduino (Windows, Mac OS X y Linux)

Instalación de bibliotecas

Instale las siguientes bibliotecas en su IDE de Arduino. Estas bibliotecas se pueden instalar a través del Administrador de bibliotecas Arduino. Ir a Bosquejo > incluir biblioteca> Administrar bibliotecas y busque el nombre de la biblioteca.

Piezas requeridas

Para este tutorial necesitarás los siguientes elementos:

Puedes utilizar los enlaces anteriores o ir directamente MakerAdvisor.com/tools ¡Para encontrar todas las piezas para tus proyectos al mejor precio!

ESP-NOW Comunicación bidireccional entre placas ESP32

Obtenga la dirección MAC de la placa.

Para enviar mensajes entre cada placa, necesitamos saber su dirección MAC. Cada placa tiene una dirección MAC única (aprenda cómo obtener y cambiar la dirección MAC de ESP32).

Cargue el siguiente código en cada una de sus placas para obtener su dirección MAC.

/*
  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(){

}

Ver código sin formato

Después de cargar el código, presione el botón RST/EN y la dirección MAC debería aparecer en el monitor serie.

ESP-NOW Comunicación bidireccional entre placas ESP32

Para una identificación única, anote la dirección MAC de cada tarjeta.

ESP-NOW Comunicación bidireccional entre placas ESP32

Representación esquemática

Conecte una pantalla OLED y un sensor BME280 a cada placa ESP32. Siga el siguiente diagrama de circuito.

ESP-NOW Comunicación bidireccional entre placas ESP32

Puede utilizar la siguiente tabla como referencia al cablear el sensor BME280.

BME280 ESP32
Número de chasis 3,3 V
Dimensiones Dimensiones
SCL GPIO22
ASD GPIO21

También puede seguir la siguiente tabla para conectar la pantalla OLED al ESP32.

pantalla OLED ESP32
Dimensiones Dimensiones
VCC Número de chasis
SCL GPIO22
ASD GPIO21

Obtenga más información sobre cómo conectar múltiples periféricos I2C al ESP32.

Código ESP-NOW de comunicación bidireccional ESP32

Sube el siguiente código a cada uno de tus tableros. Antes de cargar el código, debes ingresar la dirección MAC de la otra placa (la placa a la que estás enviando datos).

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp-now-two-way-communication-esp32/
  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>

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Adafruit_BME280 bme;

// REPLACE WITH THE MAC Address of your receiver 
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Define variables to store BME280 readings to be sent
float temperature;
float humidity;
float pressure;

// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;

// Variable to store if sending data was successful
String success;

//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
    float temp;
    float hum;
    float pres;
} struct_message;

// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;

// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;

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");
  if (status ==0){
    success = "Delivery Success :)";
  }
  else{
    success = "Delivery Fail :(";
  }
}

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
  Serial.print("Bytes received: ");
  Serial.println(len);
  incomingTemp = incomingReadings.temp;
  incomingHum = incomingReadings.hum;
  incomingPres = incomingReadings.pres;
}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);

  // Init BME280 sensor
  bool status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Init OLED display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
 
  // 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;
  }
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
 
void loop() {
  getReadings();
 
  // Set values to send
  BME280Readings.temp = temperature;
  BME280Readings.hum = humidity;
  BME280Readings.pres = pressure;

  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
   
  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  updateDisplay();
  delay(10000);
}
void getReadings(){
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = (bme.readPressure() / 100.0F);
}

void updateDisplay(){
  // Display Readings on OLED Display
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("INCOMING READINGS");
  display.setCursor(0, 15);
  display.print("Temperature: ");
  display.print(incomingTemp);
  display.cp437(true);
  display.write(248);
  display.print("C");
  display.setCursor(0, 25);
  display.print("Humidity: ");
  display.print(incomingHum);
  display.print("%");
  display.setCursor(0, 35);
  display.print("Pressure: ");
  display.print(incomingPres);
  display.print("hPa");
  display.setCursor(0, 56);
  display.print(success);
  display.display();
  
  // Display Readings in Serial Monitor
  Serial.println("INCOMING READINGS");
  Serial.print("Temperature: ");
  Serial.print(incomingReadings.temp);
  Serial.println(" ºC");
  Serial.print("Humidity: ");
  Serial.print(incomingReadings.hum);
  Serial.println(" %");
  Serial.print("Pressure: ");
  Serial.print(incomingReadings.pres);
  Serial.println(" hPa");
  Serial.println();
}

Ver código sin formato

Así es como funciona el código

En tutoriales anteriores hemos explicado detalladamente cómo interactuar con la pantalla OLED y el sensor BME280. Aquí simplemente echamos un vistazo a las partes relevantes cuando se trata de ESP-NOW.

El código está bien comentado para que comprendas lo que hace cada línea de código.

Para usar ESP-NOW necesitas incluir las siguientes bibliotecas.

#include <esp_now.h>
#include <WiFi.h>

Ingrese la dirección MAC de la placa receptora en la siguiente línea:

uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};

Crea variables para almacenar valores de temperatura, humedad y presión del sensor BME280. Estos valores se envían a la otra placa:

// Define variables to store BME280 readings to be sent
float temperature;
float humidity;
float pressure;

Crea variables para almacenar los valores del sensor provenientes de la otra placa:

// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;

La siguiente variable almacena un mensaje de éxito cuando los valores medidos se han transmitido correctamente a la otra placa.

// Variable to store if sending data was successful
String success;

Cree una estructura que almacene lecturas de humedad, temperatura y presión.

typedef struct struct_message {
  float temp;
  float hum;
  float pres;
} struct_message;

Luego deberás crear dos instancias de esta estructura: una para recibir las métricas y otra para almacenar las métricas que se enviarán.

El Lecturas del BME280 guarda los valores medidos para enviar.

// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;

El lecturas en profundidad almacena los datos provenientes de la otra tarjeta.

// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;

Crear una variable de tipo esp_now_peer_info_t para almacenar información sobre el par.

esp_now_peer_info_t peerInfo;

Luego necesitamos crear dos funciones de devolución de llamada. Uno se llama cuando se envían datos y otro cuando se reciben datos.

Función de devolución de llamada OnDataSent()

El Datos enviados() La función se llama cuando se envían nuevos datos. Esta función simplemente indica si el mensaje se entregó correctamente o no. Si el mensaje se entrega exitosamente, la variable de estado devuelve 0, dándonos nuestro mensaje de éxito. “Entrega exitosa”:

Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0) {
  success = "Delivery Success :)";
}

Si el mensaje de éxito devuelve 1, significa que la entrega falló:

else {
  success = "Delivery Fail :(";
}

Función de devolución de llamada OnDataRecv()

El OnDataRecv() La función se llama cuando llega un nuevo paquete.

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {

Guardamos el nuevo paquete en lecturas en profundidad Estructura que creamos antes:

memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));

Imprimimos la longitud del mensaje en el monitor serie. Sólo puedes enviar 250 bytes en cada paquete.

Serial.print("Bytes received: ");
Serial.println(len);

Luego guarde las mediciones entrantes en las variables apropiadas. Para acceder a la variable de temperatura, lecturas en profundidad Estructura, todo lo que tienes que hacer es llamar lecturas entrantes.temp como sigue:

incomingTemp = incomingReadings.temp;

El mismo proceso se realiza para las demás variables:

incomingHum = incomingReadings.hum;
incomingPres = incomingReadings.pres;

configuración()

En el configuración()Inicialice ESP-NOW.

if (esp_now_init() != ESP_OK) {
  Serial.println("Error initializing ESP-NOW");
  return;
}

Entonces regístrate para el Cuando se envían datos Función de devolución de llamada.

esp_now_register_send_cb(OnDataSent);

Para enviar datos a otra placa, debes emparejarla como par. Las siguientes líneas registran y agregan un nuevo par.

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

Regístrese para el Al recibir datos Función de devolución de llamada.

 esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));

Cinta()

En el Cinta()Nosotros los llamamos obtener lecturas() Función encargada de recuperar nuevos valores de temperatura del sensor. Esta función se utilizará después Cinta().

A medida que recibimos nuevas lecturas de temperatura, humedad y presión, actualizamos las nuestras. BME280Leer Estructura con estos nuevos valores:

BME280Readings.temp = temperature;
BME280Readings.hum = humidity;
BME280Readings.pres = pressure;

Entonces podemos Lecturas del BME280 Estructura vía ESP-NOW:

// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));

if (result == ESP_OK) {
  Serial.println("Sent with success");
}
else {
  Serial.println("Error sending the data");
}

Finalmente, llame al actualizarPantalla() Función que actualiza la pantalla OLED con las lecturas de la otra placa ESP32.

updateDisplay();

El Cinta() se ejecuta cada 10 segundos.

En términos generales, así es como funciona el código. Debes cargar el código en ambos tableros. Solo necesitas cambiar el código con la dirección MAC de la placa a la que estás enviando datos.

Recomendaciones de literatura: Instrucciones para pantalla OLED con ESP32 e instrucciones para sensor BME280 con ESP32.

demostración

Después de cargar el código en ambas placas, la pantalla OLED debería mostrar las lecturas del sensor de la otra placa y un mensaje que indica la transmisión exitosa.

ESP-NOW Comunicación bidireccional entre placas ESP32

Como puede ver, funciona como se esperaba:

ESP-NOW Comunicación bidireccional entre placas ESP32

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í.

ESP-NOW Comunicación bidireccional entre placas ESP32

Envolver

En este tutorial, le mostramos cómo establecer comunicación bidireccional con dos placas ESP32 usando ESP-NOW. Este es un protocolo de comunicación muy versátil que puede enviar paquetes de hasta 250 bytes. El protocolo de comunicación ESP-NOW también se puede utilizar con placas ESP8266: Primeros pasos con ESP-NOW (ESP8266 NodeMCU con Arduino IDE).

Como ejemplo, le mostramos la interacción entre dos tarjetas, pero puede agregar varias tarjetas a su configuración. Sólo necesitas saber la dirección MAC de la tarjeta a la que estás enviando datos.

Publicaremos más tutoriales sobre ESP-AHORAasí que estad atentos. Además, escribe un comentario debajo sobre qué tutorial te gustaría ver con ESP-NOW.

Para obtener más información sobre la placa ESP32, eche un vistazo a nuestros recursos:

  • 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.

Error 403 The request cannot be completed because you have exceeded your quota. : quotaExceeded

Comunicación bidireccional entre placas ESP32 con ESP-NOW

En esta guía, mostraremos cómo establecer una comunicación bidireccional entre dos placas ESP32 utilizando el protocolo de comunicación ESP-NOW. Como ejemplo, dos placas ESP32 intercambiarán lecturas de sensores (con un alcance en campo abierto de hasta 220 metros ~ 722 pies).

Video de Introducción

Para una introducción al protocolo ESP-NOW, puedes ver el siguiente video.

Introducción a ESP-NOW

ESP-NOW es un protocolo de comunicación sin conexión desarrollado por Espressif que presenta una transmisión de paquetes cortos. Este protocolo permite que múltiples dispositivos se comuniquen entre sí sin usar Wi-Fi.

Este es un protocolo de comunicación rápido que se puede utilizar para intercambiar mensajes pequeños (hasta 250 bytes) entre placas ESP32. ESP-NOW es muy versátil y se puede tener comunicación unidireccional o bidireccional en diferentes disposiciones.

En este tutorial, te mostraremos cómo establecer una comunicación bidireccional entre dos placas ESP32.

Nota: Lee nuestra Guía de Inicio de ESP-NOW para obtener una introducción completa al protocolo ESP-NOW con ESP32.

Visión General del Proyecto

El diagrama siguiente muestra una visión general del proyecto que construiremos.

En este proyecto tendremos dos placas ESP32. Cada placa está conectada a una pantalla OLED y un sensor BME280.

Cada placa obtiene lecturas de temperatura, humedad y presión de sus respectivos sensores.

Cada placa envía sus lecturas a la otra placa a través de ESP-NOW.

Cuando una placa recibe las lecturas, las muestra en la pantalla OLED.

Después de enviar las lecturas, la placa muestra en la pantalla OLED si el mensaje se entregó con éxito.

Cada placa necesita conocer la dirección MAC de la otra placa para enviar el mensaje.

En este ejemplo, estamos utilizando una comunicación bidireccional entre dos placas, pero puedes añadir más placas a esta configuración y tener todas las placas comunicándose entre sí.

Requisitos Previos

Antes de continuar con este proyecto, asegúrate de verificar los siguientes requisitos.

  • Necesitas tener el complemento ESP32 instalado en tu Arduino IDE. Sigue la siguiente guía.

  • Instala las siguientes librerías en tu Arduino IDE. Estas librerías se pueden instalar a través del Administrador de Bibliotecas de Arduino.

  • Librerías OLED (Guía ESP32 OLED): Librería Adafruit_SSD1306 y Librería Adafruit_GFX

  • Librerías BME280 (Guía ESP32 BME280): Librería Adafruit_BME280 y Librería Adafruit Unified Sensor

Partes Necesarias

Para este tutorial necesitas las siguientes partes.

  • 2 placas de desarrollo ESP32

  • 2 sensores BME280

  • 2 pantallas OLED de 0.96 pulgadas

  • Protoboard

  • Cables jumper

Puedes encontrar todas las partes para tus proyectos al mejor precio en MakerAdvisor.com/tools.

Obtener la Dirección MAC de las Placas

Para enviar mensajes entre cada placa, necesitamos conocer su dirección MAC. Cada placa tiene una dirección MAC única.

Sube el siguiente código a cada una de tus placas para obtener su dirección MAC.

Código...

Después de subir el código, presiona el botón RST/EN, y la dirección MAC debería mostrarse en el Monitor Serie.

Toma nota de la dirección MAC de cada placa para identificarlas claramente.

Diagrama Esquemático

Conecta una pantalla OLED y un sensor BME280 a cada placa ESP32. Sigue el siguiente diagrama esquemático.

Puedes usar la siguiente tabla como referencia al cablear el sensor BME280.

  • BME280 ESP32
    • VIN 3.3V
    • GND GND
    • SCL GPIO 22
    • SDA GPIO 21

También puedes seguir la siguiente tabla para cablear la pantalla OLED al ESP32.

  • OLED Display ESP32
    • GND GND
    • VCC VIN
    • SCL GPIO 22
    • SDA GPIO 21

Aprende más sobre cómo conectar múltiples periféricos I2C con el ESP32.

Código de Comunicación Bidireccional ESP-NOW ESP32

Sube el siguiente código a cada una de tus placas. Antes de subir el código, necesitas ingresar la dirección MAC de la otra placa (la placa a la que estás enviando datos).

Código...

Cómo Funciona el Código

Hemos cubierto en gran detalle cómo interactuar con la pantalla OLED y con el sensor BME280 en tutoriales anteriores. Aquí, simplemente echaremos un vistazo a las partes relevantes cuando se trata de ESP-NOW.

El código está bien comentado para que entiendas qué hace cada línea de código.

Para usar ESP-NOW, necesitas incluir las siguientes librerías.

  • include

  • include

En la siguiente línea, inserta la dirección MAC de la placa receptora.

Crear variables para almacenar lecturas de temperatura, humedad y presión del sensor BME280. Estas lecturas se enviarán a la otra placa.

  • // Define variables to store BME280 readings to be sent
  • float temperature;
  • float humidity;
  • float pressure;

Crear variables para almacenar las lecturas del sensor que vienen de la otra placa.

  • // Define variables to store incoming readings
  • float incomingTemp;
  • float incomingHum;
  • float incomingPres;

La siguiente variable almacenará un mensaje de éxito si las lecturas se entregan correctamente a la otra placa.

  • // Variable to store if sending data was successful
  • String success;

Crear una estructura que almacene las lecturas de humedad, temperatura y presión.

typedef struct struct_message {
float temp;
float hum;
float pres;
} struct_message;

Luego, necesitas crear dos instancias de esa estructura. Una para recibir las lecturas y otra para almacenar las lecturas a enviar.

BME280Readings almacenará las lecturas a enviar.

  • // Create a struct_message called BME280Readings to hold sensor readings
  • struct_message BME280Readings;

incomingReadings almacenará los datos que vienen de la otra placa.

  • // Create a struct_message to hold incoming sensor readings
  • struct_message incomingReadings;

Crear una variable de tipo esp_now_peer_info_t para almacenar información sobre el punto de acceso.

  • esp_now_peer_info_t peerInfo;

Luego, necesitas crear dos funciones de devolución de llamada. Una se llamará cuando se envíen datos y otra cuando se reciban datos.

Función de devolución de llamada OnDataSent

La función OnDataSent se llamará cuando se envíen nuevos datos. Esta función simplemente imprime si el mensaje se entregó correctamente o no. Si el mensaje se entrega correctamente, la variable de estado devuelve 0, por lo que podemos establecer nuestro mensaje de éxito en "Éxito de entrega".

  • Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
  • if (status ==0) {
  • success = "Delivery Success :)";
  • }

Si el mensaje de éxito devuelve 1, significa que la entrega falló.

  • else {
  • success = "Delivery Fail :(";
  • }

Función de devolución de llamada OnDataRecv

La función OnDataRecv se llamará cuando llegue un nuevo paquete.

  • void OnDataRecv(const uint8_t mac, const uint8_t incomingData, int len) {

Guardamos el nuevo paquete en la estructura incomingReadings que creamos anteriormente.

  • memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));

Imprimimos la longitud del mensaje en el monitor serie. Solo puedes enviar 250 bytes en cada paquete.

  • Serial.print("Bytes received: ");
  • Serial.println(len);

Luego, almacenamos las lecturas entrantes en sus variables correspondientes. Para acceder a la variable de temperatura dentro de la estructura incomingReadings, simplemente necesitas llamar incomingReadings.temp de la siguiente manera.

  • incomingTemp = incomingReadings.temp;

El mismo proceso se realiza para las otras variables.

  • incomingHum = incomingReadings.hum;
  • incomingPres = incomingReadings.pres;

Configuración

En la configuración, inicializa ESP-NOW.

  • if (esp_now_init() != ESP_OK) {
  • Serial.println("Error initializing ESP-NOW");
  • return;
  • }

Luego, registra la función de devolución de llamada OnDataSent.

  • esp_now_register_send_cb(OnDataSent);

Para enviar datos a otra placa, necesitas emparejarla como punto de acceso. Las siguientes líneas registran y añaden un nuevo punto de acceso.

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

Registra la función de devolución de llamada OnDataRecv.

  • esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));

Ciclo

En el ciclo, llamamos a la función getReadings que es responsable de obtener nuevas lecturas de temperatura del sensor. Esa función se crea después del bucle.

Después de obtener nuevas lecturas de temperatura, humedad y presión, actualizamos nuestra estructura BME280Reading con esos nuevos valores.

  • BME280Readings.temp = temperature;
  • BME280Readings.hum = humidity;
  • BME280Readings.pres = pressure;

Luego, podemos enviar la estructura BME280Readings a través de ESP-NOW.

  • // Send message via ESP-NOW
  • esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));

  • if (result == ESP_OK) {
  • Serial.println("Sent with success");
  • }
  • else {
  • Serial.println("Error sending the data");
  • }

Finalmente, llama a la función updateDisplay que actualizará la pantalla OLED con las lecturas que vienen de la otra placa ESP32.

  • updateDisplay();

El bucle se ejecuta cada 10 segundos.

Eso es prácticamente cómo funciona el código. Debes subir el código a ambas placas. Solo necesitas modificar el código con la dirección MAC de la placa a la que estás enviando datos.

Para aprender más sobre la placa ESP32, consulta nuestros recursos.

  • Aprende ESP32 con Arduino IDE (curso en video + libro electrónico)
  • Programación MicroPython con ESP32 y ESP8266
  • Más recursos de ESP32

Gracias por leer.

Conclusión

En este tutorial, te hemos mostrado cómo establecer una comunicación bidireccional con dos placas ESP32 utilizando ESP-NOW. Este es un protocolo de comunicación muy versátil que se puede utilizar para enviar paquetes de hasta 250 bytes. El protocolo de comunicación ESP-NOW también se puede utilizar con placas ESP8266.

Como ejemplo, te mostramos la interacción entre dos placas, pero puedes añadir muchas placas a tu configuración. Solo necesitas conocer la dirección MAC de la placa a la que estás enviando datos.

Estaremos publicando más tutoriales sobre ESP-NOW, así que mantente atento. Además, escribe un comentario abajo diciendo qué tutorial te gustaría ver con ESP-NOW.

Para obtener más información sobre la placa ESP32, echa un vistazo a nuestros recursos.

  • Aprende ESP32 con Arduino IDE
  • Programación con MicroPython en ESP32 y ESP8266.

Gracias por leer.

4 comentarios en «ESP-NOW Comunicación bidireccional entre placas ESP32»

  1. ¡Esto es sorprendente! No tenía idea de que se podía lograr una comunicación bidireccional entre placas ESP32 con ESP-NOW. Definitivamente, voy a probarlo en mis proyectos. ¡Gracias por compartir esta valiosa información!

Deja un comentario