Project 3: The “Invisible” Router (ESP-NOW Remote)

Build a routerless, instant-response remote using ESP-NOW that sends button and sensor data directly between two XIAO boards.

Quick Reference

Attribute Value
Difficulty Intermediate
Time Estimate 1-2 weeks
Main Programming Language C (ESP-IDF)
Alternative Programming Languages Arduino C++, MicroPython (limited)
Coolness Level High
Business Potential Medium (device-to-device control)
Prerequisites Wi-Fi basics, MAC addresses, ESP-IDF build/flash
Key Topics 802.11 MAC, ESP-NOW, peer lists, channel control

1. Learning Objectives

By completing this project, you will:

  1. Explain why ESP-NOW is Layer 2 and how it bypasses IP routing.
  2. Build a two-board system that exchanges data without a Wi-Fi router.
  3. Control the RF channel and handle channel mismatches.
  4. Implement a retry and acknowledgment strategy for high reliability.
  5. Capture and interpret serial logs that show RSSI and packet counters.

2. All Theory Needed (Per-Concept Breakdown)

2.1 Concept 1: 802.11 MAC Frames and ESP-NOW as Layer 2

Fundamentals

ESP-NOW is a vendor-specific protocol that uses Wi-Fi hardware but avoids the normal IP stack. It operates at the 802.11 MAC layer, which means data is sent as raw frames addressed by MAC addresses. Because it is Layer 2, there is no DHCP, no IP address, and no router required. The Wi-Fi radio must still be initialized, but it does not have to associate with an access point. Understanding the MAC layer is critical because ESP-NOW packets are still subject to Wi-Fi channel selection, frame types, and timing constraints. The device acts like a tiny MAC transmitter sending direct frames to peers.

Deep Dive into the Concept

The 802.11 stack is normally layered: physical layer (PHY) handles modulation, MAC handles addressing and medium access, and upper layers handle IP/TCP/UDP. ESP-NOW leverages the MAC layer and defines a vendor-specific action frame payload. These frames are transmitted using the Wi-Fi hardware but without joining a network. The sender specifies the destination MAC, and the receiver checks its peer list to accept the frame. Because this is still 802.11, the channel matters: a device on channel 1 will not hear frames sent on channel 6. ESP-NOW packets also share the same airtime as normal Wi-Fi traffic. If your environment is crowded, you can still have collisions and retries.

MAC addressing is the key identity mechanism. Each ESP32 has a unique MAC address for its Wi-Fi interface. ESP-NOW peers are defined by these MAC addresses. You must add a peer before sending, which registers the destination MAC and optionally security keys. This is why you cannot just broadcast to any MAC without setup. ESP-NOW supports unicast and broadcast. Broadcast can simplify discovery but is less reliable and can be noisy. Unicast allows the hardware to perform automatic retries and report status.

ESP-NOW frames have a payload limit (typically 250 bytes). That means you must design compact data structures. A common pattern is a small struct containing a sequence number, sensor value, and command. The receiver can use the sequence number to detect drops or duplicates. Because there is no TCP, you must design your own reliability if you need it. Some ESP-NOW implementations support acknowledgments at the MAC level, but you should still build your own application-level confirmation for critical commands.

Security is another aspect. ESP-NOW supports a peer key for encryption, but key distribution is your responsibility. For many projects, you can skip encryption for simplicity, but in real products you must handle it. The lack of IP does not mean lack of risk; a nearby attacker can still transmit frames. A simple mitigation is to validate the peer MAC and include a rolling code or sequence counter.

Finally, ESP-NOW coexists with Wi-Fi. If you also use Wi-Fi for IP, the radio can switch channels to the connected AP, which can disrupt ESP-NOW if its channel is different. For this project, you will avoid AP association to keep the channel fixed and stable. This makes ESP-NOW behave like a direct radio link, which is exactly what we want to study.

How this fits on projects

This project is entirely about MAC-layer communication without IP. You will use this knowledge again in the Wi-Fi sniffer project and in any direct device-to-device control system.

Definitions & Key Terms

  • 802.11 MAC: The layer that handles addressing and medium access.
  • Layer 2: Data link layer, below IP.
  • ESP-NOW: ESP32 vendor protocol using 802.11 action frames.
  • MAC address: Hardware address used for Wi-Fi communication.
  • Action frame: 802.11 management frame type used for vendor data.

Mental Model Diagram (ASCII)

App data
   |
   v
ESP-NOW payload
   |
   v
802.11 MAC frame
   |
   v
Wi-Fi PHY (channel)

How It Works (Step-by-Step)

  1. Initialize Wi-Fi in STA mode without connecting to an AP.
  2. Set a fixed channel (e.g., channel 1).
  3. Add peer MAC address to ESP-NOW peer list.
  4. Send payload as ESP-NOW frame.
  5. Receiver checks peer list and delivers payload.

Minimal Concrete Example

esp_now_peer_info_t peer = {0};
memcpy(peer.peer_addr, peer_mac, 6);
peer.channel = 1;
peer.ifidx = ESP_IF_WIFI_STA;
peer.encrypt = false;
ESP_ERROR_CHECK(esp_now_add_peer(&peer));

esp_now_send(peer_mac, (uint8_t*)&payload, sizeof(payload));

Common Misconceptions

  • “ESP-NOW uses IP.” It does not; it is Layer 2.
  • “Any channel works.” Sender and receiver must match channels.
  • “Broadcast is always reliable.” Broadcast has no ACKs.

Check-Your-Understanding Questions

  1. Why is ESP-NOW considered Layer 2?
  2. What happens if the receiver is on a different channel?
  3. Why must you add a peer before sending?

Check-Your-Understanding Answers

  1. It uses MAC frames and bypasses IP addressing and routing.
  2. The receiver will not hear the frames, so packets are lost.
  3. The ESP-NOW API requires peer registration for keying and routing.

Real-World Applications

  • Battery remotes and device-to-device control.
  • ESP32 mesh-like control without infrastructure.

Where You’ll Apply It

  • See Section 3.2 Functional Requirements and Section 5.10 Phase 2 in this project.
  • Also used in: P08 Wi-Fi Sniffer for frame parsing concepts.

References

  • ESP-IDF ESP-NOW documentation
  • “Computer Networks” (link layer chapters)
  • 802.11 standard summaries

Key Insights

ESP-NOW is Wi-Fi without IP: you control the MAC frame directly.

Summary

ESP-NOW leverages 802.11 MAC frames to send data without a router. You must control channels and peers to make it reliable.

Homework/Exercises to Practice the Concept

  1. List the MAC addresses of your two boards and explain how they are used.
  2. Compute the maximum payload size and design a minimal packet struct.

Solutions to the Homework/Exercises

  1. Use esp_read_mac() to print MAC and store it as peer address.
  2. Keep payload under 250 bytes; include a sequence number and data fields.

2.2 Concept 2: Peer Management, Reliability, and Channel Control

Fundamentals

ESP-NOW gives you a fast link, but it does not guarantee delivery. You must handle channel selection, retries, and loss detection yourself. A peer list defines which devices you accept data from. Reliability can be improved with acknowledgments and sequence numbers, but those add complexity. Channel control is critical because the Wi-Fi radio only listens to one channel at a time. If you do not fix the channel, the radio can wander, especially if you also use Wi-Fi connectivity. A robust design chooses a fixed channel, uses unicast with ACK status, and implements a small retry strategy for critical messages.

Deep Dive into the Concept

ESP-NOW callbacks provide a status for each send (success or failure). This status reflects MAC-level delivery, not application-level processing. You still need to confirm that the receiver actually acted on the data. The simplest approach is to include a sequence number in each packet and have the receiver send an acknowledgment packet with that sequence number. The sender tracks a retry counter and resends if no ACK arrives within a timeout. This forms a tiny reliability layer on top of ESP-NOW. You should limit retries to avoid congestion and battery drain.

Channel control is subtle. The Wi-Fi radio can be on only one channel at a time, so both devices must match. If you connect to an AP, the radio will be forced onto the AP’s channel. This can break ESP-NOW unless the AP shares the channel. A robust project avoids Wi-Fi connection entirely, sets a fixed channel, and logs it at boot. You can also implement a simple channel discovery: the sender broadcasts a “hello” on each channel in a scan list, and the receiver replies on the channel it hears. Once a channel is chosen, both fix to that channel.

Peer management requires correct MAC addresses and sometimes encryption keys. Each peer entry has properties such as channel, interface (STA), and encryption. ESP-NOW supports encryption with a local master key (LMK) per peer. Key management is beyond this project, but you should understand that unencrypted ESP-NOW is visible to any nearby listener with a sniffer. For a remote control, you can mitigate by using a rolling code (sequence number plus nonce) and rejecting old packets.

Reliability also depends on payload size and timing. Longer payloads consume more airtime and are more likely to collide. Avoid doing heavy work in the receive callback; move processing to a queue and handle it in a task. Otherwise, you can miss subsequent frames or trigger watchdog resets. Latency is usually low (few milliseconds) if your callback is lightweight and the channel is clean.

Finally, range and RSSI matter. ESP-NOW uses the same radio as Wi-Fi, so the range depends on antenna quality and environment. You should measure RSSI and log it with each packet to correlate reliability. If you see high packet loss at low RSSI, you can reduce payload size or increase retries. This kind of measurement is essential for turning a simple demo into a reliable product.

How this fits on projects

You will implement peer registration, sequence numbers, and a basic ACK. You will also control channel selection and log RSSI.

Definitions & Key Terms

  • Peer list: The list of MAC addresses allowed for ESP-NOW communication.
  • ACK: Acknowledgment packet confirming receipt.
  • Sequence number: Monotonic counter used to detect duplicates and loss.
  • Channel: Wi-Fi frequency slot (1-14 in 2.4 GHz).
  • RSSI: Received signal strength indicator.

Mental Model Diagram (ASCII)

Sender -> ESP-NOW pkt(seq=N) -> Receiver
Sender <- ACK(seq=N) ---------- Receiver

How It Works (Step-by-Step)

  1. Sender registers receiver as a peer with fixed channel.
  2. Sender transmits packet with seq number.
  3. Receiver checks seq number and processes data.
  4. Receiver sends ACK packet back.
  5. Sender marks delivery complete or retries.

Minimal Concrete Example

// Payload with sequence number
struct payload { uint32_t seq; uint16_t btn; int8_t rssi; };

Common Misconceptions

  • “Send status means the receiver handled it.” It only means MAC delivery.
  • “Broadcast is good for reliability.” Broadcast has no ACKs.
  • “Callbacks can do heavy work.” They should be minimal.

Check-Your-Understanding Questions

  1. Why do you need a sequence number?
  2. What is the risk of doing heavy work in a receive callback?
  3. How can you discover a working channel without a router?

Check-Your-Understanding Answers

  1. To detect lost or duplicate packets and match ACKs.
  2. You can miss frames or trigger watchdog resets.
  3. Scan channels by broadcasting a hello and waiting for a response.

Real-World Applications

  • Remote controls for robots or drones.
  • Sensor nodes that send data to a gateway without infrastructure.

Where You’ll Apply It

  • See Section 5.5 Questions to Guide Your Design and Section 6.2 Critical Test Cases.
  • Also used in: P02 Deep Sleep Champion for low-power communication planning.

References

  • ESP-IDF ESP-NOW API reference
  • “Computer Networks” (link layer reliability)

Key Insights

Reliability is your responsibility when you operate below IP.

Summary

ESP-NOW is fast but unforgiving. You must manage peers, channels, and retries to build a reliable remote.

Homework/Exercises to Practice the Concept

  1. Design a payload struct with sequence number, button state, and battery level.
  2. Sketch a retry strategy that gives up after 3 attempts.

Solutions to the Homework/Exercises

  1. Example: { uint32_t seq; uint8_t btn; uint16_t mv; }.
  2. Resend with 50 ms delay, max 3 retries, then log failure.

3. Project Specification

3.1 What You Will Build

A two-board ESP-NOW remote system: one board reads a button and potentiometer and transmits the data; the other board receives, logs RSSI, and triggers an action (LED toggle or buzzer).

3.2 Functional Requirements

  1. Peer Registration: Add receiver MAC as a peer.
  2. Fixed Channel: Both boards use the same channel.
  3. Packet Format: Include sequence number, button state, and analog value.
  4. Reliability: Implement ACK and up to 3 retries.
  5. Logging: Print RSSI, seq, and status for each packet.

3.3 Non-Functional Requirements

  • Latency: Button press results in action within 50 ms at short range.
  • Reliability: >95 percent packet success rate within 5 meters.
  • Stability: Runs for 30 minutes without watchdog reset.

3.4 Example Usage / Output

[ESP-NOW] Init OK channel=1
[Send] seq=12 btn=1 pot=512
[Recv] seq=12 rssi=-42 action=TOGGLE
[ACK ] seq=12 status=OK

3.5 Data Formats / Schemas / Protocols

struct packet {
    uint32_t seq;
    uint8_t button;
    uint16_t pot;
    uint16_t mv;
};

3.6 Edge Cases

  • Sender and receiver on different channels.
  • Receiver MAC address is incorrect.
  • Packet payload exceeds ESP-NOW size limit.

3.7 Real World Outcome

A routerless remote that toggles an action instantly, with logs showing RSSI and ACK status.

3.7.1 How to Run (Copy/Paste)

# Sender
idf.py -p /dev/ttyUSB0 flash monitor

# Receiver
idf.py -p /dev/ttyUSB1 flash monitor

3.7.2 Golden Path Demo (Deterministic)

  • Fixed channel 1.
  • Sequence number increments by 1 per packet.

Expected output:

[Send] seq=100 btn=1 pot=512
[Recv] seq=100 rssi=-40 action=TOGGLE
[ACK ] seq=100 status=OK

3.7.3 Failure Demo (Channel Mismatch)

If sender uses channel 6 and receiver uses channel 1:

[Send] seq=1 status=FAIL
[Recv] no packets

3.7.4 If CLI

No standalone CLI. Exit codes not applicable.

3.7.5 If Web App

Not applicable.

3.7.6 If API

No API is exposed. Error JSON shape not applicable.

3.7.7 If GUI / Desktop / Mobile

Not applicable.

3.7.8 If TUI

Not applicable.


4. Solution Architecture

4.1 High-Level Design

[Sender] -> ESP-NOW -> [Receiver]
(button/pot)          (action + log)

4.2 Key Components

| Component | Responsibility | Key Decisions | |———-|—————-|—————| | Sender task | Read inputs, build packet | Fixed period or on-change send | | Receiver task | Validate seq, trigger action | Use queue from callback | | ACK handler | Send and process ACKs | Simple timeout/retry | | Channel config | Fix channel | Channel 1 for 2.4 GHz |

4.3 Data Structures (No Full Code)

struct state {
    uint32_t seq;
    uint32_t last_ack;
};

4.4 Algorithm Overview

Key Algorithm: Reliable Send

  1. Build packet with seq number.
  2. Send via ESP-NOW.
  3. Wait for ACK or timeout.
  4. Retry up to 3 times.

Complexity Analysis:

  • Time: O(retries)
  • Space: O(1)

5. Implementation Guide

5.1 Development Environment Setup

idf.py set-target esp32c3
idf.py build

5.2 Project Structure

p03_esp_now_remote/
+-- sender/
|   +-- main.c
+-- receiver/
|   +-- main.c
+-- common/
    +-- packet.h

5.3 The Core Question You’re Answering

“Can devices communicate reliably without a router or internet?”

5.4 Concepts You Must Understand First

  1. 802.11 MAC addressing and channels
  2. ESP-NOW peer registration
  3. Sequence numbers and ACKs

5.5 Questions to Guide Your Design

  1. How will you discover and store the peer MAC address?
  2. What channel will you use and how will you enforce it?
  3. What is your retry timeout and max retries?

5.6 Thinking Exercise

If the receiver is on channel 1 and the sender on channel 6, how would you detect the mismatch from logs?

5.7 The Interview Questions They’ll Ask

  1. Why is ESP-NOW considered Layer 2?
  2. What is the maximum ESP-NOW payload size?
  3. How do you implement reliability without TCP?

5.8 Hints in Layers

Hint 1: Start with unicast to a fixed MAC before adding discovery.

Hint 2: Keep callbacks tiny; push data to a queue.

Hint 3: Log channel and MAC on both sides.

Hint 4: Use sequence numbers to detect loss.

5.9 Books That Will Help

| Topic | Book | Chapter | |——|——|———| | Link layer | Computer Networks | MAC chapters | | Wireless | 802.11 Wireless Networks | Frame formats |

5.10 Implementation Phases

Phase 1: One-Way Send (1 day)

Goals:

  • Send packets from sender to receiver.
  • Verify with logs.

Tasks:

  1. Initialize Wi-Fi and ESP-NOW.
  2. Add peer and send test packet.

Checkpoint: Receiver prints packets with RSSI.

Phase 2: Reliability (1-2 days)

Goals:

  • Add sequence numbers and ACKs.
  • Implement retry logic.

Tasks:

  1. Add ACK packets.
  2. Implement timeout and retries.

Checkpoint: Packet success >95 percent.

Phase 3: Input Integration (1 day)

Goals:

  • Read button and pot.
  • Trigger action on receiver.

Tasks:

  1. Add ADC read and button input.
  2. Map input to LED/buzzer action.

Checkpoint: Button press triggers action instantly.

5.11 Key Implementation Decisions

| Decision | Options | Recommendation | Rationale | |———-|———|—————-|———–| | Channel | Fixed vs dynamic | Fixed | Reliability and simplicity | | Reliability | None vs ACK + retry | ACK + retry | Better UX | | Payload size | Small vs large | Small | Lower loss, faster |


6. Testing Strategy

6.1 Test Categories

| Category | Purpose | Examples | |———-|———|———-| | Unit Tests | Validate packet struct sizes | sizeof checks | | Integration Tests | Two-board communication | End-to-end send/recv | | Edge Case Tests | Channel mismatch | Verify failure log |

6.2 Critical Test Cases

  1. Fixed Channel: Both devices on channel 1 communicate.
  2. Channel Mismatch: Communication fails cleanly with log.
  3. Retry Logic: Lost packet triggers retry and succeeds.

6.3 Test Data

seq=1..100
button=0/1
pot=0..1023

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

| Pitfall | Symptom | Solution | |——–|———|———-| | Wrong MAC | No packets received | Print MAC from esp_read_mac() | | Channel mismatch | Send fails | Set same channel on both | | Heavy callback | Watchdog resets | Queue work to a task |

7.2 Debugging Strategies

  • Print MAC and channel at boot on both devices.
  • Capture ESP-NOW status codes in send callback.

7.3 Performance Traps

  • Large payloads increase airtime and collision risk.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add a battery voltage field to the payload.
  • Add a second button and map to different actions.

8.2 Intermediate Extensions

  • Implement channel discovery by scanning channels.
  • Add AES encryption with peer keys.

8.3 Advanced Extensions

  • Implement a multi-peer remote with a small device registry.
  • Add a relay node that forwards packets to extend range.

9. Real-World Connections

9.1 Industry Applications

  • Home automation remotes without infrastructure.
  • Industrial controls in RF-hostile environments.
  • esp-now-example in ESP-IDF examples
  • ESP-Mesh for larger networks

9.3 Interview Relevance

  • Understanding Layer 2 communication and MAC addressing is common in networking interviews.

10. Resources

10.1 Essential Reading

  • ESP-IDF ESP-NOW documentation
  • “Computer Networks” (MAC layer chapters)

10.2 Video Resources

  • “Understanding Wi-Fi Frames” (tutorial)
  • “ESP-NOW in Practice” (conference talk)

10.3 Tools & Documentation

  • Wireshark (optional for frame capture)
  • ESP-IDF Wi-Fi/ESP-NOW APIs

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain why ESP-NOW is Layer 2.
  • I can control and verify the Wi-Fi channel.
  • I can implement a simple ACK retry scheme.

11.2 Implementation

  • Two boards exchange packets without a router.
  • Logs show RSSI, seq, and status.
  • Packet success >95 percent at short range.

11.3 Growth

  • I can describe how to secure ESP-NOW.
  • I can explain tradeoffs between broadcast and unicast.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Reliable unicast communication on a fixed channel.
  • Logs show seq numbers and RSSI.

Full Completion:

  • ACK + retry scheme implemented.
  • Input data triggers an action on receiver.

Excellence (Going Above & Beyond):

  • Channel discovery or multi-peer support.
  • Documented packet loss vs distance measurements.