2016-04-02

Update: Inzwischen gibt es eine aktualisierte Version: Qudio. Die neue Version hat einen robusteren Erkennungsmechanismus für die QR-Karten und eine verbesserte Steuerung. Dank des Rapberry Pi Zero reicht inzwischen auch das Apple Dock des Lautsprechers, um die ganze Konstruktion mit Strom zu versorgen.

Die Musikrakete

Ein kindgerechter mp3-Player auf Basis von Raspberry Pi und JBL OnStage IIIp

Der CD-Player im Kinderzimmer war zwar beliebt, aber nicht wirklich praktisch: Die CDs waren so schnell zerkratzt, dass ich mit dem nachbrennen kaum hinterherkam und auch das Gerät selbst schien schon nach einem dreiviertel Jahr seinem Ende entgegen zu gehen. Deshalb sollte eine neue Lösung her. Möglichst robust, ohne CDs und auf jeden Fall ohne Hilfe der Eltern bedienbar.

Es fing damit an, dass Anica mich mit Begeisterung auf den hörbert aufmerksam machte. Das ist ein mp3-Player für Kinder, genauer gesagt ein Mono-Lautsprecher im Holzgehäuse mit einem SD-Slot und vier AA-Batterien. An der Vorderseite können bis zu neun Tracks über bunte Tasten direkt ausgewählt werden.

Ich war nicht so überzeugt von dem Konzept. Die SD-Karte muss man für jeden Wechsel der Inhalte herausnehmen, Batteriebetrieb fand ich nicht gut und so richtig günstig kam mir die Sache auch nicht vor. Allerdings war ich kurz vorher auf die Projektseite für einen MP3-Player für Kindergartenkinder gestoßen und habe das als Gegenbeispiel angeführt: Ein kleiner Raspberry Pi wird mit einer Webcam und ein paar Lautsprechern verbunden. Auf Knopfdruck wird ein QR-Code gelesen, den das Kind unter die Webcam gelegt hat und daraufhin wird das entsprechende Album abgespielt.

Entgegen meiner Erwartung wurde das gleich für besser als der hörbert befunden und damit hatte ich mein Projekt.

Weil der grundsätzliche Aufbau nicht besonders kompliziert ist, bin ich ursprünglich davon ausgegangen, dass sich das Ganze mit zwei bis drei Wochenenden umsetzen lassen müsste. Für die Basis-Variante war diese Einschätzung wohl auch nicht falsch, aber wie bei jedem guten Projekt kam dann einiges an Fehlversuchen, Verzögerungen und auch etwas Feature Creep hinzu. Am Ende war ich um einiges an Erfahrung reicher, habe viel dazu gelernt (CAD, Python) und aus „ein bisschen Elektronik in einer Box“ wurde eine Musikrakete aus dem 3D-Drucker. Der ursprünglich gesetzte Kostenrahmen wurde gnadenlos überzogen (ebenfalls wie bei jedem guten Projekt) und von den ersten Überlegungen bis zum glorreichen Moment der Übergabe an die Endnutzer vergingen dann auch fast vier Monate.

Der Player ist ein voller Erfolg und wurde von den Jungs super angenommen. Neben ein paar Verbesserungen an der Software plane ich noch eine Anleitung für eine kostengünstigere Version. Es gibt da draußen noch viele Lautsprecher mit altem Apple-Dock-Anschluss, die auf ein neues Leben warten.


Für alle, die es genau wissen wollen und als Dokumentation noch der Projektverlauf mit allen Details:

Planung und erste Schritte

Mir war schnell klar, dass ich gegenüber dem Originaldesign ein paar Verbesserungen wollte: Auf jeden Fall musste der Player eine Einheit sein, also alles in einem Gehäuse verbaut werden, inklusive der Lautsprecher. Zweitens wollte ich eine automatische Erkennung der QR-Codes durch eine Lichtschranke ohne zusätzliches Drücken irgendwelcher Knöpfe. Und drittens musste die Musik nicht von der internen SD-Karte sondern von unserem Heimserver kommen.

Nachdem ich mir ein paar Gedanken über den Gehäusebau gemacht hatte, fiel mir ein JBL OnStage IIIP in die Hände, der seit einiger Zeit bei uns einsam im Schrank lag. Der alte 30-Pin-Anschluss für iPods ist inzwischen nicht mehr ganz aktuell und die passenden Geräte schon nicht mehr im Einsatz. Ich wusste aber noch, dass der Lautsprecher einen beeindruckend guten Klang hat, außerdem passte die Größe gut zum Projekt. Die Frage war jetzt also, wie man die Komponenten (Raspi, Webcam, Lichtschranke, etc.) gut auf die kleine Plattform bekommen könnte.

Der ursprüngliche Ansatz war, eine Halterung für die Bauteile drucken zu lassen und dann alles zusammen in die Kunstoff-Kugel von einer Gartenleuchte (wie dieser) einzubauen. Die Idee kam dadurch zustande, dass die Form des JBL-Lautsprechers genau das Aufsetzen einer Kugel mit 20 cm Durchmesser erlaubt.

Leider war die Kugel weit weniger formstabil als angenommen. Beim Einschneiden fiel sie praktisch sofort in sich zusammen und war damit unbrauchbar. Außerdem ließ sich das Problem der Befestigung der Kugel auf der Plattform des Lautsprechers nicht so einfach lösen, so dass dieser erste Versuch dem Player ein Gehäuse zu geben fehlschlug. Deshalb sollte im zweiten Anlauf gleich das ganze Gehäuse gedruckt werden.

Design

Für den Gehäuse-Entwurf kam Onshape zum Einsatz. Ich hatte vorher noch mit FreeCAD experimentiert, war aber nicht wirklich voran gekommen. Onshape stürzte im Browser zwar immer mal wieder ab, aber da jeder Klick sofort gespeichert wird war das nicht besonders problematisch. Auf jeden Fall war die Bedienung so intuitiv, dass auch ein absoluter CAD-Anfänger wie ich schnell zurecht kommen konnte.

Das Gehäuse sollte einer Rakete nachempfunden sein. Zum einen, weil Raketen von Dreijährigen im Allgemeinen gut angenommen werden, zum anderen, weil die langgestreckte Form den Einbau eines WLAN-Adapters mit Antenne ermöglicht, der auch im schlecht abgedeckten Kinderzimmer noch ausreichenden Empfang garantiert.



Da ich vor dem Projekt weder Erfahrung mit CAD noch mit 3D-Druck hatte, musste ich erst ein paar Grundlagen lernen. Um nicht druckbare Überhänge zu vermeiden wurde die Rakete in drei Segmente unterteilt, die später verschraubt werden sollten. Ein Check der fertigen STL-Dateien mit Willit? 3D Print gab nochmals zusätzliche Sicherheit. Durch die Entscheidung, das gesamte Gehäuse zu drucken war der ursprüngliche Kostenrahmen sowieso schon hinfällig, mehrere Druckversuche für die Hauptkomponenten wären schlicht zu teuer geworden.

Das Raketen-Gehäuse besteht aus drei Segmenten: Unten der Hauptteil, in dem der Raspi verschraubt und die Webcam installiert wird. Darauf wird die Schiene angebracht, auf der die Karten mit den QR-Codes eingeschoben werden, sowie der Mittelteil, der ein kleines Fenster für einen Infrarot-Empfänger hat. Dadurch kann der Player auch per Fernbedienung gesteuert werden. Ganz oben dann die Raketenspitze mit Öffnungen für drei Schalter, die mit den Funktionen Vor, Zurück und Play/Pause belegt werden. Damit das Ganze auch wirklich nach Rakete aussieht, werden links und rechts noch Leitwerk-Elemente angeschraubt. Den Druck der fertigen Rakete übernahmen die Jungs von Laydrop (via 3dhub.com). Material PLA, Schichtdicke 300, Preis 105,80 € (und damit bei weitem die teuerste Komponente).

Die Erfahrungen aus dem ersten Anlauf mit der Stützstruktur machten sich bezahlt. Bis auf ein paar Kleinigkeiten passte alles exakt. Das Ganze wurde dann auf dem JBL-Lautsprecher verschraubt. Die Löcher für die Schrauben hatte ich ganz zu Anfang in den Lautsprecher gebohrt und dann das Gehäuse drum herum entworfen. Beim Öffnen half eine Anleitung von ifixit.com (für den On Stage II, aber der ist hinreichend ähnlich aufgebaut).

Aufbau

Stückliste

Elektronik und Montage

Parallel zum CAD-Design musste noch die Elektronik zusammengesetzt werden. Zum Glück war der Aufbau mit einer Lichtschranke, einer Beleuchtungs-LED, drei Schaltern und dem Infrarot-Empfänger nicht allzu kompliziert, für alle Elemente finden sich gute Anleitungen im Netz. Der fertige Aufbau ist auf dem Schemabild unten zu sehen. Verlötet wurde alles auf einer kleinen Leiterplatte, die mit auf dem Rahmen in der Mitte der Rakete sitzt.

Die gedruckten Raketen-Elemente passten gut und mussten nur zusammengeschraubt und auf dem Lautsprecher montiert werden. Schwieriger war die Befestigung und Ausrichtung der Webcam. Letztendlich half hier Polymorph-Kunststoff weiter: Im ersten Schritt wurde ein Sockel geformt, der in der Mitte des Raketenbodens sitzt und sich sich in die Vertiefung des iPod-Anschlusses einfügt. Dadurch sitzt die Kamera ausreichend fest und hat eine genau definierte Perspektive, kann aber jederzeit für Arbeiten am Gerät entnommen werden. Im zweiten Schritt wurde dann die Kamera mit Polymorph auf dem Sockel fixiert. Dabei war sie mit einem Laptop verbunden, so dass die Perpektive kontrolliert und nachkorrigiert werden konnte, bis die Verbindung ausgehärtet war.

Der Polymorph-Kunststoff war auch bei der Bearbeitung der Kabel nützlich: Der Micro-USB-Anschluss des Raspi war so nah an der Außenwand der Rakete, dass sich das Kabel nicht mehr ohne Aus- und Wiedereinbau einstecken ließ. Anstatt extra Adapter oder Kabel mit 90°-Winkel nachzukaufen wurde die Plastik-Kapsel am Stecker entfernt und durch Polymorph ersetzt. Damit kam das Standard-Kabel schnell und billig zu seinem 90°-Winkel.

Eine weitere kleine Herausforderung war noch das Fenster für den Infrarot-Sensor. Nach erfolgloser Suche nach geeignetem dunklen Kunststoff (wie er auch vorne an Fernbedienungen oder auf Empfängerseite an Stereoanlagen verwendet wird), fand ich in einem Forum den Hinweis, dass die dunklen Plastikscheiben aus Disketten in etwa dieselben Eigenschaften haben. Ein Stückchen Diskettenplastik auf einer Acrylscheibe und mit Heißkleber hinter die Fenster-Öffnung geklebt - fertig.

Die restliche Montage war relativ einfach: Die Leiterplatte mit der Lichtschranke und der Elektronik ist mit etwas Heißkleber auf dem Rahmen fixiert. Die Verbindungsdrähte der Beleuchtungs-LED sind so lang, dass die QR-Codes bequem von unten angeleuchtet werden können. Ganz allgemein waren Sorgen bezüglich Bildschärfe und Ausleuchtung unbegründet: Sobald der gesamte QR-Code im Bild ist, funktioniert die Erkennung auch bei bescheidener Bildqualität zuverlässig.

Bei den drei Schaltern war kein Verkleben nötig, weil sie auch so fest im Gehäuse sitzen. Sehr fest - 12,5 mm Öffnung waren für die 12-mm-Schalter etwas knapp bemessen. Die Kunststoff-Gewinde musste ich etwas abfeilen, damit sie in die Löcher passten. Verbunden wurden sie direkt mit den GPIO-Pins des Raspi per Jumper-Kabel.

Software und Programmierung

mocp statt xmms2

Anders als im Vorbild-Projekt sollte als Software-Player nicht xmms2 sondern mocp zum Einsatz kommen. Während xmms2 die Musiksammlung scannt und die ID3-Tags in einer Datenbank ablegt, über die dann der Zugriff erfolgt, wird mocp einfach der gewünschte Pfad übergeben. Das kann eine mp3-Datei, eine Playlist, ein Verzeichnis oder eine Stream-URL sein. Für meinen Ansatz war mocp besser geeignet, weil nicht sicher war, wie gut die ID3-Tags der Kindermusik-Sammlung gepflegt waren und weil möglichst keine Schreibzugriffe (für die Befüllung der xmms2-Datenbank) auf der SD-Karte nötig sein sollten (dazu später mehr).

Steuerung mit Python 3

Im Gegensatz zu den Vorbild-Projekten sollte die Steuerung auch nicht durch bash-Skripte, sondern mit Python erfolgen. Zunächst mussten die drei Schalter für Vor, Zurück und Play/Pause abgefragt werden. So weit, so simpel. Die einzige "Besonderheit" ist hier, dass nicht, wie sonst oft üblich, Pullup-Widerstände eingelötet wurden, sondern die bereits im Raspberry Pi vorhandenen durch das Programm konfiguriert werden:

# Buttons on PINs 14, 15 and 18
GPIO.setup(14, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

Die Reaktion auf einen gedrückten Button ist einfach: Der Befehl wird direkt an den mocp-Server weitergereicht. Um Mehrfach-Befehle bei länger gedrücktem Knopf zu vermeiden, wird danach das Skript kurz angehalten.

if (GPIO.input(15) == False):
    subprocess.call(["mocp", "--toggle-pause"])
    time.sleep(BUTTON_PAUSE)

Zusätzlich muss im Loop noch die Lichtschranke abgefragt werden. Sobald sie eine Unterbrechung meldet, startet der Hauptteil des Programms: Das Licht wird angeschaltet und die Webcam gestartet. Zusätzlich wird ein Scan-Sound abgespielt, damit man auch merkt, dass etwas passiert. Wenn ein QR-Code erkannt wird, wird die entsprechende Playlist oder Stream-URL an den mocp-Server gegeben. Falls es zum Timeout kommt oder der im QR-Code enthaltene Pfad nicht gefunden werden kann, wird ein Fehlersound abgespielt.

Dabei gab es ein paar Klippen zu umschiffen. Zum einen musste der QR-Scanner zbarcam in einem eigenen Prozess gestartet und abgefragt werden. Da zbarcam leider endlos scannt und nicht einfach das erste Ergebnis zurückliefert, muss die Abfrage per Polling erfolgen:

# scan QR code
zbarcam = subprocess.Popen(['zbarcam', '--nodisplay', '--raw', '-Sdisable', '-Sqrcode.enable', '--prescale=320x240', '/dev/video0'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

poll_obj = select.poll()
poll_obj.register(zbarcam.stdout, select.POLLIN)

# wait for scan result (or timeout)
start_time = time.time()
poll_result = False
while ((time.time() - start_time) < QR_SCANNER_TIMEOUT and (not poll_result)):
    poll_result = poll_obj.poll(100)

Es gibt zwar auch ein paar Python-Pakete zur Abfrage von zbarcam , aber die waren nicht zur Zusammenarbeit mit Python 3 zu bewegen. Python 3 widerum war nötig, weil ich in Python 2 nicht in der Lage war, das Encoding der von zbarcam zurückgelieferten Strings richtig aufzulösen. Anders als im Artikel von raspberry-pi-geek.de behauptet kann zbarcam nämlich sehr wohl mit Umlauten umgehen. Die werden nur beim Durchreichen über die Konsole zerschossen. Durch das UTF-8 default-Encoding von Python 3 kamen auch Pfade mit Umlauten korrekt im Programm an.

Das Skript nutzt vier Sound-Dateien für das akustische Feedback:

Der komplette Code für die Steuerung des Players findet sich in piplayer_pulse.py.

Audio-Ausgabe beim Raspi: Drama, Baby!

Die Musik dann auch wirklich in den JBL zu bekommen war schwieriger als gedacht. Zwar hatte ich schon vorher gelesen, dass das, was aus dem Kopfhörerausgang des Raspi kommt, nicht besonders toll ist, aber war davon ausgegangen, dass die Qualität schon ausreichen würde. Dem war nicht so. Der Ausgang knisterte und rauschte durchgängig. Das Audio-Signal musste also auf einem anderen Weg aus dem Computer kommen.

Der nächste Ansatz war die Ausgabe über den HDMI-Port. Dafür hatte ich einen HDMI-to-VGA/Audio-Adapter besorgt, der intern wohl auch mit irgendeinem Billig-Chip auf analoges Signal umsetzt. Für die Musikrakete war das zwar schlussendlich nicht die Lösung, aber weil die reine Sound-Ausgabe ohne angehängten Bildschirm beim Raspi etwas hakelig ist, hier noch der Hinweis: Damit der Raspi beim Hochfahren nicht kurzerhand den HDMI-Port lahmlegt weil er kein Display findet, muss in /boot/config.txt die Zeile hdmi_drive=2 eingetragen bzw. aktiviert werden (s. Raspi-Dokumentation). Zusätzlich muss dann noch die Soundausgabe per raspi-config auf "force HDMI" umgestellt werden. Das funktionierte zunächst einmal sehr gut, aber beim Zusammensetzen gab es ein böse Überraschung. Sobald der HDMI-Adaper am Raspi hing, reichte der vom 30-Pin-Anschluss bereitgestellte Strom nicht mehr aus und der Computer hing in einer Boot-Schleife.

Der dritte Versuch war dann die Verwendung einer USB-Soundkarte für unter 2 Euro aus China. Um die Ausgabe über die externe Soundkarte zu erzwingen, wird der interne Chip auf die ALSA-Blacklist gesetzt (s. Bash History). Damit lief im Test mit angeschlossenen Kopfhörern zunächst alles wunderbar, sobald die Karte über den Adapter an den JBL angeschlossen war, rausche und fiepste es auf einmal wieder. Auch ein Kürzen der Adapterkabel brachte keine Besserung. Nach etwas Verzweiflung fiel auf, dass man Knacksen provozieren konnte, indem man im per SSH zum Raspi verbundenen Terminal eine Taste drückte 0_o

Offensichtlich verursachte schon die Suche in der bash-History eine Spannugsänderung am Stromanschluss, die im 30-Pin-Adapter als Störsignal auf den Soundanschluss überging. Sobald der Raspberry Pi über ein separates Netzteil versorgt wurde, war die Ausgabe glasklar. Weil die Versorgung über den 30-Pin-Anschluss wesentlich eleganter als ein zusätzliches Netzteil ist, versuchte ich noch, die Störsignale mit Kondensatoren zu filtern. Aber auch die hervorragende Erklärung von Blake Jaquot brachte leider nicht das gewünschte Ergebnis.

Glücklicherweise war ich immerhin vorsichtig genug gewesen, im Gehäuse für genau so einen Fall eine Öffnung für Kabel vorzusehen, so dass zumindest der Anschluss des Zusatz-Netzteils kein Problem war. Natürlich hätte man jetzt auch wieder die Ausgabe per HDMI nutzen können, aber erstens war bei einer Hörprobe kein Unterschied festzustellen (vermutlich sind die Audio-Chips in den Adaptern ohnehin die gleichen) und zweitens hoffe ich immer noch darauf, das Problem mit den Störsignalen irgendwann lösen zu können.

Zu guter letzt gab es dann noch ein Software-Problem. Manchmal hörte man beim Start eines Tracks statt Musik nur lautes Rauschen. Sobald die Ausgabe einmal mit mocp --toggle-pause unterbrochen und neu gestartet wurde, ging es ganz normal weiter. Abhilfe schaffte die Verwendung eines alternativen Soundsystems an Stelle von ALSA. Nachdem ich PulseAudio installiert und mocp über den Adapter padsp gestartet hatte, hörte sich dann endlich alles an wie gewünscht. (Um den etwas hässlichen Umweg über padsp zu vermeiden müsste man mocp mit PulseAudio-Patch neu kompilieren, das habe ich mir bisher gespart.)

System-Einrichtung

Um den Samba-Share automatisch einzubinden, wird in /etc/fstab eine Zeile hinzugefügt:

//192.168.1.125/media /media/share cifs guest

Damit auch das Steuer-Skript automatisch gestartet wird, muss /etc/rc.local ebenfalls um eine Zeile (vor exit 0) erweitert werden. Weil die SD-Karte im Raspi später schreibgeschützt werden soll, wird die Log-Ausgabe auf den Share umgeleitet. Dort ist es im Alltag auch besser erreichbar.

su pi -c 'python3 /home/pi/piplayer.py >> /media/share/piplayer.log 2>&1 &

Für die Einrichtung von WLAN, lirc und allen anderen Details hier noch einmal die bereinigte und kommentierte bash History ab Installation von Raspbian Jessie Lite:

# Passwort ändern
passwd pi

# Partition auf SD-Karte vergrößern, Locales anpassen
sudo raspi-config

sudo apt-get update
dmesg
lsusb
sudo apt-get install iw

# WLAN installieren (Quelle: https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md)
# WLANs scannen
sudo iwlist wlan0 scan
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
#	# Eintrag:
#	network={
#		ssid="The_ESSID_from_earlier"
#		psk="Your_wifi_password"
#	}

sudo ifdown wlan0
sudo ifup wlan0

select-editor

sudo apt-get install ntp
sudo /etc/init.d/ntp restart
sudo nano /etc/ntp.conf
#	# in /etc/ntp.conf Zeitserver ergänzen
#	server de.pool.ntp.org
sudo /etc/init.d/ntp restart
date

sudo apt-get install lirc zbar-tools mc moc python3 python-rpi.gpio python3-rpi.gpio

sudo nano /boot/config.txt
# activate lirc and configure PINs by putting the following line in config.txt
# Quelle: https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README
#    dtoverlay=lirc-rpi,gpio_out_pin=22,gpio_in_pin=23

sudo reboot

# hiermit kann der Empfang der Fernbedienung getestet werden
mode2 -d /dev/lirc0

# Fernbedienung aufzeichen
sudo irrecord -d /dev/lirc0 ~/remote.conf

# Um die Ausgabe per USB-Soundkarte zu erzwingen, wird der interne Chip auf die ALSA-Blacklist gesetzt
# (Quelle: http://www.instructables.com/id/Use-USB-Sound-Card-in-Raspberry-Pi/?ALLSTEPS)
# create ALSA blacklist
sudo nano /etc/modprobe.d/alsa-blacklist.conf
#	blacklist snd_bcm2835

sudo reboot

# check if driver has been loaded
lsmod | grep snd_usb_audio

# list devices
aplay -l
arecord -l

# test audio (funktioniert nicht mit allen Adaptern)
speaker-test -Dhw:1,0 -c2 -twav

# mocp einmal starten und server herunterfahren, um .moc in ~ anzulegen
mocp --server
mocp --exit

# Umstellung auf Pulseaudio, um ALSA-Ausraster (Noise/Crackling) zu vermeiden
# s. https://moc.daper.net/comment/4316#comment-4316
# (für die ganz saubere Lösung müsste man https://moc.daper.net/comment/5240#comment-5240 anwenden)
sudo apt-get install pulseaudio
nano ~/.moc/config
#  	# Use OSS for Pulseaudio compatibility (run 'padsp mocp')
#	SoundDriver = OSS:ALSA:JACK
# Der moc Server muss jetzt im Skript über padsp gestartet werden, dann läuft alles über pulseaudio:
padsp mocp --server


# Einrichtung des Samba-Share vom Fileserver, auf dem die Musik liegt

# mount smb share 
sudo mount -t cifs -o user=guest,password= //192.168.1.111/media /media/share

# Dauerhaft einbinden über Eintrag in /etc/fstab
//192.168.1.111/media /media/share cifs guest

# piplayer.py und Sound-Dateien nach /home/pi kopieren

# autostart for piplayer with log output redirection
# (siehe http://raspberrypi.stackexchange.com/questions/8169/run-startup-application-as-a-specific-user)
sudo nano /etc/rc.local
#	...
#	su pi -c 'python3 /home/pi/piplayer.py >> /media/share/Audio/piplayer.log 2>&1 &'
#	exit 0

# make logfile accessible (the script is run as pi, the share is accessed as nobody)
sudo touch /media/share/piplayer.log
sudo chmod 777 /media/share/piplayer.log

sudo reboot

# check if running after restart
ps -ef | grep python 

# Tests mit QR-Code-Karten
tail -f piplayer.log

Die QR-Code-Karten

Die Vorlage für die QR-Code-Karten sollte den Bastel-Aufwand möglichst gering halten. Schließlich müssen immer mal wieder neue Karten auf die Schnelle nachprodiziert werden. Deshalb wurden die Karten als Streifen über die volle Breite einer DIN-A4-Seite ausgelegt, so dass man pro Karte nur ein bis zwei Schnitte braucht. Der Streifen wird dann noch einmal gefaltet, so dass der QR-Code auf der Unterseite für die Webcam im Gehäuse sichtbar ist, während man von oben das Album-Cover sehen kann. Weil die Karte am Ende aber auch nicht zu labil sein soll, wird am besten auf Papier mit 160-200 g/m² Stärke ausgedruckt.

Die Bilder mit den Codes lassen sich online mit http://goqr.me/ oder im Terminal mit qrencode erstellen. Für einen einzelnen Stream bspw. so:

qrencode -s 6 -m 0 -l L -o Radio-Teddy.png "http://streams.ir-media-tec.com/radioteddy.mp3"

Vor allem, wenn viele Codes auf einmal erstellt werden sollen, ist qrencode praktisch. Um Codes für alle Verzeichnisse im Kindermusik-Ordner zu erstellen verwendet man einfach eine Schleife:

cd /media/Audio/Kinder
for f in * ; do qrencode -s 6 -m 0 -l L -o "$f".png "$f"; done

Weil das Encoding einem bei Umlauten und Sonderzeichen schnell in die Quere kommen kann, sollte man das Ergebnis vor dem Druck evtl. noch einmal prüfen. Das kann man gut mit QtQR machen, das eine grafische Oberfläche für zbar und qrencode bietet. Das angezeigte Ergebnis ist also das Selbe, das auch im Player ankommt.

Was noch zu tun ist

Auch wenn die Musikrakete bereits erfolgreich im Einsatz ist, gibt es natürlich noch das ein oder andere zu verbessern. So ist die Bedienung per Fernbedienung zwar schon vorbereitet, aber das nötige Skript bisher noch nicht erstellt. Das liegt hauptsächlich daran, dass die Fernbedienung im Alltag bisher noch nicht vermisst wurde - vielleicht kommt das ja noch. Die Umsetzung ist aber denkbar einfach: Die mit lirc aufgezeichneten Tasten müssen nur mit Befehlen für den moc-Server hinterlegt werden.

Die größte noch verbliebene Kinderkrankeit ist, dass die Verbindung zum Samba-Share ab und an hängt. Dann wird der QR-Code zwar erfolgreich gescannt, bis die mp3-Dateien hinzugefügt sind und das Playback startet vergeheb dann aber eine oder zwei Minuten. Eventuell liegt das an einer „eingeschlafenen“ Verbindung. Das kommt zum Glück aber nicht allzu häufig vor und sollte sich auch noch lösen lassen.

Die größte noch geplante Anpassung ist die Umstellung der Raspbian-Installation auf read-only. Dadurch wird die SD-Karte geschont und der Player wird immun gegen plötzlichen Verlust der Stromversorgung. Bis jetzt muss der Player vor dem Ausschalten noch per SSH heruntergefahren werden. Für die Umstellung habe ich eine vielversprechende Anleitung im raspberrycenter.de, die zuletzt aber nur noch über archive.org zu finden war. Einen etwas radikaleren Ansatz findet man bei Michael Kofler. Auch dieser Punkt sollte jedenfalls lösbar sein.

Der letzte Wermutstropfen ist die oben erwähnte zusätzliche Stromversorgung. Wenn sich doch noch ein Weg finden sollte, den Raspberry Pi über den 30-Pin-Anschluss mit Strom zu versorgen, würde es mich freuen. Grundsätzlich geht es da aber eher um die Ingenieurs-Ästhetik - im täglichen Einsatz macht das zusätzliche Netzteil keinen großen Unterschied.