Imagine sending sensor data between two ESP32 boards in under 10 milliseconds, without any WiFi router, without any pairing, without any internet connection — just two boards talking directly to each other at 1 Mbps. That is exactly what the ESP-NOW protocol for ESP32 peer-to-peer communication enables. Developed by Espressif, ESP-NOW is a connectionless WiFi communication protocol that has become one of the most exciting tools in any Indian maker’s wireless toolkit. This tutorial covers everything from how ESP-NOW works to building a working multi-node sensor network.
What Is ESP-NOW and How Does It Work?
ESP-NOW is a short-range, low-power, peer-to-peer communication protocol developed by Espressif (the company behind ESP8266 and ESP32). It operates at the WiFi physical layer — using the 2.4 GHz radio — but bypasses the full WiFi stack. There is no TCP/IP, no DHCP, no routers, and no internet required.
ESP-NOW uses the WiFi radio in a special mode to send small packets (up to 250 bytes per transmission) directly from one ESP device’s MAC address to another. The latency is typically 1–10 ms — far faster than an MQTT publish which might take 50–500 ms over WiFi. The protocol is based on IEEE 802.11 action frames sent at a fixed 1 Mbps rate.
Key characteristics of ESP-NOW:
- Payload size: up to 250 bytes per packet
- Latency: 1–10 ms (typical)
- Max peers: 20 encrypted peers, unlimited unencrypted peers
- Range: 200–500m line-of-sight (similar to WiFi at the same power)
- Speed: 1 Mbps physical layer
- Encryption: optional AES-128 CCM (per peer)
- Supported on: ESP8266, ESP32, ESP32-S2, ESP32-S3, ESP32-C3
Devices are identified by their MAC addresses, which are fixed for each chip. You register peer MAC addresses before sending data. No handshake, no connection — just fire-and-forget packets with optional delivery callbacks.
Why Use ESP-NOW? Key Advantages
ESP-NOW solves several pain points that Indian makers commonly face with other wireless protocols:
No router dependency: Your sensor network works even if the WiFi router is down or not present. Perfect for field deployments, temporary setups at exhibitions, or off-grid projects.
Ultra-low latency: For RC vehicles, robotic arms, and real-time control applications, that 5ms latency vs 200ms WiFi MQTT round-trip is game-changing. ESP-NOW is fast enough for control loops.
Low power: Because there is no WiFi association overhead, ESP-NOW nodes can wake from deep sleep, send a sensor reading in ~100ms, and go back to sleep — consuming far less power than maintaining a full WiFi connection. Combine with ESP32 deep sleep for months of battery life.
Simultaneous WiFi + ESP-NOW: An ESP32 can run ESP-NOW AND be connected to WiFi at the same time, making it ideal for gateway nodes that collect data from ESP-NOW sensors and forward it over WiFi to MQTT or a cloud service.
Works with multiple boards: One master ESP32 can receive data from up to hundreds of sensor nodes, making star topology sensor networks straightforward to build.
Ai Thinker ESP32-CAM Development Board
ESP32-CAM with WiFi and Bluetooth — use as an ESP-NOW receiver/gateway that collects data from sensor nodes and uploads to cloud via WiFi.
Step 1: Get Your ESP32 MAC Address
Before setting up ESP-NOW communication, you need the MAC address of each ESP32 board. Upload this simple sketch to each board and note the MAC addresses from Serial Monitor:
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop() {}
You will get output like: MAC Address: 24:6F:28:AA:BB:CC. Write this down for every ESP32 board you plan to use. The receiver’s MAC address must be hardcoded into the sender’s code.
Step 2: ESP-NOW Sender (Transmitter) Code
The sender registers the receiver as a peer and sends a data structure periodically. Struct-based data exchange is the cleanest pattern for ESP-NOW:
#include <esp_now.h>
#include <WiFi.h>
// Replace with your receiver's MAC address
uint8_t receiverMAC[] = {0x24, 0x6F, 0x28, 0xAA, 0xBB, 0xCC};
typedef struct {
int nodeID;
float temperature;
float humidity;
int batteryLevel;
} SensorData;
SensorData myData;
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Send status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed!");
return;
}
esp_now_register_send_cb(onDataSent);
esp_now_peer_info_t peerInfo = {};
memcpy(peerInfo.peer_addr, receiverMAC, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer!");
return;
}
}
void loop() {
myData.nodeID = 1;
myData.temperature = 28.5; // replace with actual sensor read
myData.humidity = 65.2;
myData.batteryLevel = 85;
esp_now_send(receiverMAC, (uint8_t *)&myData, sizeof(myData));
delay(2000);
}
Step 3: ESP-NOW Receiver Code
The receiver registers a callback that fires every time a packet arrives. No polling, no blocking — purely interrupt-driven:
#include <esp_now.h>
#include <WiFi.h>
typedef struct {
int nodeID;
float temperature;
float humidity;
int batteryLevel;
} SensorData;
SensorData receivedData;
void onDataReceived(const esp_now_recv_info *info, const uint8_t *data, int len) {
memcpy(&receivedData, data, sizeof(receivedData));
Serial.printf("Node %d | Temp: %.1f°C | Humidity: %.1f%% | Battery: %d%%n",
receivedData.nodeID,
receivedData.temperature,
receivedData.humidity,
receivedData.batteryLevel);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW init failed!");
return;
}
esp_now_register_recv_cb(onDataReceived);
Serial.println("Receiver ready. Waiting for data...");
}
void loop() {
// Nothing needed — callback handles incoming data
}
Upload the sender code to one ESP32 and the receiver code to another. Open Serial Monitor on the receiver and watch data arrive every 2 seconds with sub-10ms latency. Congratulations — you have a working ESP-NOW link!
Ai Thinker ESP32-C3-01M Wi-Fi + BLE Module
Compact ESP32-C3 module with full ESP-NOW support, WiFi, and BLE — perfect for small battery-powered sensor nodes in an ESP-NOW network.
Building a Multi-Node Sensor Network
ESP-NOW really shines in multi-node deployments. Here are two common topologies:
Star Topology (Many-to-One): Multiple sensor nodes (senders) all transmit to a single gateway (receiver). The gateway uses the sender’s MAC address in the callback to identify which node sent the data. This is ideal for home automation sensors spread across different rooms.
On the receiver, use the info->src_addr (or mac_addr in older APIs) in the callback to log which node the data came from:
void onDataReceived(const esp_now_recv_info *info, const uint8_t *data, int len) {
Serial.printf("From: %02X:%02X:%02X:%02X:%02X:%02Xn",
info->src_addr[0], info->src_addr[1], info->src_addr[2],
info->src_addr[3], info->src_addr[4], info->src_addr[5]);
// process data...
}
Broadcast Mode: Send to broadcast MAC address {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} and all nearby ESP32 boards in receive mode will get the packet. Useful for time synchronization or global commands across all nodes.
Tips for reliable multi-node networks:
- Include a
nodeIDin your data struct so the receiver can identify senders without parsing MAC addresses - Add a sequence number to detect lost packets
- Use the
onDataSentcallback on senders to detect delivery failures and retry - Keep all devices on the same WiFi channel (channel 1 or 6 if also using WiFi)
- Add a timestamp to data packets for time-series logging
Using ESP-NOW and WiFi Simultaneously
One of the most powerful patterns for IoT projects in India is using an ESP32 as an ESP-NOW gateway — it receives data from battery-powered ESP-NOW sensor nodes via ESP-NOW, and simultaneously forwards that data to the cloud via WiFi (MQTT, HTTP, Firebase). This eliminates the need for every sensor node to maintain a full WiFi connection.
The key constraint: when using ESP-NOW and WiFi simultaneously, all ESP-NOW devices must use the same WiFi channel as the access point. Set your gateway to WiFi STA mode first (which assigns a fixed channel from the AP), then initialize ESP-NOW. All sensor nodes should be configured to use that same channel.
// Gateway: ESP-NOW + WiFi simultaneously
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
// Now init ESP-NOW — it inherits the WiFi channel
esp_now_init();
Sensor nodes sending to this gateway should use WiFi.mode(WIFI_STA) and set peerInfo.channel to match the gateway’s channel. Use esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE) on sensor nodes to force the correct channel.
Ai Thinker ESP32-C3-12F Wi-Fi + BLE Module
ESP32-C3 with larger 4MB flash and PCB antenna — excellent for ESP-NOW sensor nodes requiring OTA update capability and longer range.
Waveshare ESP32-C3 0.71inch Round Display Board
Compact ESP32-C3 with built-in display — perfect for an ESP-NOW receiver node that shows live sensor data from all nodes on screen.
Frequently Asked Questions
What is the maximum range of ESP-NOW?
In open-field line-of-sight conditions, ESP-NOW can reach 200–500 metres with standard PCB antennas. With external antenna modules (like the ESP32-CAM with external antenna), this extends to 1 km or more. Range decreases significantly through walls — expect 30–100m indoor range through concrete walls.
Can I use ESP-NOW with ESP8266?
Yes! ESP8266 also supports ESP-NOW, though the API is slightly different. ESP8266 and ESP32 can communicate with each other via ESP-NOW since they use the same underlying protocol. However, the ESP8266 is limited to fewer peers and has a different function signature for callbacks.
Is ESP-NOW secure? Can nearby devices intercept my data?
ESP-NOW supports optional AES-128 CCM encryption on a per-peer basis. For sensitive data, enable encryption by setting peerInfo.encrypt = true and providing a 16-byte LMK (Local Master Key) and PMK (Primary Master Key). Without encryption, packets are visible to anyone with a 2.4 GHz sniffer.
How many sensor nodes can one ESP32 gateway receive from?
For unencrypted communication, there is no hard limit on the number of peers that can send to a single receiver — you just need to handle the incoming data appropriately. For encrypted peers, the limit is 20. In practice, ESP-NOW star networks with 50–100 unencrypted sensor nodes sending to one gateway work reliably.
Does ESP-NOW work with ESP32-S3 and ESP32-C3?
Yes, ESP-NOW is supported across the entire ESP32 family including ESP32, ESP32-S2, ESP32-S3, and ESP32-C3. The API is identical across all variants in the Arduino-ESP32 framework, making code portable.
With ESP-NOW, your ESP32 boards can communicate instantly without any infrastructure. Whether you are building a smart home sensor network, a wireless RC controller, or an industrial monitoring system, Zbotic has all the ESP32 modules you need. Explore our Communication & Wireless Modules — shipped fast across India.
Add comment