Page 16 of 37

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

Posted: Tue Oct 26, 2021 1:20 am
by glenn20
ESP8266 Bugfix

For those who missed it (https://github.com/glenn20/micropython- ... s/issues/7) I have posted some updated pre-compiled micropython espnow images (https://github.com/glenn20/micropython- ... g26f058583) which address a serious bug on the esp8266 platform.

The espressif espnow function esp_now_send() would generate a panic (only on esp8266) if the message buffer pointed to an address in ROM. Passing any ROM-interned string literal to ESPNow.send() would trigger this bug (eg. e.send(peer, 'join') or e.send(peer, '<module>') or e.send(peer, '7')...).

(If you are curious and new to string interning see: https://docs.micropython.org/en/latest/ ... /qstr.html).

Thanks to @danish1963 for the bug report.

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

Posted: Sun Oct 31, 2021 2:55 pm
by Zoland
Hi, Glenn!

There is some part of my experience with ESP-Now and creating unified startup for each node.
It's not mesh yet, but I can inform net space about own node and find necessary nodes, just defining their names

Result: dictionary { NAME, MAC, DATA } can be used in future code

Code: Select all

#  ESPNow NODES

import network
import utime
from esp import espnow

class NODE():
    def __init__(self):
        self.MAC  = None
        self.data = None
        

class ESP_NET():
    #              owner_node  critical_nodes  recommended_nodes
    def __init__(self, o_node, c_nodes = None, r_nodes = None ):
        print('Owner         :',o_node)
        print('Critical_nodes:',c_nodes)
        print('Recomend_nodes:',r_nodes)
        print()
        
        self.o_node  = o_node  # owner_node
        self.c_nodes = c_nodes # critical_nodes
        self.r_nodes = r_nodes # recommended_nodes
        
        #  A WLAN interface must be active to send()/recv()
        w0 = network.WLAN(network.STA_IF)
        w0.active(True)
        local = w0.config('mac')
        self.bcast = b'\xff'*6

        self.e0 = espnow.ESPNow()
        self.e0.init()
        self.e0.config(timeout=1000)

        self.e0.add_peer(local)      # add owner MAC first
        self.e0.add_peer(self.bcast) # add broadcast second
        
        self.macs = dict.fromkeys(c_nodes,None) # create NODE register
        
        find_peers = (len(c_nodes) if c_nodes else 0) + (len(r_nodes) if r_nodes else 0)
        i=0
        while True:
            ping = 'Ping'+o_node+' '+str(i)
            for mac, msg in self.e0:
                self.e0.send(self.bcast,ping,True) # I'm here
                print('Send: ',ping)
                    
                if mac:                            # Oy, who is here
                    print('MAC detected: ',mac)
                    new_msg = msg.decode('utf-8')
                    node_name = new_msg[4:5]
                    
                    if node_name in self.macs.keys(): # One of the declared Nodes
                        if self.macs[node_name]:
                            print('_____________Already peered with MAC: ',mac,'stored in ',self.macs)
                            if new_msg[0:4] == 'Pong':
                                self.macs[node_name].data = new_msg
                                print('_____________Pong from ',node_name)
                                find_peers -= 1
                        else: # New peer
                            self.e0.add_peer(mac)
                            new_MAC = self.e0.get_peer(mac)
                            self.macs[node_name] = NODE()
                            self.macs[node_name].MAC = new_MAC[0]
                            print('______________New peer with MAC: ',new_MAC[0])
                            self.e0.send(mac, bytearray('Pong'+o_node+' '+str(i)), True) #  send back answer

                        print ('Received from :{}: "{} peers left {}"'.format(node_name, new_msg,find_peers))
                        print()
                        break

            if not find_peers: break
            print ('..............waiting for msg '+str(i))
            print()
            i += 1


#################################################################################### main                
en = ESP_NET('A',['B','C'])

print('RESULT')
for node in en.macs.keys():
    print (node,en.macs[node].MAC,en.macs[node].data)

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

Posted: Wed Nov 03, 2021 1:51 pm
by Zoland
FROM DOC:
ESPNow.peer_count() (ESP32 only)¶
Return the number of peers which have been registered.

REAL RESULT:
2-values tuple

QUESTION:
First element - real number of peers, what is the meaning of the second value?

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

Posted: Wed Nov 03, 2021 10:51 pm
by glenn20
Zoland wrote:
Wed Nov 03, 2021 1:51 pm
FROM DOC:
ESPNow.peer_count() (ESP32 only)¶
Return the number of peers which have been registered.

REAL RESULT:
2-values tuple

QUESTION:
First element - real number of peers, what is the meaning of the second value?
Doh - that's an oversight in the docs. Thie first number is the total number of peers and the second is the number of encrypted peers. As per the data returned from esp_now_get_peer_num().

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

Posted: Wed Nov 03, 2021 10:58 pm
by glenn20
Zoland wrote:
Sun Oct 31, 2021 2:55 pm
Hi, Glenn!

There is some part of my experience with ESP-Now and creating unified startup for each node.
It's not mesh yet, but I can inform net space about own node and find necessary nodes, just defining their names
This is really interesting - thanks for your work on this. Sorry I've been so slow to follow up - I've been trying to get some other things cleaned up and been out of action for most of the last few weeks. I will definititely be looking to use this in my node management framework too - which I hope to get back to next week.

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

Posted: Thu Nov 04, 2021 12:48 am
by glenn20
ESPNow also supported on ESP32S2

I've uploaded a new micropythom image with ESPNow support for the ESP32S2 at https://github.com/glenn20/micropython-espnow-images.

That image is compiled against my micropython espnow-g20-v1.17 branch and ESP IDF v4.3.1 using BOARD=GENERIC_S2. It also requires PR#7963 to get a functional image on a generi ESP32S2 (withhout extra SPIIRAM).

I will compile and upload some additional images for the various other esp32s2 target boards today. As always, let me know there if there are any issues (I have limited devices available to test) here or raise an issue on github.

Thanks again to everyone who has been testing and raising issues.

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

Posted: Fri Nov 05, 2021 1:44 am
by glenn20
Zoland wrote:
Mon Oct 25, 2021 5:41 pm
Accidentally stumbled upon the Expressif ESP-NOW source https://github.com/espressif/esp-now
(Sorry - I forgot to post this when I reviewed this.)

For anyone who hasn't yet looked into this, the code is for a framework with more advanced capabilities (inc, mesh and grouping, OTA, etc) that sits over the existing esp_now functionality. The underlying esp_now code is still closed and only available as binary libs in the ESP IDF.

Confusingly, this interface duplicates much of the api with renamed functions, eg: espnow_send() is implemented over esp_now_send(), etc...

Nonetheless, these capabilites may be interesting/useful for future adoption in micropython.

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

Posted: Sat Nov 06, 2021 12:16 pm
by Zoland
From the documentation:

To send() a broadcast message, the broadcast MAC address must first be registered using add_peer(). send() will always return True for broadcasts, regardless of whether any devices receive the message. It is not permitted to encrypt messages sent to the broadcast address or any multicast address.


And what about return value for the multicast messages? For example, I want to check all active peers in my network. If one of the registered peers not response it will return False? So if it's critical for me, next I'll need to find this peer? Or it's easier to check each peer in loop?

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

Posted: Sat Nov 06, 2021 12:38 pm
by Zoland
glenn20 wrote:
Wed Nov 03, 2021 10:58 pm
This is really interesting - thanks for your work on this.
My idea is to avoid knowing the real MAC addresses by replacing them with symbolic names. At startup, using broadcast pinging starts in the searching adding pairs with the specified names and the same time making dictionary with additional info about this peers. At the working logic,we continue to monitor the situation of loss of communication by regularly broadcast pingig to suspend work until reconnection occurs. At the same time, I don't want to write a lot of code and not use asyncio to save memory.

Like this code can be added to examples if it's interesting.

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

Posted: Sat Nov 06, 2021 3:50 pm
by Zoland
Does anyone know if there is a time difference between broadcast (multicast) and peer-to-peer sending?

Maybe it's easier to send broadcast publications (messages) that the receiving modules just filter the necessary publications as subscriber? For example subscriber send peer-to-peer request to publisher module, that further answer by broadcast publication. In that case we not need to make peers on publisher modules ?

What happens when the received message buffer overflows? Are earlier messages being pushed or are later messages not being logged?