In CircuitPython, the aptly named espnow module provides ESP-NOW functionality. The wifi module is also used during setup to turn on the radio and set the channel to 6, where ESP-NOW magic happens.
The first step is to go to the Learn Guide for your board and update the TinyUSB bootloader for CircuitPython 10 and later. For example, set up the Feather ESP32-S2 with BME280 Sensor by going here and then installing CircuitPython 10.
For a second board, set up the ESP32-S2 Reverse TFT Feather to read messages sent to it from the first board.
Setup
To use ESP-NOW in CircuitPython you'll import espnow and wifi.
import espnow import wifi
Then, turn on the WiFi radio and start an access point on channel 6, which is the channel used by ESP-NOW. Immediately turn off the WiFi access because we aren't using it, we just needed to hack the channel.
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
Create an instance of ESP-NOW:
e = espnow.ESPNow()
import espnow
import wifi
# Initialize WiFi, set to channel 6 where ESP-NOW lives
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
# Create ESP-NOW instance
e = espnow.ESPNow()
Peer List & Send Modes
There are two main modes of communications in ESP-NOW: Broadcast Mode and Peer-to-Peer Mode.
Broadcast Mode
In Broadcast Mode, you can send messages without adding any specific peers -- any ESP-NOW device within range that's listening will receive the broadcast. This is done by specifying a special MAC address of \xff\xff\xff\xff\xff\xff and appending it to the peer list.
Then, in the main loop, e.send("Hello everyone", peer) sends a message to anyone listening.
import time
import wifi
import espnow
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
e = espnow.ESPNow()
peer = espnow.Peer(mac=b'\xff\xff\xff\xff\xff\xff', channel=6) # broadcast
e.peers.append(peer)
while True:
e.send("Hello everyone", peer)
time.sleep(2)
Peer-to-Peer Mode
In Peer-to-Peer mode, you'll explicitly add devices as peers using their MAC addresses.
# Add a peer device (replace with actual MAC address) peer = b'\xaa\xbb\xcc\xdd\xee\xff' e.peers.append(peer)
# find out MAC address
import wifi
wifi.radio.enabled=True
print("mac is:", wifi.radio.mac_address)
To receive the message being sent by the sender, run this code on your receiver boards:
import time
import wifi
import espnow
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
e = espnow.ESPNow()
while True:
if not e: # wait for a packet
continue
packet = e.read()
print("packet message:", packet.msg)
print("full packet:", packet)
With the sender running, you'll see a response in the REPL and on the TFT of the receiver like this:
packet message: b'Hello everyone'
full packet: ESPNowPacket(mac=b'|\xff\xee\xdd\xcc&', msg=b'Hello everyone', rssi=-14, time=1348919)
# ESP-NOW Sender
import time
import wifi
import espnow
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
e = espnow.ESPNow()
# broadcast to everyone:
peer = espnow.Peer(mac=b'\xff\xff\xff\xff\xff\xff', channel=6)
# or set specific mac addresses for peers:
# peer = espnow.Peer(mac=b'\xaa\xbb\xcc\xdd\xee\xff', channel=6)
e.peers.append(peer)
message = "Hello everyone"
my_mac_str = ":".join([f"{b:02x}" for b in wifi.radio.mac_address])
print("Starting sender on MAC:", my_mac_str)
while True:
try:
e.send(message, peer)
print("sent packet: ", message)
except Exception as ex:
print("exception:", ex)
time.sleep(2)
# ESP-NOW Receiver
import time
import wifi
import espnow
wifi.radio.start_ap(" ", "", channel=6, max_connections=0)
wifi.radio.stop_ap()
e = espnow.ESPNow()
my_mac_str = ":".join([f"{b:02x}" for b in wifi.radio.mac_address])
print("Starting receiver on MAC:", my_mac_str)
while True:
if not e: # wait for a packet
continue
packet = e.read()
mac_str = ":".join([f"{b:02x}" for b in packet.mac])
# Decode bytes to string for clean output
decoded_message = packet.msg.decode('utf-8')
print("received message:", decoded_message)
print("from MAC:", mac_str)
print("full packet:", packet)
time.sleep(0.3)
Page last edited August 05, 2025
Text editor powered by tinymce.