Bereits ein Raspberry Pi Pico 2W bietet genügend Leistung, um damit ein gut funktionierendes Webradio aufzusetzen.
Der Autor hat schon verschiedene Projekte für Webradios gebaut. Vom einfachen Radio mit Vierzeilen-LC-Display [1] bis zum wohnzimmertauglichen Webradio mit einem Raspberry Pi 4 und großem Touchscreen für die Stereoanlage [2]. Das aktuelle Projekt ist ein Downsizing auf minimale Größe (Abbildung 1) und verwendet einen Pico 2W als Basis. Genauso gut würde sich auch ein ESP32-S3 eignen.
Grundfunktionen
Das Radio unterstützt lediglich die grundlegendsten Funktionen: Es kann MP3-Streams von Internet-URLs ausgeben, zeigt das entsprechende Senderlogo und erlaubt eine Navigation in der Senderliste mit Tastern. Dementsprechend überschaubar bleiben die Hardwareanforderungen.
Bei Taster und Bildschirm sind Sie nicht festgelegt. Allerdings drängen sich für die konkrete Anwendung Bildschirme mit integrierten Buttons geradezu auf. Einen besonders großen Bildschirm benötigen Sie nicht, da die Anwendung nur ein Logo anzeigen soll. Dazu genügen bereits 135 x 135 Pixel. Die meisten Bildschirme basieren auf einem ST7789 oder einem verwandten Chip; an passenden Treibern dafür herrscht keinerlei Mangel.
Für die Wiedergabe eines Radioprogramms lädt die Anwendung kontinuierlich einen MP3-Datenstrom von einer URL herunter und gibt die Daten immer noch digital über I²S an einen Digital-Analog-Wandler-Chip (DAC) weiter. Der sitzt auf einem externen Breakout und bestimmt die Qualität der Audioausgabe. Ein paar Optionen für den DAC stellen wir weiter unten vor.
Neben einem DAC-Board benötigen Sie zusätzlich noch Taster für die Navigation sowie einen Bildschirm für die Logoanzeige. Der Pirate Audio HAT [3] vereint alle notwendigen Komponenten auf einer Platine (Abbildung 1). Pimoroni entwickelte ihn ursprünglich für den Pi Zero. In unserem Fall sitzt aber unterhalb des HATs kein RasPi, sondern ein Pico 2W auf einer Adapterplatine. Einen möglichen alternativen Aufbau mit einem kleinen Waveshare-LCD und einem PCM5102A als DAC zeigt Abbildung 2. Der Pico 2W sitzt dabei unterhalb des Bildschirms, dazwischen steckt noch ein Mini-Breadboard.

Abbildung 2: Ein alternativer Aufbau für das Webradio mit einem LC-Display von Waveshare und einem PCM5102A als DAC.
Digital-Analog-Wandler
Je nachdem, welche Ansprüche Sie an Ihr Webradio stellen, haben Sie bei den DAC-Boards die Wahl zwischen preiswerteren und teureren Exemplaren. In Abbildung 3 sehen Sie eine Reihe von einfachen DACs. Der MAX98357A ganz links bringt einen integrierten Class-D-Verstärker (3 Watt, Mono) mit. Zwei davon am selben I2S-Bus lassen sich als Stereoverbund konfigurieren. Der PCM5102A (Mitte) und der UDA1334A (rechts) haben einen Line-Level-Ausgang, benötigen also einen externen Verstärker.

Abbildung 3: Sie haben die Wahl zwischen diversen günstigen DAC-Breakouts. Von links nach rechts: MAX98357A, PCM5102A und UDA1334A.
Oft kombinieren Hersteller einen DAC gleich mit einem Verstärker, was dann aber je nach Ausstattung richtig ins Geld gehen kann. Einen PCM510xx verwendet zum Beispiel auch der Hersteller HiFiBerry, dessen Audio-HATs im RasPi-Umfeld einen guten Ruf genießen. Viele DAC-Boards lassen sich über Pins oder Jumper konfigurieren, aber das ist selten nötig. Bei Ware aus Fernost lohnt sich eine kurze Google-Suche, denn die Chancen stehen gut, dass ein anderer Maker eine passende Anleitung bereithält.
Der Anschluss an den Mikrocontroller klappt problemlos. Neben Masse und Spannung benötigen Sie für I2s die drei Pins BCLK, WSEL und DATA. Der erste gibt den Takt an, der zweite wählt den linken oder rechten Kanal und der dritte Stift liefert die Daten. Auf den Breakouts finden Sie statt der genannten Bezeichnungen manchmal diverse alternative Versionen wie BCK (BCLK), LRCK (“left-right clock”) und LCK (WSEL) oder DIN (DATA).
Nicht alle Pins der verschiedenen Mikrocontroller unterstützen I2S. Darüber hinaus gibt es noch weitere Einschränkungen: So müssen beim Pico 2W die beiden Pins für BCLK und WSEL direkt nebeneinander liegen. Dasselbe gilt für den Raspberry Pi, dort liegt I2S auf den Pins GPIO18, GPIO19 und GPIO21. Die ersten beiden Pins liegen auf dem PCM5102A-Chip nebeneinander, auf der Pin-Leiste allerdings weit entfernt.
Software
In Sachen Software setzt das hier vorgestellte Projekt auf CircuitPython. Das bringt im Gegensatz zu MicroPython einen eingebauten MP3-Decoder mit, was das eigentliche Abspielen zu einer Sache von einer Handvoll Zeilen macht.
Die ersten drei Zeilen in Listing 1 erzeugen einen MP3Decoder (decoder) und ein I2S-Ausgabegerät (i2s). Zeile 4 ruft eine Webradio-URL (url) per GET-Request im Stream-Modus ab. Zeile 5 setzt anschließend die Eingabedatei des Decoders auf den Socket des Streams. Zeile 6 spielt zu guter Letzt das ab, was der Decoder liefert.
Auch die Verarbeitung der Tasten gelingt dank des in CircuitPython eingebauten Keypad-Moduls sehr einfach. Das in der zweiten Zeile von Listing 2 definierte Objekt keys überwacht im Hintergrund die angegebenen GPIOs und erzeugt Events, die dann die Hauptschleife ab Zeile 5 verarbeitet. Über die Nummer des gedrückten Tasters ruft der Code dann die passende Verarbeitungsfunktion auf.
Das soll an dieser Stelle als kurze Skizze des Programmablaufs genügen. Der reale Code für das Webradio ist freilich etwas ausgefeilter und umfasst beispielsweise auch die Ansteuerung des Bildschirms. Das komplette CircuitPython-Webradio-Programm steht im Github-Repository des Autors [4] für Sie zum Download bereit.
Listing 1
MP3-Streams abspielen
buffer = bytearray(bufsize)
decoder = audiomp3.MP3Decoder("dummy.mp3", buffer)
i2s = audiobusio.I2SOut(pin_bclk, pin_wsel, pin_data)
response = requests.get(url, timeout=5, headers={"connection": "close"}, stream=True)
decoder.file = response.socket
i2s.play(decoder)
Listing 2
Button-Verarbeitung
import keypad
keys = keypad.Keys([PIN_PREV, PIN_NEXT, PIN_RELOAD, PIN_MUTE], value_when_pressed=False, pull=True, interval=0.1, max_events=4)
callbacks = [on_prev, on_next, on_reload, on_mute]
[...]
while True:
event = keys.events.get()
if event and event.pressed:
callbacks[event.key_number]()
Ergebnisse
Der Betrieb des Webradios funktioniert überwiegend problemlos, aber nicht immer perfekt. So gibt es Streams, bei denen das Programm mehrere Anläufe benötigt, bis die Wiedergabe gelingt. Das hängt mit den MP3-Frames zusammen, auf die sich der Decoder erst synchronisieren muss. Der Autor hat bis jetzt nur einen einzigen (französischen) Sender gefunden, der überhaupt nicht funktionierte. Hier sendet die Radiostation vermutlich falsche Daten und bringt den Decoder aus dem Tritt.
Tests mit dem Pico W haben ergeben, dass er für Streams mit einer CBR (“constant bitrate”, konstante Bitrate) von 64 Bit funktioniert, darüber kommt er ins Stottern. Allerdings überträgt zumindest in Deutschland kaum noch ein Sender mit einer derart niedrigen Bitrate, obwohl sie für viele Anwendungsfälle absolut ausreichend wäre.
Mit der hierzulande üblichen CBR von 128 oder 256 Bit kommt erst ein Pico 2W problemlos zurecht. Wichtig ist aber, dass Sie möglichst unverschlüsselte Streams nutzen, also mit http:// statt https:// in der URL, denn das Entschlüsseln ist eine echte Performance-Bremse. Ebenfalls gut funktioniert ein System auf Basis eines ESP32-S3 oder eines ähnlich leistungsfähigen Mikrocontrollers. Da CircuitPython fast auf jeder MCU läuft, stellt das auch softwareseitig kein Problem dar.
Ausblick
Das in diesem Artikel vorgestellte Programm unterstützt keine ICY-Metadaten. Diese Infoschnipsel mischen die Sender auf Anforderung unter die eigentlichen MP3-Daten. Die Trennung von MP3-Frames und ICY-Metadaten würde die kleinen Rechner wahrscheinlich überfordern und ist deshalb nicht implementiert. Ähnliches gilt für einen zusätzlichen Softwaremixer für die Lautstärkeregelung. Mit zukünftigen, leistungsstärkeren MCUs dürfte sich das aber in absehbarer Zeit ändern. Der Code auf Github ist zumindest schon darauf vorbereitet.
Fazit
Die Implementation des Webradios war insgesamt eine einfache Sache. Ein fertiges Projekt jenseits des Breadboard-Stadiums erfordert freilich noch etwas mehr Arbeit. Haben Sie irgendwo noch alte Boxen herumliegen, könnten Sie sie upcyceln und die Komponenten einfach einbauen.
Auch die Software beschränkt sich auf ein Minimum und lädt förmlich zum Ändern und Erweitern ein. Moderne Touchscreens können die Senderauswahl erleichtern, ein kleiner Webserver auf dem Pico 2W würde die Fernbedienung per Smartphone erlauben. Der Autor nimmt jederzeit Pull Requests an und verlinkt auch gern von seinem Webradio-Repo auf alternative Projekte. (jlu)
Der Autor
Bernhard Bablok ist im Ruhestand. Wenn er nicht Musik hört oder mit dem Rad respektive zu Fuß unterwegs ist, beschäftigt er sich mit Themen rund um Linux, Programmierung und Kleincomputer. Sie erreichen ihn unter mailto:mail@bablokb.de.
Glossar
- I²S
- Inter-IC Sound. Unidirektionale Schnittstelle für serielle digitale Audiodaten. Kommt typischerweise zur Übertragung digitaler Audiodaten mit Puls-Code-Modulation (PCM) zum Einsatz.
- ICY
- I Can Yell. Summarische Bezeichnung für Metadaten-Tags und Responses im Streaming-Protokoll des Freeware-Mediaservers Shoutcast [5]. Deren Bezeichnungen beginnen alle mit ICY.
Infos
- Simple Radio: https://github.com/bablokb/simple-radio
- Luxusradio (Teil 1): Bernhard Bablok, “Schmuckstück”, RPG 10/2021, S. 52, https://www.raspi-geek.de/46115
- Pirate Audio HAT: https://www.berrybase.de/pirate-audio-hat-fuer-raspberry-pi-mit-eingebautem-lautsprecher
- Webradio für Pico und Co.: https://github.com/bablokb/cp-webradio
- Shoutcast: https://de.wikipedia.org/wiki/SHOUTcast






