ESP-Now support for ESP32 (and ESP8266)

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Wed Mar 30, 2022 2:12 am

So is pairing an accessory device without encryption as simple as this?
Accessory:

Code: Select all

broadcast = b'\xff\xff\xff\xff\xff\xff'
add_peer(broadcast)
send(broadcast, '')
Central:

Code: Select all

peer = irecv()[0]
add_peer(peer)

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Wed Mar 30, 2022 4:10 am

BetterAutomations wrote:
Wed Mar 30, 2022 2:12 am
So is pairing an accessory device without encryption as simple as this?
Just tested it. I was almost correct.
Accessory:

Code: Select all

from esp import espnow
import network
w0=network.WLAN(network.STA_IF)
w0.active(True)
e = espnow.ESPNow()
e.init()
broadcast = b'\xff\xff\xff\xff\xff\xff'
e.add_peer(broadcast)
e.send(broadcast, 'Hello')
Central:

Code: Select all

from esp import espnow
import network
w0=network.WLAN(network.STA_IF)
w0.active(True)
e = espnow.ESPNow()
e.init()
while True:
    host, msg = e.irecv()
    if msg:
        e.add_peer(host)
        break
Accessory:

Code: Select all

>>> w0.config('mac')
b'\xe0\xe2\xe6L\x19\xf4'
>>>
Central:

Code: Select all

>>> e.get_peers()
((b'\xe0\xe2\xe6L\x19\xf4', b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 0, 0, False),)
>>> 

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Wed Mar 30, 2022 5:02 pm

Help? When I compile the firmware, the esp module doesn't seem to include espnow. I got it working with precompiled binaries (above) but not when I compile.

Code: Select all

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4252
load:0x40078000,len:12500
load:0x40080400,len:3392
entry 0x4008060c
could not find module '_boot.py'
MicroPython v1.13-1283-gc768704cf-dirty on 2022-03-30; 8MB/OTA/ESPNow module with ESP32
Type "help()" for more information.
>>> from esp import espnow
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: can't import name espnow
>>>
Here's the steps I took to compile for my WROVER with 8MB SPIRAM and 8MB flash:

Code: Select all

# git clone glenn20's code

. $HOME/esp-idf/export.sh

cd ~/glenn20/ports/esp32/

vi boards/GENERIC_OTA/mpconfigboard.h

# Change this #define:
#define MICROPY_HW_BOARD_NAME "8MB/OTA/ESPNow module with ESP32"

vi boards/GENERIC_OTA/sdkconfig.board

CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-ota.csv"
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_CACHE_WORKAROUND=y
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
CONFIG_SPIRAM_USE_MEMMAP=y

vi partitions-ota.csv
# Set up that as I always do

export FLASH_SIZE=8MB
export BOARD=GENERIC_OTA
make clean
make
Last edited by BetterAutomations on Wed Mar 30, 2022 6:16 pm, edited 1 time in total.

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Wed Mar 30, 2022 5:08 pm

I think I see why. I cloned glenn20's MicroPython fork which I assumed contained his ESPnow code, but it does not. I'll try to merge from his pull request instead.

Edit: Confirmed, that was the problem. I can now import espnow.

Code: Select all

cdevidal@ubuntuvm:~/glenn20/ports/esp32$ ls ~/glenn20/docs/library/espnow.rst
ls: cannot access '/home/cdevidal/glenn20/docs/library/espnow.rst': No such file or directory
cdevidal@ubuntuvm:~/glenn20/ports/esp32$

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Thu Mar 31, 2022 7:54 pm

Anyone have a problem with intermittent firing of on_recv callbacks? Mine intermittently work, even with a bare minimum implementation. I'm working on dynamic pairing with an unencrypted peer.

Central:

Code: Select all

import network
from esp import espnow

def cb(espn):
    while espn.poll():
        print(repr(espn.irecv()))

w0=network.WLAN(network.STA_IF)
w0.active(True)
espn = espnow.ESPNow()
espn.config(on_recv=cb)
espn.init()
Accessory:

Code: Select all

import network
from esp import espnow
espn = espnow.ESPNow()
w0=network.WLAN(network.STA_IF)
w0.active(True)
espn.init()
broadcast = b'\xff\xff\xff\xff\xff\xff'
espn.add_peer(broadcast)
Send a message:

Code: Select all

>>> espn.send(broadcast, 'Test')
True
>>>
Central just ignores it:

Code: Select all

>>>
>>>
But sometimes after a hard reset, it works:

Code: Select all

>>> (bytearray(b'4\xab\x95ZU`'), bytearray(b'Test'))

>>>

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Thu Mar 31, 2022 9:47 pm

Edit: Not caused by ESP-Now code. See this bug report. Solution: Use ESP-IDF 4.2+.

WARNING! The code from the PR "bricked" (broke the wifi radio) on two different ESP32s. (ESP32-WROVER-IE 8MB and ESP32-WROVER-E 16MB.) It starts with the errors below on wlan.connect(). The first time I got it, I couldn't fix it. I counted that chip as dead. Tried again with a second chip, and I got these errors again. I ran erase_flash and flashed it to the standard esp32spiram-20220117-v1.18.bin, unplugged from USB, and it came back to life.

Happened a third time and the second ESP32 is also now bricked (no wifi) :(

Edit: I tried both ESP32 again and both are now functional, after several unplugs and plugs. So it appears to only brick them for a few minutes or hours, or requires several unplugs.

Code: Select all

E (45979) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (45979) wifi:alloc eb len=76 type=2 fail, heap:151108

W (45979) wifi:m f probe req l=0

E (46099) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (46099) wifi:alloc eb len=76 type=2 fail, heap:151108

W (46099) wifi:m f probe req l=0

E (46229) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (46229) wifi:alloc eb len=76 type=2 fail, heap:151108

W (46229) wifi:m f probe req l=0

E (47079) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (47079) wifi:alloc eb len=76 type=2 fail, heap:151184

W (47079) wifi:m f probe req l=0

E (48809) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (48809) wifi:alloc eb len=76 type=2 fail, heap:151108

W (48809) wifi:m f probe req l=0

E (48939) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (48939) wifi:alloc eb len=76 type=2 fail, heap:151108

W (48939) wifi:m f probe req l=0

E (49059) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (49059) wifi:alloc eb len=76 type=2 fail, heap:151108

W (49059) wifi:m f probe req l=0

E (49189) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (49189) wifi:alloc eb len=76 type=2 fail, heap:151108

W (49189) wifi:m f probe req l=0

E (49309) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (49309) wifi:alloc eb len=76 type=2 fail, heap:151108

W (49309) wifi:m f probe req l=0

E (49439) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (49439) wifi:alloc eb len=76 type=2 fail, heap:151108

W (49439) wifi:m f probe req l=0

E (50279) wifi:esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
W (50279) wifi:alloc eb len=76 type=2 fail, heap:151052

W (50279) wifi:m f probe req l=0
I then ran erase_flash and flashed it to the standard esp32spiram-20220117-v1.18.bin, unplugged from USB, but now it's bricked :(

Code: Select all

MicroPython v1.18 on 2022-01-17; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>> import network
>>> sta_if = network.WLAN(network.STA_IF)
>>> sta_if.active(True)
>>> sta_if.connect('My SSID', 'Passphrase')
E (83336) wifi:sta is connecting, return error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: Wifi Internal Error
>>>
Last edited by BetterAutomations on Mon Apr 11, 2022 12:19 pm, edited 2 times in total.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ESP-Now support for ESP32 (and ESP8266)

Post by davef » Fri Apr 01, 2022 12:57 am

I often see this error:

Code: Select all

OSError: Wifi Internal Error
when my ESP32 Generic runs someone else program that only has a boot.py and a main.py

A hard reset sorts it then I shift most of the code in main to my_program.py and problem goes away.

Haven't seen this with any ESPNow on Generic.

By "bricked" do you mean the hardware is no longer useful?

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Fri Apr 01, 2022 1:25 am

BetterAutomations wrote:
Thu Mar 31, 2022 7:54 pm
Anyone have a problem with intermittent firing of on_recv callbacks? Mine intermittently work, even with a bare minimum implementation. I'm working on dynamic pairing with an unencrypted peer.

Central:

Code: Select all

import network
from esp import espnow

def cb(espn):
    while espn.poll():
        print(repr(espn.irecv()))

w0=network.WLAN(network.STA_IF)
w0.active(True)
espn = espnow.ESPNow()
espn.config(on_recv=cb)
espn.init()
Accessory:

Code: Select all

import network
from esp import espnow
espn = espnow.ESPNow()
w0=network.WLAN(network.STA_IF)
w0.active(True)
espn.init()
broadcast = b'\xff\xff\xff\xff\xff\xff'
espn.add_peer(broadcast)
Send a message:

Code: Select all

>>> espn.send(broadcast, 'Test')
True
>>>
Central just ignores it:

Code: Select all

>>>
>>>
But sometimes after a hard reset, it works:

Code: Select all

>>> (bytearray(b'4\xab\x95ZU`'), bytearray(b'Test'))

>>>
Hmm. Not just callbacks. Central is intermittently not responding at all.
Central:

Code: Select all

MicroPython v1.17-277-gb67384616-dirty on 2022-03-30; 8MB/OTA/ESPNow module with ESP32
Type "help()" for more information.
>>> import network
>>> from esp import espnow
>>> w0=network.WLAN(network.STA_IF)
>>> w0.active(True)
True
>>> espn = espnow.ESPNow()
>>> espn.init()
>>> espn.irecv()
Accessory:

Code: Select all

>>> while True:
...     espn.send(broadcast, 'Testing')
...     sleep(1)
...
True
True
True
Might? be hardware. When I reversed the hardware, the accessory is struggling to send, only occasionally gets through.

Code: Select all

>>> while True:
...     espn.send(broadcast, 'Test')
...     sleep(1)
...
False
False
True
False
False
False
False

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ESP-Now support for ESP32 (and ESP8266)

Post by davef » Fri Apr 01, 2022 2:21 am

The documentation says he has put a RSSI function in, but check his GitHub as I am not sure it has made its way into images.

BetterAutomations
Posts: 83
Joined: Mon Mar 20, 2017 10:22 pm

Re: ESP-Now support for ESP32 (and ESP8266)

Post by BetterAutomations » Fri Apr 01, 2022 2:39 am

davef wrote:
Fri Apr 01, 2022 12:57 am
I often see this error:

Code: Select all

OSError: Wifi Internal Error
when my ESP32 Generic runs someone else program that only has a boot.py and a main.py

A hard reset sorts it then I shift most of the code in main to my_program.py and problem goes away.

Haven't seen this with any ESPNow on Generic.

By "bricked" do you mean the hardware is no longer useful?
It was, yes. Even flashing to standard unmodified official uPy firmware binaries, I could no longer connect to WiFi. Pull the device off for some time and it resets itself and eventually starts working again. I don't know what's going on. Found a third ESP32 and am testing with that now. So far it hasn't bricked it. I could blame it on faulty hardware if one chip bricked, but a second bricked in exactly the same way.

And by the way, it bricked when using no one's code. Was just pasting raw commands into the REPL. See above.

Post Reply