ESP-Now support for ESP32 (and ESP8266)

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
User avatar
glenn20
Posts: 132
Joined: Mon Jun 04, 2018 10:09 am

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

Post by glenn20 » Sat Jan 02, 2021 12:57 am

davef wrote:
Fri Jan 01, 2021 8:01 pm
I think you are suggesting that when you get a timeout just ignore the message.
Yes, you should just ignore the message on timeout. However, your response has clearly shown me that it can be confusing that the tuple still contains the previous message data. I will change that so the bytearrays are cleared on timeout. That should be in my next commit. Hopefully I can squeeze it into the esp8266 code restrictions :-).
Appreciate your support as ESPNow seems the best solution for a reliable dedicated control link on the ESP devices.
Glad to hear it is useful to someone other than myself. Good luck.

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 » Tue Jan 05, 2021 9:12 pm

Just some observations on the ESP32 image:

1) can't use AP

Code: Select all

send command
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "local.py", line 23, in <module>
OSError: (-12396, 'ESP_ERR_ESPNOW_IF')

line 23:
e.send(peer, "pump off", True)
Don't really care, but in STA mode on the ESP32 board that I have the host doesn't see any network connection and therefore can't use WebREPL. STA mode on the ESP8266 image shows a network connection and WebREPL works.

2) Ctrl D in rshell doesn't do as good a job as a re-boot

For the ESP8266 remote device, after a re-flash, doesn't show that issue with the previous command running after 5 minutes. Sorry, but I don't have the skills to debug these issues.

User avatar
glenn20
Posts: 132
Joined: Mon Jun 04, 2018 10:09 am

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

Post by glenn20 » Tue Jan 05, 2021 11:27 pm

davef wrote:
Tue Jan 05, 2021 9:12 pm
Just some observations on the ESP32 image:

1) can't use AP

Code: Select all

send command
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "local.py", line 23, in <module>
OSError: (-12396, 'ESP_ERR_ESPNOW_IF')
That error code comes from the underlying Espressif ESPNOW stack. It signifies that the peer is not associated with an active() interface (see return codes of esp_now_send() at https://docs.espressif.com/projects/esp ... p_now.html).

The ESP32 effectively has two wifi interfaces (STA and AP) which can each be activated independently (each has a separate MAC address too). When you add_peer() you specify which interface that peer is to be associated with. So, if you wish to send a message to a peer via the AP interface you should register the peer with THAT interface, eg

Code: Select all

e.add_peer(peer_mac, ifidx=network.AP_IF)
The default interface for add_peer is network.STA_IF (=0).

e.get_peers() will show you which peers are registered with which interfaces.

The error message is just what I would expect if you register the peer with STA_IF (by default) but do not set STA_IF to active(True).

This is just the way the Espressif ESPNow protocl works - ie. it is working as expected. I confess it was confusing to me at first till I understood the nature of the esp32 wifi interfaces and the espressif espnow protocol.

Remember also that all peers must agree to use the same wifi chanel and encryption keys as well.
Don't really care, but in STA mode on the ESP32 board that I have the host doesn't see any network connection and therefore can't use WebREPL. STA mode on the ESP8266 image shows a network connection and WebREPL works.
I don't use the webrepl much, but I don't expect any issues with the webrepl are affected by my espnow module. (Of course, if you want to use the webrepl on STA_IF you need to connect to a wifi network.)
2) Ctrl D in rshell doesn't do as good a job as a re-boot
Yes, crtl-D just does a soft reset of the micropython interpreter. A machine.reset() will reinitialise the hardware (including wifi interfaces) and possibly parts of the underlying Espressif software stack (not sure about the latter part).

User avatar
glenn20
Posts: 132
Joined: Mon Jun 04, 2018 10:09 am

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

Post by glenn20 » Tue Jan 05, 2021 11:34 pm

glenn20 wrote:
Tue Jan 05, 2021 11:27 pm
The ESP32 effectively has two wifi interfaces (STA and AP) which can each be activated independently (each has a separate MAC address too). When you add_peer() you specify which interface that peer is to be associated with. So, if you wish to send a message to a peer via the AP interface you should register the peer with THAT interface, eg

Code: Select all

e.add_peer(peer_mac, ifidx=network.AP_IF)
The default interface for add_peer is network.STA_IF (=0).

e.get_peers() will show you which peers are registered with which interfaces.

The error message is just what I would expect if you register the peer with STA_IF (by default) but do not set STA_IF to active(True).

This is just the way the Espressif ESPNow protocol works - ie. it is working as expected. I confess it was confusing to me at first till I understood the nature of the esp32 wifi interfaces and the espressif espnow protocol.
Oh - and it may also be useful to realise that you can use the AP_IF for your webrepl at the same time as you use STA_IF for your ESPNow communications. Eg. setup your ESP32 AP, set network.WLAN(network.STA_IF).active(True) and continue to register your ESP peers with STA_IF. The Espressif code will use which ever interface the peer is registered with so long as that interface is active(True).

I have added a clarifying note on these issues to the documentation for add_peer() (see https://micropython-glenn20.readthedocs ... w.add_peer).
Last edited by glenn20 on Wed Jan 06, 2021 12:59 am, edited 1 time 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 » Tue Jan 05, 2021 11:42 pm

Now I know there are separate MAC addresses for AP and STA, I thought is was a "hardware' value for that particular board.

Not using any encryption, Both units are on channel 1, they all seem to default to that.
A machine.reset() will reinitialise the hardware (including wifi interfaces) and possibly parts of the underlying Espressif software stack (not sure about the latter part).
I understood Ctrl D did everything except hardware but that possibly relates to the PYBoard not to the ESP.

Thanks for the feedback.

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 » Wed Jan 06, 2021 12:10 am

ESP8266 in STA mode:

Code: Select all

w0 = network.WLAN(network.STA_IF)
w0.active(True)
mac = w0.config('mac')
print(mac)
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print(mac)
b'\x18\xfe4\xde\xea\xf3
18:fe:34:de:ea:f3

The same ESP8266 in AP mode:

Code: Select all

w0 = network.WLAN(network.AP_IF)
w0.active(True)
mac = w0.config('mac')
print(mac)
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print(mac)
b'\x1a\xfe4\xde\xea\xf3
18:fe:34:de:ea:f3

x18 versus x1a but the same 18. Is that expected?

Somebody doesn't like <: d e :>

User avatar
glenn20
Posts: 132
Joined: Mon Jun 04, 2018 10:09 am

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

Post by glenn20 » Wed Jan 06, 2021 1:14 am

davef wrote:
Wed Jan 06, 2021 12:10 am

Code: Select all

w0 = network.WLAN(network.AP_IF)
w0.active(True)
mac = w0.config('mac')
print(mac)
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print(mac)
b'\x1a\xfe4\xde\xea\xf3
18:fe:34:de:ea:f3

x18 versus x1a but the same 18. Is that expected?
It is expected. The interfaces have different MAC addresses. You need to register the right MAC address - and you need to associate it with the correct interface on the ESP32 (and vice versa) AND make sure the right interfaces are active().

You can fix the incorrect hexlified changeing the second last time to:

Code: Select all

mac = ubinascii.hexlify(network.WLAN(network.AP_IF).config('mac'),':').decode()
or:

Code: Select all

mac = ubinascii.hexlify(w0.config('mac'),':').decode()
or:

Code: Select all

mac = ubinascii.hexlify(mac,':').decode()
;)

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 » Wed Jan 06, 2021 3:06 am

Copy and paste someone else's code :) Thanks for correcting.

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 Jan 08, 2021 5:32 am

For the ESP32 ESP-NOW image on page 1:

I would like to run WiFi for two tasks and ESP-NOW for one task.

Rather than leave my datalogger continuously connected to a hotspot
I thought I would only connect when I want to get the time and when I
want to send a log.

Starting from a hard-reset (ESP32) the first connection to get time
works OK but the 2nd connection to send a log, say 5 minutes later, fails
with a hard reset.

Code: Select all

ets Jun  8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (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:5052
load:0x40078000,len:10600
load:0x40080400,len:5684
entry 0x400806bc
which I think is expected.

After I get the time I do:

Code: Select all

sta_if.disconnect()
sta_if.active(False)
I have read that a connection persists until you do a hard-reboot.
Does this mean you can't do a disconnect and then another re-connect
without a hard-reset? Is it a "persistent" issue that after
searching-around doesn't seem to be available on the ESP series in
Micropython.

Also, if I do a soft-reset just after the 1st connect is closed the
2nd connect runs properly ... sometimes.

I haven't tried the standard image from Micropython Downloads, but will do to check if nothing pops into your mind.

Would you prefer I put these issues on GitHub?

Any suggestions on how to fix this issue appreciated.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

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

Post by pythoncoder » Fri Jan 08, 2021 9:06 am

davef wrote:
Fri Jan 08, 2021 5:32 am
...
I have read that a connection persists until you do a hard-reboot.
Does this mean you can't do a disconnect and then another re-connect
without a hard-reset? Is it a "persistent" issue that after
searching-around doesn't seem to be available on the ESP series in
Micropython...
How about a try-and-see approach? Firing up an ESP32:

Code: Select all

MicroPython v1.13-266-g069557ede on 2020-12-20; ESP32 module with ESP32
Type "help()" for more information.
>>> 
>>> import do_connect
>>> do_connect.do_connect()
connecting to network...
network config: ('192.168.0.34', '255.255.255.0', '192.168.0.1', '208.67.220.220')
MAC 24:0a:c4:05:e5
>>> import network
>>> sta_if = network.WLAN(network.STA_IF)
>>> sta_if.isconnected()
True
On another terminal or machine:

Code: Select all

$ ping 192.168.0.34
PING 192.168.0.34 (192.168.0.34) 56(84) bytes of data.
64 bytes from 192.168.0.34: icmp_seq=1 ttl=255 time=207 ms
64 bytes from 192.168.0.34: icmp_seq=2 ttl=255 time=23.8 ms
64 bytes from 192.168.0.34: icmp_seq=3 ttl=255 time=47.7 ms
64 bytes from 192.168.0.34: icmp_seq=4 ttl=255 time=68.3 ms
^C
--- 192.168.0.34 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 23.763/86.622/206.759/71.129 ms
[adminpete@capybara]: ~
Back to the ESP32. Now issue:

Code: Select all

>>> sta_if.disconnect()
>>> sta_if.isconnected()
False
>>> 
Back to the remote, the ping now fails:

Code: Select all

[adminpete@capybara]: ~
$ ping 192.168.0.34
PING 192.168.0.34 (192.168.0.34) 56(84) bytes of data.
^C
--- 192.168.0.34 ping statistics ---
11 packets transmitted, 0 received, 100% packet loss, time 10246ms
Ergo disconnect works on an ESP32.
Peter Hinch
Index to my micropython libraries.

Post Reply