// PiFace CAD: Erste Versuche mit MPD

Wie bereits berichtet habe ich vor mit dem PiFace Control and Display (CAD) und MPD einen kleinen Musikplayer aus einem Raspberry Pi Model B zu basteln. Zum PiFace CAD existiert eine offizielle Python Library, die über die Raspbian Paketquellen nachinstalliert werden kann. Mit dieser kann man auf recht einfache Weise alle Funktionen der Erweiterungsplatine nutzen. Da sich meine Python Kenntnisse aber eher gering waren, habe ich mich in letzter Zeit ein bisschen in Python eingearbeitet. Sollte mein Programmierstil also noch etwas suboptimal sein, schrecke bitte nicht vor einem Kommentar zurück!

Vorbereitung

Zunächst habe ich das Board mit dem Raspberry Pi (Model B) in das passende Gehäuse eingebaut, welches es beispielsweise beim Distributor Farnell element14 gibt. Dies geht am besten, wenn zuerst der Pi und anschließend die Erweiterungsplatine in das Case gesteckt wird.

Auf das Model B+ passt das CAD zwar, allerdings liegt es aufgrund der neuen USB-Buchsen wie in den Bildern erkennbar etwas schief auf. Wenn die Kontaktstellen mit etwas Isolierband abgeklebt werden und sichergestellt wird, dass die GPIOs gut verbunden sind, dürfte dies aber kein Problem darstellen. Da ich aber ein „altes“ Model B verwende, bleiben mir diese Probleme erspart.

MPD installieren & konfigurieren

Auf die Installation und Konfiguration von MPD will ich hier nicht weiter eingehen, dazu gibt es zahlreiche Ressourcen. Statt dessen will ich kurz erläutern, welche Änderungen für den Pi notwendig sind und einen groben Einstiegspunkt liefern.
Nachdem die Pakete mpd und mpc installiert sind und die gröbsten Anpassungen in /etc/default/mpd und /etc/mpd.conf gemacht sind, kann mit raspi-config festgelegt werden welche Audioausgang verwendet werden soll. Diese Option findet sich unter Punkt 8 Advanced Options → Punkt A6 Audio. Ebenfalls unter Punkt 8 Advanced Options kann bei A5 SPI noch SPI, was später für das CAD benötigt wird, aktiviert werden.

Ich verwende für meinen Versuch die 3.5'er Klinke. Reicht die oft krtitisierte Qualität der Klinkenbuchse nicht aus kann ein HDMI Audio Extractor oder eine externe USB-Soundkarte verwendet werden. Im folgenden eine für den Pi gut funktioniernde MPD Audioconfig. Soll statt der internen Soundkarte eine externe USB-Soundkarte verwendet werden, muss noch Alsa konfiguriert werden.

audio_output {
        type            "alsa"
        name            "My ALSA Device"
        mixer_control   "Master"
        mixer_type      "software"
}

Nun kann die MPD Konfiguration überprüft werden, dazu aktualisiere ich zunächste mit mpc update die Datenbank, füge alle Titel der Wiedergabewarteschlange hinzu und starte die Wiedergabe. MPD sollte nun beginnen die Playlist, also alle verfügbaren Titel abzuspielen.

$ mpc update
# warten bis MPD die Datenbank aktualisiert hat (mit mpc status checken)
$ mpc add /
$ mpc play

MPC ist ein kleiner CLI Client für MPD. Eine Übersicht über die zur Verfügung stehenden Optionen liefert mpc help.

PiFace CAD einrichten

Auf mein.homelinux.com habe ich bereits eine Kurzanleitung zum PiFace CAD erstellt. Dort findet sich auch ein Abschnitt zur Einrichtung. Die Eckpunkte meines Vorgehens zu Einrichtung des CADs, die im Übrigen sehr gut auf der offziellen Seite dokumentiert sind:

  • SPI aktivieren (siehe weiter oben)
  • python{,3}-pifacecad (die offizielle Python 2 bzw. 3 Library) installieren und anschließend den Pi neustarten
  • sysinfo.py (eine Systemstatusanzeige) ausprobieren
  • den IR-Receiver bzw. LIRC einrichten

Die ersten Versuche

Zum PiFace CAD existiert eine offizielle Python Library, über die alle Funktionen des Boards in Python genutzten werden können. In der Dokumentation zur Library finden sich einige gut erklärte Beispiele, sodass auch ein Python Neuling wie ich etwas damit anfangen kann. Hin und wieder lohnt sich auch ein Blick in die Referenz.
Die wichtigsten Funktionen der Lirbrary habe ich hier kurz zusammengefasst. Dort finden sich auch einige kleine Beispiele, die im Endeffekt meine ersten Versuche waren.
Dieser Code nutzt zum Beispiel „Interrupts“ und gibt den gerade gedrückten Button auf das Display aus, dies ist besonders praktisch, wenn einem die Buttonbelegung noch nicht bekannt ist.

import pifacecad
 
# Init the CAD    
def initCad():
	cad.lcd.blink_off()
	cad.lcd.cursor_off()
	cad.lcd.clear()
	cad.lcd.backlight_on()
 
# Handle pushed pins
def handlePin(event):
	event.chip.lcd.clear()
	event.chip.lcd.write("Pressed button:")
	event.chip.lcd.set_cursor(0, 1)
	event.chip.lcd.write(str(event.pin_num))
 
cad = pifacecad.PiFaceCAD()
initCad()
listener = pifacecad.SwitchEventListener(chip=cad)
 
for i in range(8):
	listener.register(i, pifacecad.IODIR_FALLING_EDGE, handlePin)
 
listener.activate()

Für den Anfang habe ich mich entschieden vorerst kein LIRC zu verwenden. Ich will zuerst eine funktionierende Steuerung nur mit den Buttons realisieren.

MPD ansteuern

MPD lässt sich ganz einfach aus der Shell mit dem CLI Client mpc steuern. In Verbindung mit der Fähigkeit von Python Shell Befehle zum Beispiel mit os.system() auszuführen, ergibt sich hieraus eine sehr einfache Möglichkeit MPD zu kontrollieren:

$ python3
>>> import os
>>> os.system("mpc next")      # nächster Titel

Um nun auch die Ausgaben von mpc parsen zu können, kann subprocess.check_output() verwendet werden:

$ python3
>>> import subprocess
>>> status = subprocess.check_output("mpc status", shell=True, stderr=subprocess.STDOUT)      # Achtung: Python3 => binary string
>>> status = status.decode()
>>> status.find("%")

Mit diesen Hilfsmitteln habe ich nun versucht eine einfach Steuerung zu realisieren:

  • Eine erste naive Umsetzung: Mein erster Versuch, in dem das Display nicht wirklich verwendet wird, ist hier ersichtlich. Der Code nutzt den Status (Play/Pause) von MPC nur bedingt.
  • Erweiterte Realisierung: In diesem Code berücksichtige ich die Ausgaben von mpc zur Titelanzeige, Volumenanzeige und zur Ermittlung des Statuses (Play/Pause). Außerdem habe ich die Steuerung von MPD in eine eigene Klasse ausgelagert.

Wie gehts es weiter?

Der Code kann bis jetzt nur die Basisaufgaben, so aktualisiert sich die Anzeige noch nicht. Pin/Taster 0 ist eigentlich noch unbelegt und soll später dazu verwendet werden zwischen den einzelnen Funktionen des erweiterten Mediaplayersumzuschalten.
Bis jetzt habe ich neben der MPD Steuerung noch eine Uhr- und Wetteranzeige, eine Netzwerk bzw. Statusfunktion und die Möglichkeit den Raspberry Pi herunterzufahren oder zu rebooten in Planung. Diese zusätzlichen Funktionen werde ich nach und nach implementieren und hier über meinen Fortschritt berichten.

// Raspberry Pi: Basteln mit dem PiFace Control and Display

Neulich bin ich auf das PiFace Control and Display aufmerksam geworden. Die Erweiterungsplatine für den Raspberry Pi verfügt neben einem bequem mit Python programmierbaren Display über einen IR-Receiver, 5 Taster und einen Navigationsschalter. Die Dokumentation des Boards ist sehr ausführlich und enthält zahlreiche Beispiele.
Ich habe vor mit dem Board (und natürlich einem Pi) ein auf dem Musik Player Demon (MPD) basierenden Musikplayer zu basteln. Da ich die Hardware erst bestellt habe und noch nicht in den Händen halte, kann ich in diesem Post leider nur die beiden Komponenten – den Musikserver und das Erweiterungsboard – vorstellen und ein wenig auf die Möglichkeiten eingehen.

Hardware – PiFace Control and Display

Der IR-Receiver kann von LIRC verwendet werden, was die Hardware äußerst interessant macht. So kann der Pi prinzipiell von jeder IR-Fernbedienung aus gesteuert werden. Damit ist z.B. ein Musikplayer sehr gut realisierbar – von überall im Raum kann die Playlist gewechselt, die Musik pausiert oder die Lautstärke verändert werden.
Auch Timer (etwa nach 10min Pause) oder gar Weckzeiten könnte man damit einstellen. Mit den zusätzlich auf dem Board angebrachten Schaltern und Tastern lässt sich dies natürlich auch direkt am Pi erledigen.
Auf dem Displays des Boards können zusätzlich zahlreiche Informationen wie Musiktitel, Künstler, Lautstärke und Dauer dargestellt werden.

Musikserver – Musik Player Demon (MPD)

Musik höre ich in den eigenen 4 Wänden mit dem Musikserver Musik Player Demon (MPD). Die Software ist als Client/Server aufgebaut, wobei MPD eigentlich nur den Server bereitstellt.

  • Der Server (MPD) gibt die Musik wieder und verfügt über die Musiksammlung. Da der Server wenn möglich immer verfügbar sein sollte, macht es Sinn hier einen kleinen sparsamen Rechner zu verwenden, der außerdem passiv gekühlt/leise ist. Der Raspberry Pi erfüllt genau diese Eigenschaften und verfügt auch gleich über ein Audiointerface.
  • Der Client, der nun z.B. die Playlists erstellt und auswählt, die Lautsärke regelt, die Musik pausiert und fortsetzt, kann dann ein anderer Rechner mit entsprechender Software oder ein Smartphone mit passender App sein.

Aber auch eine Steuerung direkt auf dem Pi ist möglich und genau hier kommt nun das PiFace Control and Display zum Einsatz. Durch die zahlreichen Mensch-Maschine-Schnittstellen (IR-Fernbedienung, Taster/Schalter, Display) bietet es sich sehr gut zur Steuerung von MPD und zur Präsentation der relevanten Daten an.

Vorausblick – Wie gehts weiter?

Genug geschrieben, in der nächsten Zeit werde ich mich (sobald ich die Hardware habe) mit der Steuerung von MPD mit dem PiFace Control and Display beschäftigen …und mich in Python einarbeiten :-)
Zunächst habe ich vor einzelne Aktionen wie Pausieren der Musik oder Anpassung der Lautstärke über die Taster und später dann natürlich auch per IR-Fernbedienung zum Laufen zu bekommen. Das Display werde ich dann nach und nach einbinden. Wobei ich hier noch gespannt bin, wie das alles läuft.
Interessant ist auch die Anzeige des Wetters (siehe Beispiel) oder die Integration einer Weckerfunktion. Doch dazu in den nächsten Wochen mehr!

// Kurztipp: BIND – Cache leeren

Nachdem diese NoIP Geschichte nun doch noch ein gutes Ende genommen hatte, musste ich ein paar Backup MX-Einträge wieder zurückbiegen, die ich nach dem Domainklau durch Microsoft verbiegen durfte. In diesem Zusammenhang nochmal vielen Dank an die Redmonder ;-)
Wenn man Änderungen an DNS Records kontrollieren will, muss man wegen den Verzögerungen/Caching/TTL im Domainsystem meistens etwas warten (teilweise bis zu 24h). Ein eigener Resolver wie z.B. BIND verkürzt diese Wartezeit extrem, wenn man dessen Cache leert. Dies geht bei BIND mit dem Tool rndc:

$ sudo rndc flush       # mit Root-Rechten ausführen!

Die Änderungen kamen ca. 15min. später an! MX-Einträge lassen sich übrigens sehr gut mit nslookup oder host überprüfen:

$ nslookup -q=mx domain.tld
$ host -t mx domain.tld

// Kurztipp: Einem NIC eine weitere IP-Adresse mit IP hinzufügen

Wenn auf einem NIC (Network Interface Controller) eine weitere IP-Adresse benötigt wird, wird dies oft via Ifconfig mit einem virtuellen Interface bewerkstelligt, welches in der /etc/network/interfaces eingetragen wird:

auto eth0:1
iface eth0:1 inet static
    address 192.168.10.10
    netmask 255.255.255.0

Hier möchte als Alternative die Methode via IP kurz vorstellen. Zunächst fügen wir die IP-Adresse 192.168.10.10 mit der Subentzmaske 255.255.255.0 bzw. /24 dem Interface eth0 hinzu:

$ sudo ip addr add 192.168.10.10/24 dev eth0

…und schon ist unser Rechner über die bereits erwähnte Adresse erreichbar:

$ ip addr        #Ausgabe gekürzt
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    inet 192.168.9.10/24 brd 192.168.9.255 scope global eth0
    inet 192.168.10.10/24 scope global eth0
       valid_lft forever preferred_lft forever
 
$ ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.044 ms

Ebenfalls zu erwähnen ist, wie einfach diese Einstellung wieder wiederrufen werden kann:

$ sudo ip addr del 192.168.10.10/24 dev eth0
 
$ ip addr        #Ausgabe gekürzt
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    inet 192.168.9.10/24 brd 192.168.9.255 scope global eth0
       valid_lft forever preferred_lft forever
 
$ ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
^C
--- 192.168.10.10 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

Soll diese Einstellung nun bootfest gemacht werden, kann dies beispielsweise durch einen Eintrag in der /etc/network/interfaces geschehen, der so aussehen könnte:

#Definition von eth0
auto eth0
iface eth0 inet static
    address 192.168.9.10
    netmask 255.255.255.0
    gateway 192.168.9.1
    up ip addr add 192.168.10.10/24 dev eth0       #weitere IP-Adresse beim Start von eth0 hinzufügen
    down ip addr del 192.168.10.10/24 dev eth0     #...und beim Beenden wieder entfernen 
Hello World!

This is the personal website of Christoph Winkler.
Here you will find a sort of blog and some information about me and my projectshave fun!

Recent Comments
Latest Tweets

Follow me on Twitter...

QR-Code: aktuelle Seiten-URL
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Noncommercial-Share Alike 3.0 Unported