micropython / micropython/micropython
Pico W - Multicast receive stops working until after `machine.reset()`
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 22.1k
- Forks
- 9k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 16
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Pico W receiver and Windows multicast sender, reproducing the failure after stopping and restarting the receiver. Trace multicast membership and socket cleanup in the networking implementation; done means multicast packets continue arriving after repeated stop/start cycles without calling machine.reset().
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- embedded-iot, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100