Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arduino RP2040 connect wifi UDP - Multicast group not working #139

Open
manpowre opened this issue Oct 20, 2021 · 5 comments
Open

Arduino RP2040 connect wifi UDP - Multicast group not working #139

manpowre opened this issue Oct 20, 2021 · 5 comments

Comments

@manpowre
Copy link
Contributor

CircuitPython version

Adafruit 7.0 latest, and master branch (yeah I compiled master).

esp32 wifi chip:
Firmware vers. bytearray(b'1.4.8\x00')

Code/REPL

import time
import board
import busio
from digitalio import DigitalInOut
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi
import neopixel
from rainbowio import colorwheel
import gc
from secrets import secrets

UDP_IN_ADDR="224.1.1.1"
UDP_IN_PORT = 5500

UDP_TIMEOUT = 20

esp32_cs = DigitalInOut(board.CS1)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

spi = busio.SPI(board.SCK1, board.MOSI1, board.MISO1)

esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
socket.set_interface(esp)

s_in = socket.socket(type=socket.SOCK_DGRAM)
s_in.settimeout(UDP_TIMEOUT)


if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])
print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except RuntimeError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
#esp.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
time.sleep(1)
IP_ADDR = esp.pretty_ip(esp.ip_address)
print("ip:", esp.ip_address)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("udp in addr: ", UDP_IN_ADDR, UDP_IN_PORT)



socketaddr_udp_in = socket.getaddrinfo(UDP_IN_ADDR, UDP_IN_PORT)[0][4] 
s_in.connect(socketaddr_udp_in, conntype=esp.UDP_MODE) 
print("connected local UDP")

while True:
    data = s_in.recv(1205)
    if len(data)>=1:
        data=data.decode('utf-8')
        print(len(data), data)


Python on Ubuntu:
# Untitled - By: svein - fre. okt. 15 2021

import socket
import time

def run(group, port):
    MULTICAST_TTL = 40
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
    sock.sendto(b'from multicast_send.py: ' +
                f'group: {group}, port: {port}'.encode(), (group, port))
if __name__ == '__main__':
    while True:
        #run('224.1.1.1', 5500)
        run('192.168.2.147', 5500)
        time.sleep(1)

Behavior

ESP32 found and in idle mode
Firmware vers. bytearray(b'1.4.8\x00')
MAC addr: ['0xd0', '0xb1', '0x78', '0xa8', '0xcc', '0x84']
Connecting to AP...
Connected to zone RSSI: -47
ip: bytearray(b'\xc0\xa8\x02\x93')
My IP address is 192.168.2.147
udp in addr: 224.1.1.1 5500
connected local UDP
-->>> NO PACKETS recieved

ESP32 found and in idle mode
Firmware vers. bytearray(b'1.4.8\x00')
MAC addr: ['0xd0', '0xb1', '0x78', '0xa8', '0xcc', '0x84']
Connecting to AP...
Connected to zone RSSI: -47
ip: bytearray(b'\xc0\xa8\x02\x93')
My IP address is 192.168.2.147
udp in addr: 192.168.2.147 5500
connected local UDP
56 from multicast_send.py: group: 192.168.2.147, port: 5500
56 from multicast_send.py: group: 192.168.2.147, port: 5500
56 from multicast_send.py: group: 192.168.2.147, port: 5500
56 from multicast_send.py: group: 192.168.2.147, port: 5500

Description

So Ive been testing the wifi part of the circuitpython on the Arduino rp2040 connect.
The circuitpython esp32 wifi integration doesnt allow to set a static IP (Im gonna make a separate bug report on this), and I want to be able to communicate with the rp2040 chip through wifi and send datapackets, but since I dont know the IP adress, I figured I could send a multicast IP instead. On my ubuntu, I do recieve these packages on same multicast IP and port. so the router is out of the question.(As I made a multicast data logger from my rp2040 chip to get debug data from it).

The UDP reciever works with the IP adress of the wifi chip eg. 192.168.2.147:5500, but NOT the multicast adress 224.1.1.1:5500.

I hope you guys can fix this.. and the dhcp=True/False issue aswell.

Additional information

No response

@ladyada ladyada transferred this issue from adafruit/circuitpython Oct 20, 2021
@ladyada
Copy link
Member

ladyada commented Oct 20, 2021

not surprising as we dont know anyone who has used UDP - the library has strong TCP/SSL support which is what most people use. if you find a fix for the bug please submit a PR!

@sullivanst
Copy link

I'm trying to work out if I can implement a discovery protocol like mDNS, DNS-SD or SSDP so I'm interested too.
From spellunking through this repo and the one for the NINA firmware library it seems that to set the socket to multicast mode you have to tweak your connect to something like this:

    UDPMULTI_MODE = const(3)
    s_in.connect(socketaddr_udp_in, conntype=UDPMULTI_MODE)

Hope to find out whether that actually works soon.

@anecdata
Copy link
Member

anecdata commented Apr 10, 2022

What version of ESP32SPI library are you using? Static IP was added last month in 4.1.0 https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI/releases/tag/4.1.0
(should work with both the Arduino and Adafruit versions of NINA firmware)

@mattwTS
Copy link

mattwTS commented Apr 10, 2022

I'm still super early in the whole project, only downloaded the libraries this week so I assume I'm recent enough to have that. I can also set a static DHCP lease if I need to.

I'm hoping to get this thing working in SmartThings and haven't worked out the flow that expects to pick up a device yet & the few examples I've found so far have a discovery stage, so first stab was to look at the plausibility of that.

@sullivanst
Copy link

Oops I guess I was logged in with my work account in the iOS app for the previous comment.

It didn't work, and I can see why.

In adafruit_esp32spi.socket_connect are the following lines:

        self.socket_open(socket_num, dest, port, conn_mode=conn_mode)
        if conn_mode == self.UDP_MODE:
            # UDP doesn't actually establish a connection
            # but the socket for writing is created via start_server
            self.start_server(port, socket_num, conn_mode)
            return True

It looks like socket_open will fail if conntype isn't one of TCP_MODE, UDP_MODE or TLS_MODE because those are the only values the nina-fw firmware will accept; conntype=3 is only valid for the call to start_server.

The nina-fw doesn't appear to offer any way to set socket options directly so I think the only way to get multicast UDP working would be to tweak socket_connect to know some way about when it should call socket_open with conntype=1 and start_server server with conntype=3, whether that's by passing in conntype=3, by adding a multicast flag (defaults false of course), or by identifying a multicast address and conntype=1 (not so feasible if host is a name).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants