Description
CircuitPython version
Adafruit CircuitPython 9.2.3 on 2025-01-17; Raspberry Pi Pico 2 W with rp2350a
Code/REPL
import time
import gc
import board
import digitalio
import audiobusio
import audiomp3
import wifi
import socketpool
import ssl
import adafruit_requests
class Player:
def __init__(self,i2s_pins):
self._buffer = bytearray(16384)
self._decoder = audiomp3.MP3Decoder("dummy.mp3", self._buffer)
self._i2s = audiobusio.I2SOut(*i2s_pins[:3])
pool = socketpool.SocketPool(wifi.radio)
self._requests = adafruit_requests.Session(pool)
# --- play the given webradio-station ------------------------------------
def play(self,url):
gc.collect()
while True:
try:
self._response = self._requests.get(
url, timeout = 5,
headers = {"connection": "close"},
stream = True)
if not self._response:
print(f"no response for {url}")
time.sleep(1)
continue
self._decoder.file = self._response.socket
self._i2s.play(self._decoder)
return True
except Exception as ex:
print(f"play(): exeception: {ex}")
return False
# --- stop playing -------------------------------------------------------
def stop(self):
""" stop playing radio stream """
if self._i2s.playing:
try:
self._i2s.stop()
self._response.socket.close()
self._response.close()
except Exception as ex:
print(f"stop(): exeception: {ex}")
# --- connect-helper --------------------------------------------------------
def connect(ssid,passwd):
state = wifi.radio.connected
print(f" connected: {state}")
if state:
return
for _ in range(3):
try:
wifi.radio.connect(ssid,passwd)
break
except ConnectionError as ex:
print(f"{ex}")
print(f" status: {wifi.radio.connected}")
if not wifi.radio.connected:
raise ConnectionError(f"could not connect to {ssid}")
# --- main application code -------------------------------------------------
connect("my_ssid","my_password")
player = Player(board.GP10 # PIN_I2S_BCLK
board.GP11, # PIN_I2S_WSEL
board.GP9]) # PIN_I2S_DATA
URLS = [
"http://dispatcher.rndfnk.com/br/br1/obb/mp3/mid",
"http://dispatcher.rndfnk.com/br/br2/live/mp3/mid",
"http://dispatcher.rndfnk.com/br/br3/live/mp3/mid",
"http://dispatcher.rndfnk.com/br/brklassik/live/mp3/mid",
"http://dispatcher.rndfnk.com/br/br24/live/mp3/mid",
"http://mdr-284350-0.cast.mdr.de/mdr/284350/0/mp3/high/stream.mp3",
"http://icecast.ndr.de/ndr/ndrkultur/live/mp3/128/stream.mp3",
]
while True:
for interval in [10,5]:
for url in URLS:
print(f"free memory before play(): {gc.mem_free()}")
print(f"playing {url} for {interval}s...")
player.play(url)
time.sleep(interval)
print(f"stopping player")
player.stop()
time.sleep(1)
Behavior
Automatisches Neuladen ist aktiviert. Speichere Dateien einfach über USB, um sie auszuführen, oder gib REPL ein, um sie zu deaktivieren.
main.py Ausgabe:
connected: False
status: True
free memory before play(): 313104
playing http://dispatcher.rndfnk.com/br/br1/obb/mp3/mid for 10s...
stopping player
free memory before play(): 284752
playing http://dispatcher.rndfnk.com/br/br2/live/mp3/mid for 10s...
stopping player
free memory before play(): 282480
playing http://dispatcher.rndfnk.com/br/br3/live/mp3/mid for 10s...
[15:31:46.853] Disconnected
Description
The program automatically cycles through a number of web-streams from internet radio (in the real application the user presses buttons to switch stations). After a few URLs, the Pico2W just disconnects and needs a hard reset for a restart. Behavior is random, sometime it fails after three streams, sometimes later. Switching streams seems to be the problem, playing a single stream for an extended time works without problems for all of the example URLs.
Note that you don't need real I2S hardware to reproduce the error. Also, the program works fine on an ESP32-S3.
Some speculations: maybe the network-stack of the Pico2W does not cleanup resources and fails after a while. Or it produces illegal data during close and this trips the MP3Decoder.
Additional information
No response