How to Play With Espnow Between an Esp8266/Micropython and Linux
Fleetinghow to play with espnow in a esp8266 with micropython
on the server
Note that it wont work with the wifi chipset of raspberry pi, as they don’t support monitor mode. You will have to plug an external usb wifi adapter that supports it.
VERSION 0.8
IMPORT github.com/Konubinix/Earthfile AS e
espnow-src:
FROM alpine
WORKDIR /app
GIT CLONE https://github.com/ChuckMash/ESPythoNOW /app
SAVE ARTIFACT /app
espnow-build:
FROM e+alpine --extra_packages="ipython wireless-tools libpcap"
WORKDIR /app
COPY +espnow-src/app /app
DO e+PYTHON_VENV --base /app --packages "scapy==2.5.0"
espnow:
FROM +espnow-build
SAVE IMAGE espnow
earthly +espnow
Start with docker run -ti --rm --privileged --network=host konubinix/espnow
First, run sh ./prep.sh <interface> <channel>
to put make the interface listen to
the proper channel. I used sh ./prep.sh wlp2s0 4
in my setup.
then, run scapy
and try
from ESPythoNOW import *
def callback(from_mac, to_mac, msg):
print(f"ESP-NOW message from {from_mac} to {to_mac}: {msg}")
espnow = ESPythoNow(interface="wlp2s0", callback=callback)
espnow.start()
bytes.fromhex(espnow.local_hw_mac.replace(':', ''))
This will output the mac address to give to the board. Mine was b'|\\\xf8\xb3\xe0R'
.
on the board
mpremote
, then
import espnow
import network
ap = network.WLAN(network.WLAN.IF_AP)
ap.active(True)
ap.config(channel=4)
e = espnow.ESPNow()
e.active(True)
peer = b'|\\\xf8\xb3\xe0R'
e.add_peer(peer)
ap.config("mac")
It will connect to the computer and output the mac address of the board, mine was b'^\xcf\x7f\x0e\xe1\x19'
from the computer to the board
To receive data from the board, simply run
e.recv()
And from the scapy session in the computer
espnow.send(':'.join(format(x, '02x') for x in b'\\\xcf\x7f\x0e\xe1\x19'), b"Hello from the computer")
You should see it in the board.
from the board to the computer
The computer already listens to messages, using the callback in the code above.
In the board, run
e.send(b'|\\\xf8\xb3\xe0R', b'Hello from the board')
You should see it appear in the computer.
using aioespnow
mpremote mip install aioespnow
Adapting the example given in https://github.com/micropython/micropython-lib/tree/master/micropython/aioespnow
Also, using aiorepl (mpremote mip install aioespnow)
import network
import aioespnow
import asyncio
import aiorepl
sta = network.WLAN(network.WLAN.IF_STA)
sta.active(True)
# ap = network.WLAN(network.WLAN.IF_AP)
# ap.active(True)
# ap.config(channel=4)
e = aioespnow.AIOESPNow()
e.active(True)
peer = b'|\\\xf8\xb3\xe0R'
e.add_peer(peer)
# Send a periodic ping to a peer
async def heartbeat(e, peer, period=30):
while True:
if not await e.asend(peer, b'ping'):
print("Heartbeat: peer not responding:", peer)
else:
print("Heartbeat: ping", peer)
await asyncio.sleep(period)
# Echo any received messages back to the sender
async def echo_server(e):
async for mac, msg in e:
print("Echo:", msg)
try:
await e.asend(mac, msg)
except OSError as err:
if len(err.args) > 1 and err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND':
e.add_peer(mac)
await e.asend(mac, msg)
async def main(e, peer, timeout, period):
asyncio.create_task(heartbeat(e, peer, period))
asyncio.create_task(echo_server(e))
asyncio.create_task(aiorepl.task())
await asyncio.sleep(timeout)
asyncio.run(main(e, peer, 120, 10))