ESPNow with LR-mode

Showroom for MicroPython related hardware projects.
Target audience: Users wanting to show off their project!
Post Reply
davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

ESPNow with LR-mode

Post by davef » Wed May 04, 2022 7:36 am

With assistance from glenn20 I got LR-mode working on my antenna testing project.
https://github.com/glenn20/micropython- ... /issues/20

I nominated the local end (receiver) to operate in AP-mode and the sender end (transmitter) in STA-mode. Whether or not other configurations work has not been investigated by me.

Remember the mac address is different between STA and AP modes. Also, note the use of the ifidx parameter when specifying peers.

Code: Select all

e0.add_peer(local_mac, ifidx=network.STA_IF)
sender.py:

Code: Select all

# sender.py for ESPNow LR-mode testing.

import network
from esp import espnow
import utime
import machine
from machine import Pin


CYCLE_TIME = 60             #  seconds
REBOOT_DELAY = 5            #  seconds
#local_mac = b'\x08:\xf2\xab\xe2\x0c' #  STA-mode
local_mac = b'\x08:\xf2\xab\xe2\r' #  AP-mode
pin33 = Pin(33, Pin.OUT)
pin33.off()


def reboot(delay = REBOOT_DELAY):
 #  print a message and give time for user to pre-empt reboot
 #  in case we are in a (battery consuming) boot loop
    print (f'Rebooting device in {delay} seconds (CTRL-C to escape).')
 #  or just machine.deepsleep(delay) or lightsleep()
    utime.sleep(delay)
    machine.reset()


try:
    print ('you have 5 seconds to do Ctrl C if you want to edit the program')
    utime.sleep(5)

    w0 = network.WLAN(network.STA_IF)
    w0.active(True) #  has to be true before the following line
    w0.config(protocol=network.MODE_LR)
    print (w0.config('mac'))
    e0 = espnow.ESPNow()

 #  these functions generate exceptions on error - always return None
    e0.init()

    e0.config(timeout = CYCLE_TIME * 1000)

    e0.add_peer(local_mac, ifidx=network.STA_IF)
except KeyboardInterrupt as err:
    raise err #  use Ctrl-C to exit to micropython repl
except Exception as err:
    print ('Error initialising espnow:', err)
    reboot()

try:
    while True:

     #  heartbeat, this also slows the loop down
        pin33.on()
        utime.sleep_ms(150)
        pin33.off()
        utime.sleep_ms(150)
        pin33.on()
        utime.sleep_ms(150)
        pin33.off()

        status = 'we have a link'

     #  if you want to save more battery, set sync=False
     #  at cost of not knowing if message was received.
        e0.send(local_mac, status, True)

        utime.sleep(10)
except KeyboardInterrupt as err:
    raise err #  use Ctrl-C to exit to micropython repl
except Exception as err:
    print ('Error during execution:', err)
    reboot()
and receiver.py:

Code: Select all

# receiver.py for ESPNow LR-mode testing.

import network
from esp import espnow
import utime
import machine
from machine import Pin, SoftI2C
import ssd1306_peter_hinch


i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000)
display = ssd1306_peter_hinch.SSD1306_I2C(128, 64, i2c)
CYCLE_TIME = 60             #  seconds
REBOOT_DELAY = 5            #  seconds
remote_mac = b'x!\x84{\xde\x80' #  STA-mode
#remote_mac = b'x!\x84{\xde\x81' #  AP-mode

def reboot(delay = REBOOT_DELAY):
 #  print a message and give time for user to pre-empt reboot
 #  in case we are in a (battery consuming) boot loop
    print (f'Rebooting device in {delay} seconds (Ctrl-C to escape).')
    utime.sleep(delay)
    machine.reset()


try:
    print ('you have 5 seconds to do Ctrl-C if you want to edit the program')
    utime.sleep(5)

    w0 = network.WLAN(network.AP_IF)
    w0.active(True) #  has to be True before the following
    w0.config(protocol=network.MODE_LR)
    print (w0.config('mac'))
    e0 = espnow.ESPNow()

 #  these functions generate exceptions on error - always return None
    e0.init()
    e0.config(timeout = (CYCLE_TIME) * 1000)
    e0.add_peer(remote_mac, ifidx=network.AP_IF)
except KeyboardInterrupt as err:
    raise err #  use Ctrl-C to exit to micropython repl
except Exception as err:
    print ('Error initialising espnow:', err)
    reboot()


while True:
    try:
        print ('waiting for a msg from the remote')

        for mac, msg in e0:
            if mac == remote_mac:
                msg = msg.decode('utf-8')

                print (msg)

                break #  out of the for loop!!
            elif mac == None:
                print ('no peers found')
                utime.sleep(5)
                break
            else:
                print ('Recv from {}: "{}"'.format(mac, msg))
                utime.sleep(5)
                break

        rssi_time_ms =  (e0.peers[b'x!\x84{\xde\x80'])
        rssi = (rssi_time_ms[0])
        print (rssi)

     #  display the RSSI
        display.fill(0)
        display.text(f'RSSI = {rssi:.0f}' + 'dBm', 0, 24)
        display.show()

    except KeyboardInterrupt as err:
        raise err #  use Ctrl-C to exit to micropython repl
    except Exception as err:
     #  all other exceptions cause a reboot
        print ('Error during execution:', err)
        reboot()
On bench testing I was seeing a 1-2dB increase in RSSI in LR-mode. To check all you have to do is comment-out the line that calls
LR mode in both the sender and the receiver.

I would appreciate any comments about whether or not I have used the idifx parameter correctly or any other potential errors in my approach.

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

Re: ESPNow with LR-mode

Post by davef » Mon Jul 11, 2022 10:36 pm

According to https://github.com/micropython/micropython/issues/8510
NOTE: I believe you may need to set this config option BEFORE calling w0.active(True) (ie. before esp_wifi_start() is called).
Looks like I will need to re-do my tests

Post Reply