Breadboard
docs
Example project · ESP32

ESP-NOW pair: two boards talking

Two ESP32-C3 boards share the virtual air and ping-pong ESP-NOW messages, each showing its own TX/RX tally and the last message received on its OLED. Watch the glowing packets fly between the chips, follow every frame in the 📡 Sniffer, and click either board for its radio state. One script runs on both; each derives its peer from its own MAC.

The ESP-NOW pair: two boards talking circuit as rendered by the simulator

What's on the bench

  • 2× Battery
  • 2× ESP32-C3
  • 2× OLED 128×64

The code

This MicroPython script runs on the emulated board every boot; edit it in the Code tab.

from machine import I2C, Pin
import framebuf, time
i = I2C(0, scl=Pin(9), sda=Pin(8))
buf = bytearray(1024)
fb = framebuf.FrameBuffer(buf, 128, 64, framebuf.MONO_VLSB)
for c in b'\xae\xd5\x80\xa8\x3f\xd3\x00\x40\x8d\x14\x20\x00\xa1\xc8\xda\x12\x81\xcf\xd9\xf1\xdb\x40\xa4\xa6\xaf':
    i.writeto(0x3c, bytes([0, c]))
def show():
    i.writeto(0x3c, b'\x00\x21\x00\x7f\x22\x00\x07')
    i.writeto(0x3c, b'\x40' + buf)

import network, espnow
w = network.WLAN(network.STA_IF)
w.active(True)
e = espnow.ESPNow()
e.active(True)
mac = w.config('mac')
peer = bytearray(mac)
peer[5] ^= 0x03  # …:c1 <-> …:c2 — the other board on the bench
e.add_peer(bytes(peer))
me = 'A' if mac[5] == 0xc1 else 'B'
print('board', me, 'ready, sending to', bytes(peer))
tx = 0; rx = 0; last = ""
while True:
    e.send(bytes(peer), 'ping %d from %s' % (tx, me)); tx += 1
    host, msg = e.recv(500)
    if msg:
        rx += 1; last = msg.decode()
        print('board', me, 'received:', last)
    fb.fill(0)
    fb.text('ESP-NOW  board ' + me, 0, 0)
    fb.hline(0, 10, 128, 1)
    fb.text('TX sent: %d' % tx, 0, 16)
    fb.text('RX recv: %d' % rx, 0, 30)
    fb.text(last[:16], 0, 46)
    show()
    time.sleep_ms(500)