ESP-Now support for ESP32 (and ESP8266)

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
mekanixms
Posts: 28
Joined: Fri Oct 18, 2019 3:46 pm

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

Post by mekanixms » Wed Jul 27, 2022 11:23 am

glenn20 wrote:
Wed Jul 27, 2022 9:56 am
It might be a bug. On my devices, I can see the entries in peers_table without setting AP active. BUT, it is only populated for INCOMING messages from the peer (because that is where we get the RSSI values from).
Thanks Glen

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 » Thu Jul 28, 2022 2:10 am

Glenn,
That error means you forgot to do add_peer() before send() ;).
When I first saw that I thought but I did add_peer() before the send and then a "penny-dropped".
Because I never send messages from the repeater to the remote THAT peer was NOT added.

I will repeat the test with add_peer(remote) before the send().

And try the other checks you have mentioned.

Power supply issues. I have several fixes for drop-outs when the WiFi fires up and as everything
had been running properly for the last 5 months I don't think I can blame hardware problems.

Mostly, system understanding-problems :oops:

from remote.py

Code: Select all

   w0 = network.WLAN(network.STA_IF)
    w0.active(True)
    print (w0.config('mac'))
    w0.config(channel=6)
    print (w0.config('channel'))

    e0 = espnow.ESPNow()
#    print (e0)
    e0.active(True)

 #  so that we wake up and reset the wdt before it times out
    e0.config(timeout = CYCLE_TIME * 1000)

    e0.add_peer(repeater_mac)
    print (e0.get_peers())

from repeater.py

Code: Select all

   w0 = network.WLAN(network.STA_IF)
    w0.active(True)
    print (w0.config('mac'))
    print (w0.config('channel'))
    w0.config(channel=6) # c4fd
    print (w0.config('channel'))
    print (w0.config('ps_mode'))

    e0 = espnow.ESPNow()
  # print (e0)

    e0.active(True)

 #  these functions generate exceptions on error - always return None
 #   e0.init()
 #  so that we wake up and reset the wdt before it times out
    e0.config(timeout = CYCLE_TIME * 1000)
    e0.add_peer(local)
    
 #  just a test   
    e0.send(remote, 'test', True)

from local.py

Code: Select all

#  the WiFi interface is set-up in wifi_functions.py

#  set up the ESPNow interface
e0 = espnow.ESPNow()
e0.active(True)
e0.config(timeout=1000) #  listen for 1 second for any ESPNow traffic
e0.add_peer(config.repeater)
I see one issue in remote.py Maybe, I should not have set the WiFi channel to 6.
I will delete those lines and add e0.add_peer(remote) to repeater.py!!


my connect function

Code: Select all

def connect_w0():
    count = 0


    if ap_if.isconnected():
        ap_if.disconnect()
        print ('AP started in the connected state, but now is disconnected')
    else:
        print ('AP started in the disconnected state')

    utime.sleep(1)

    ap_if.active(False) #  ensure AP is inactive


    if w0.isconnected():
        w0.disconnect()
        print ('w0 started in the connected state, but now is disconnected')
    else:
        print ('w0 started in the disconnected state')

    utime.sleep(1)

 #  both interfaces should now be disconnected

 #  now make w0 active and connect
    w0.active(True)

    print('connecting to hotspot...')

    utime.sleep(1) #  was getting Guru Meditation Error without this delay
                   #  and when doing w0.config(), ie a static IP

    w0.ifconfig((config.WiFi_device, '255.255.255.0', config.gateway, '8.8.8.8'))

    try:
        w0.connect(config.hotspot, config.password)
    except OSError as error:
        try:
            with open('errors.txt', 'a') as outfile:
                outfile.write(error + '\n')
        except OSError:
            pass

    while (count < 30): #  try to connect for up to 30 seconds
        count += 1

        if (w0.isconnected()):
            count = 0 # reset count
            print ('network config:', w0.ifconfig())
            break

        print ('.', end = '')
        utime.sleep(1)


    if (count == 30):
        try:
            with open('errors.txt', 'a') as outfile:
                outfile.write('failed to connect in 30 seconds' + '\n')
        except OSError:
            pass

        disconnect_w0() # or you could get errors
        count = 0 # just to be tidy
        machine.reset() #  start again


 #  now that you are connected
    print (w0.config('mac'))
    print ('channel = ', w0.config('channel'))

    w0.config(ps_mode=network.WIFI_PS_NONE) # ... then disable power saving
    print ('disabled power saving mode')

    try:
        rssi = w0.status('rssi')
        print ('RSSI = ' + str(rssi) + 'dBm')
    except:
        print ('signal level too low')

    utime.sleep(1)


Will get back with results in a day or two.
Yet again, thanks for your patience.

Dave

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 Jul 29, 2022 12:02 am

Today's observations (after making the changes as above):

1) maybe part of the problem is that my repeater can see the WiFi network or that the local unit is "telling" it to go to channel 6. I find if I change w0 to channel 1 then I can receive messages from the remote.
2) when the remote boots-up and gets to the point before a message is sent e0.get_peers() returns False but the message goes though.

Today's testing, channel changes using w0.config():
if both on channel 1 the remote sends repeatedly to the repeater
if both on channel 6 the remote only sends once
likewise in the other direction.

Maybe, I need to be somewhere that the WiFi is not visible to the units.

As a rule, would not all units have to be on the same WiFi channel, if there is only one radio. Hopefully, dynamic channel switching is not required for my case.

mekanixms
Posts: 28
Joined: Fri Oct 18, 2019 3:46 pm

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

Post by mekanixms » Fri Jul 29, 2022 6:36 am

Hi Dave,

You do not have to be connected with the Station interface, unless you use it for something else.
If you are connected, this may be the reason why the channel is changed.

By default espnow is using AP interface (ifidx = 0) and this can be set with add_peer so, if you wat to use STA interface you need to add ifidx=network.STA_IF when add_peer.

Last but not least, you have to be on the same channel, with the sender and receiver devices, on the interface that is used to send the messages

As explained in a prev post, to make it simple for me, I activated both AP and STA, disconnected STA and set the channel to whatever I need

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 Jul 29, 2022 6:48 am

Hi mekanixms,

In the section ESPNow and WiFi it sounds to me to be easier to connect to the STA interface. In other words there are more conditions you have to meet when using the AP interface.
By default espnow is using AP interface (ifidx = 0) and this can be set with add_peer so, if you wat to use STA interface you need to add ifidx=network.STA_IF when add_peer.
Are you sure about this?

v1.191.1 docs
add_peer()
ifidx: (ESP32 only) Index of the wifi interface which will be used to send data to this peer. Must be an integer set to network.STA_IF (=0) or network.AP_IF (=1). (default=0/network.STA_IF). See ESPNow and Wifi Operation below for more information.

mekanixms
Posts: 28
Joined: Fri Oct 18, 2019 3:46 pm

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

Post by mekanixms » Fri Jul 29, 2022 6:51 pm

Right Dave, is the other way around AP is 1 and STA is 0, I mixed the values

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 Jul 30, 2022 3:23 am

mekanixms wrote:
Fri Jul 29, 2022 6:36 am
You do not have to be connected with the Station interface, unless you use it for something else.
If you are connected, this may be the reason why the channel is changed.

By default espnow is using AP interface (ifidx = 0) and this can be set with add_peer so, if you wat to use STA interface you need to add ifidx=network.STA_IF when add_peer.
(EDIT - I see you clarified this in a later message :-)).

Actually the AP interface is ifidx=1. You can check the value using print(network.AP_IF). network.STA_IF is 0. ifidx=0 (STA_IF) is the default setting for add_peer(). You can see more about this in the Espressif API docs at https://docs.espressif.com/projects/esp ... red-device.
Last but not least, you have to be on the same channel, with the sender and receiver devices, on the interface that is used to send the messages
Yes - for Dave's scenario ALL 3 devices must be running on the same channel - and that is dictated by the Access Point (channel 6 if I have understood correctly). I still strongly suspect one or more of these devices is not continuing to run on channel 6.
As explained in a prev post, to make it simple for me, I activated both AP and STA, disconnected STA and set the channel to whatever I need

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 Jul 30, 2022 3:44 am

davef wrote:
Fri Jul 29, 2022 12:02 am
Today's observations (after making the changes as above):

1) maybe part of the problem is that my repeater can see the WiFi network or that the local unit is "telling" it to go to channel 6. I find if I change w0 to channel 1 then I can receive messages from the remote.
2) when the remote boots-up and gets to the point before a message is sent e0.get_peers() returns False but the message goes though.
I'm getting confused about your setup Dave - try to be a little more precise in your descriptions.

Earlier you said that the repeater is NOT connected to the wifi - the statement (1) above "suggests" it might be - but is ambiguous. It also seems to confirm my suspicion that the remote is running on channel 1 (the default channel) - not channel 6 (at least after you send the first message). I assume your are referring to changing w0 to channel 1 on the repeater - but not sure.

e0.get_peers() should return a tuple of tuples contaning any devices you have added with add_peer() (presumably the repeater mac address) or an empty tuple if you have not registered any peers.

Today's testing, channel changes using w0.config():
if both on channel 1 the remote sends repeatedly to the repeater
if both on channel 6 the remote only sends once
likewise in the other direction.

Maybe, I need to be somewhere that the WiFi is not visible to the units.
The presence of the wifi won't make any difference to any devices which are NOT connected to the wifi.

One thing to check: on the remote - if you call active(False) or deinit() or enter any form of light sleep the channel will be reset to 1 after you reactivate the wifi.
As a rule, would not all units have to be on the same WiFi channel, if there is only one radio. Hopefully, dynamic channel switching is not required for my case.
That's correct - I run a lot of devices in a similar configuration to you here Dave (remotes, relays and proxies) and all works fine if they are all running on the same channel.

Try adding print("channel =", e0.config('channel')) immediately before every call to e0.send() on the remote.

And - if all else fails reset to a simpler test setup - if you can change your wifi access point to run on channel 1 and leave all 3 devices on their default channel.

My suspicion is that for whatever reason your remote is switching from channel 6 to channel 1. It'd be good to confirm that and then investigate the cause in case it is a bug.

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 Jul 30, 2022 3:47 am

glenn20 wrote:
Sat Jul 30, 2022 3:44 am
davef wrote:
Fri Jul 29, 2022 12:02 am
Today's observations (after making the changes as above):

1) maybe part of the problem is that my repeater can see the WiFi network or that the local unit is "telling" it to go to channel 6. I find if I change w0 to channel 1 then I can receive messages from the remote.
2) when the remote boots-up and gets to the point before a message is sent e0.get_peers() returns False but the message goes though.
I'm getting confused about your setup Dave - try to be a little more precise in your descriptions.

Earlier you said that the repeater is NOT connected to the wifi - the statement (1) above "suggests" it might be - but is ambiguous. It also seems to confirm my suspicion that the remote is running on channel 1 (the default channel) - not channel 6 (at least after you send the first message). I assume your are referring to changing w0 to channel 1 on the repeater - but not sure.

e0.get_peers() should return a tuple of tuples contaning any devices you have added with add_peer() (presumably the repeater mac address) or an empty tuple if you have not registered any peers.

Today's testing, channel changes using w0.config():
if both on channel 1 the remote sends repeatedly to the repeater
if both on channel 6 the remote only sends once
likewise in the other direction.

Maybe, I need to be somewhere that the WiFi is not visible to the units.
The presence of the wifi won't make any difference to any devices which are NOT connected to the wifi. However, if you want to be really sure, call w0.disconnect() after calling w0.active(True) (should not be necessary on your esp32 devices).

One thing to check: on the remote - if you call active(False) or deinit() or enter any form of light sleep the channel will be reset to 1 after you reactivate the wifi.
As a rule, would not all units have to be on the same WiFi channel, if there is only one radio. Hopefully, dynamic channel switching is not required for my case.
That's correct - I run a lot of devices in a similar configuration to you here Dave (remotes, relays and proxies) and all works fine if they are all running on the same channel.

Try adding print("channel =", e0.config('channel')) immediately before every call to e0.send() on the remote.

And - if all else fails reset to a simpler test setup - if you can change your wifi access point to run on channel 1 and leave all 3 devices on their default channel.

My suspicion is that for whatever reason your remote is switching from channel 6 to channel 1. It'd be good to confirm that and then investigate the cause in case it is a bug.

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 » Sat Jul 30, 2022 4:12 am

Sorry to cause more confusion, but there seem to be some basic rule(s) I am not following. I see that this is reflected in some confusing statements.

1) the remote w0 channel needs to be the same as the repeater and the proxy, correct?
2) no messing-around with channel assignments in add_peers(), correct?
One thing to check: on the remote - if you call active(False) or deinit() or enter any form of light sleep the channel will be reset to 1 after you reactivate the wifi.
Now, there is another thing I didn't know. For quite awhile the remote still had lightsleep() in it, the last day or two I commented it out ... because it slowed down the testing I was doing.

When I get confirmation on 1) and 2) I will do more testing tomorrow.

As always, thank you.
Dave

Post Reply