Building an ESP-NOW-based Mesh Network with ESP32

Protonest IoT
4 min readMar 12, 2024

--

Introduction

In this guide, we’ll walk you through the steps to create a mesh network using ESP32 devices and the ESP-NOW protocol. ESP-NOW is a protocol developed by Espressif that enables multiple devices to communicate with each other in a peer-to-peer way without needing a Wi-Fi network. This is particularly useful for creating networks of IoT devices that need to send small bits of information to each other, like sensor readings or control signals.

What You’ll Need

Key Features of the ESP-NOW-based Mesh Network

  • Peer-to-Peer Communication: Directly connects ESP32 devices without the need for a Wi-Fi network, facilitating efficient data exchange.
  • Low Power Consumption: ESP-NOW is designed for IoT applications, emphasizing minimal power usage for battery-operated devices.
  • Simple Device Identification: Each device is assigned a unique ID, simplifying the process of targeting messages and commands.
  • Mesh Networking Capability: Enables messages to “hop” between devices, ensuring that commands reach their destination even if direct communication is not possible.

Step 1: Retrieve the MAC Addresses

  • Upload and run the ‘get_mac_address’ code on each of your slave ESP32 devices. This code should print each device’s MAC address to the Serial Monitor.
  • Note down the MAC addresses of each ESP32 device. It looks something like ‘B0:A7:32:81:EC:78’.
#include <WiFi.h>

void setup() {

Serial.begin(115200);


String mac = WiFi.macAddress();

// Print the MAC address to the Serial Monitor
Serial.print("MAC Address: ");
Serial.println(mac);
}

void loop() {

}

Step 2: Convert the MAC Addresses

  • Convert the noted MAC addresses to the format ‘0xB0, 0xA7, 0x32, 0x81, 0xEC, 0x78’. Basically, replace each ‘:’with a ‘, 0x’.

Step 3: Configure the ESP Codes

  • Open the ESP code for each device in your network.
  • Locate the lines where the MAC addresses of all other devices in the network are defined.
uint8_t device1[] = {0xB0, 0xA7, 0x32, 0x81, 0xEC, 0x78};
uint8_t device2[] = {0xD4, 0xD4, 0xDA, 0x5E, 0x22, 0x5C};
uint8_t device3[] = {0x84, 0xCC, 0xA8, 0x47, 0x9D, 0x7C};
  • Replace the MAC addresses in the code with the converted addresses from Step 2.
  • Change the ‘myID’ variable to a unique ID for each ESP32 device.
char myID = '3'; // Unique for each device.

Step 4: Upload the Codes

  • Upload the ESP code to each ESP32 device in your network.
#include <esp_now.h>
#include <WiFi.h>

typedef struct struct_message {
char command[5];
int msgID;
} struct_message;

struct_message myData;
int lastReceivedMsgID = -1;

char myID = '2'; //Change this, it's unique for each device


// You need to include MAC addresses of all devices in the network
uint8_t device1[] = {0xB0, 0xA7, 0x32, 0x81, 0xEC, 0x78};
uint8_t device2[] = {0xD4, 0xD4, 0xDA, 0x5E, 0x22, 0x5C};
uint8_t device3[] = {0x84, 0xCC, 0xA8, 0x47, 0x9D, 0x7C};

const int ledPin = LED_BUILTIN;
int msgCount = 0;

void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);

WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW Init Failed");
return;
}

esp_now_register_recv_cb(OnDataRecv);

esp_now_peer_info_t peerInfo;
peerInfo.channel = 0;
peerInfo.encrypt = false;

memcpy(peerInfo.peer_addr, device1, 6);
esp_now_add_peer(&peerInfo);
memcpy(peerInfo.peer_addr, device2, 6);
esp_now_add_peer(&peerInfo);
memcpy(peerInfo.peer_addr, device3, 6);
esp_now_add_peer(&peerInfo);
}

void loop() {
if (Serial.available() > 0) {
String command = Serial.readString();
command.trim();

strncpy(myData.command, command.c_str(), sizeof(myData.command));
myData.msgID = msgCount++;

sendCommand(myData);
}
}

void sendCommand(struct_message commandData) {
if (commandData.command[0] != myID) {
esp_now_send(device1, (uint8_t *)&commandData, sizeof(commandData));
esp_now_send(device2, (uint8_t *)&commandData, sizeof(commandData));
esp_now_send(device3, (uint8_t *)&commandData, sizeof(commandData));
}
}

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));

// If this message has already seen, skip it
if (myData.msgID == lastReceivedMsgID) {
return;
}

lastReceivedMsgID = myData.msgID;

String command = String(myData.command);

if (command.charAt(0) == myID) {
if (command.substring(1).equals("ON")) {
digitalWrite(ledPin, HIGH);
} else if (command.substring(1).equals("OFF")) {
digitalWrite(ledPin, LOW);
}
}
else {
sendCommand(myData);

}


}

Step 5: Test the System

  • Power on all the devices.
  • Open the Serial Monitor for any ESP32 device.
  • Enter a command (e.g., ‘1ON’ to turn on the LED on the device with ‘myID = ‘3’’) in the Serial Monitor and check if the corresponding action takes place on the correct device.

Step 6: Adding ESPs to the Network

  • To add more ESP32 devices to your system, repeat Steps 1 and 2 to get and convert the MAC address for each new device.
  • In the ESP code for each existing and new device, add more lines to define the new devices,
uint8_t device4[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
  • In the ‘setup()’ function of the ESP code for each existing and new device, add corresponding peer info for the new devices,
memcpy(peerInfo.peer_addr, device4, 6);
esp_now_add_peer(&peerInfo);
  • Assign a unique ‘myID’ for the new ESP32 device in its code.
  • Upload the updated ESP code to all ESP32 devices, including the new ones with unique IDs.
  • Test the extended system as described in Step 5.

Building a mesh network with ESP32 devices using the ESP-NOW protocol is a powerful way to create interconnected IoT applications.

By following the steps outlined in this guide, you can set up your network to communicate efficiently and expand it as needed.

Contact us for any consultations or projects related to ESP-NOW and mesh networks.

Protonest for more details.

Protonest specializes in transforming IoT ideas into reality. We offer prototyping services from concept to completion. Our commitment ensures that your visionary IoT concepts become tangible, innovative, and advanced prototypes.

Our Website: https://www.protonest.co/

Email: udara@protonest.co

If you enjoyed this article and would like to show some support, consider buying me a coffee on Ko-Fi.

Your support not only helps me keep creating content like this but also fuels me! ☕️📚

Thank you for being an amazing reader!

Here’s my Ko-Fi link: https://ko-fi.com/udarakumarasena

Cheers!

--

--

Protonest IoT
Protonest IoT

Written by Protonest IoT

We make your IoT ideas a reality

Responses (1)