Language: EN

esp-now-comunicacion-uno-a-muchos-esp32

One-to-Many Communication with ESP-NOW on ESP32

In previous tutorials, we have covered the basics of ESP-NOW, how to set up a one-to-one communication to send a simple variable, how to send a data structure (struct), a string, and a JSON.

In this tutorial, we will delve into using ESP-NOW to implement one-to-many communication.

For this, I will focus on the example of sending a string (just to pick one). But you can easily adapt it to send a struct, or JSON, or whatever you want.

What is One-to-Many Communication?

In a one-to-many communication, a single device (sender) sends data to multiple devices (receivers).

esp32-espnow-one-to-many

This type of communication is useful in applications where a central node needs to send commands or configurations to several nodes (such as in lighting control systems, sensor networks, or automation systems).

The main difference is that now, instead of having a receiver MAC, we have an array of MACs.

const uint8_t* RECEIVERS_MACS[] = { /* ... */ };
const uint8_t RECEIVERS_COUNT = sizeof(RECEIVERS_MACS) / sizeof(uint8_t*);

And we need to register all of them in the Sender.

void static RegisterPeek(uint8_t id)
{
	esp_now_peer_info_t peerInfo;
	memcpy(peerInfo.peer_addr, RECEIVERS_MACS[id], 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 ");
		Serial.println(id);
	}
}

void static RegisterPeeks()
{
	for(auto peek_id = 0; peek_id < RECEIVERS_COUNT; peek_id ++)
	{
		RegisterPeek(peek_id);
	}
}

Otherwise, it basically works the same way we have seen before.

Complete Example

Let’s look at the complete example 👇

  • ESP-NOW Initialization: ESP-NOW is initialized and a callback is registered to know if the message was sent successfully.
  • Peer Registration: The MAC addresses of the receivers are registered as “peers” in the ESP-NOW network.
  • Message Sending: A string is sent to each receiver using esp_now_send. The string is converted to a byte array using payload.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(uint8_t peek_id)
{
	String payload = "MY STRING";

	esp_err_t result = esp_now_send(RECEIVERS_MACS[peek_id], (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 RegisterPeek(uint8_t id)
{
	esp_now_peer_info_t peerInfo;
	memcpy(peerInfo.peer_addr, RECEIVERS_MACS[id], 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 ");
		Serial.println(id);
	}
}

void static RegisterPeeks()
{
	for(auto peek_id = 0; peek_id < RECEIVERS_COUNT; peek_id ++)
	{
		RegisterPeek(peek_id);
	}
}

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(0);

	delay(2000);
}
#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* RECEIVERS_MACS[] = { MAC_RECEIVER_1 };
const uint8_t RECEIVERS_COUNT = sizeof(RECEIVERS_MACS) / sizeof(uint8_t*);