Pico W - Multicast receive stops working until after `machine.reset()`
Issue Description
When testing sending multicast packets back and forth between my Pi Pico W and my Windows 10 machine, the Pico will initially work, receiving packets sent to the same multicast group until you CTRL-C, hit stop, or leave it sitting a while. Eventually you will get into a state where it doesn't receive the packets anymore, though it is still listening and presumably still a member of the multicast group.
After this point, the only way to get things working again is to machine.reset() or physically power cycle the device. Once you do, things will work again. I've confirmed the packets are all sending via wireshark even after the Pico stops receiving things.
I found https://github.com/micropython/micropython/issues/10812 which looks similar, but is resolved by using SO_REUSEADDR, which I am doing, but still have the issue.
The most reliable way to reproduce:
- In Thonny, run the pico code
- In Windows Terminal, run the sender
- See it receive on the pico side. hit stop in Thonny.
- Hit start again (the sender script should still be going)
- It may work for 5ish more packets then stop. If not stop and start another time or two
- Eventually you will be unable to receive the multicast packets, even if you call
sock.close()in the repl and make a new socket - Curiously, if I send a packet to the pico directly, or to the broadcast address (192.168.1.255) it will be received, even when in this state
Pico W Code (Receiver)
import network
import socket
from time import sleep
import machine
ssid = 'SSID'
password = 'PASSWORD'
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
def inet_aton(addr):
return bytes(map(int, addr.split(".")))
###
ip = connect()
MCAST_GRP = '224.1.5.16'
MCAST_PORT = 9242
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, inet_aton(MCAST_GRP) + inet_aton("192.168.1.72"))
sock.bind(('', MCAST_PORT))
try:
while True:
print('waiting to receive message...')
data, address = sock.recvfrom(16)
print(f"received {len(data)} bytes from {address}")
print(f"{data}")
finally:
sock.close()
Windows Code (Sender)
import time
import socket
MCAST_GRP = '224.1.5.16'
MCAST_PORT = 9242
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("192.168.1.206"))
for i in range(100):
s.sendto(b'some data1 %i' % i, (MCAST_GRP, MCAST_PORT))
time.sleep(0.33)
s.close()
Hardware
- MicroPython v1.19.1-1016-gb525f1c9e on 2023-04-14; Raspberry Pi Pico W with RP2040
Sockets not releasing for Pico_W
Using a very simple web server on the Pico_W, running it once works fine. Running it a second time throws an address in use error. The only way to reset the system is to remove power. Stopping the device (e.g. in Thonny) still gives the same error when attempting to run the code.
The expectation is that once the code stops and/or is reset that running the code again would provide the same response as the first time.
The MicroPython build: is rp2-pico-w-20230221-unstable-v1.19.1-887-gb11026689
Version Reported: MicroPython v1.19.1-887-gb11026689 on 2023-02-21; Raspberry Pi Pico W with RP2040
The first file is the simple web server, the python script
sweb-server-d.txt
Running the above script two successive times yields the following information in the terminal window
repl-session.txt
Additionally, the output does not display on the web site every time, but only occasionally