In Zuge eines 8-wochigen Betriebspraktikum im Sommer 2017, haben ein Mitschuler und ich an der Hochschule Bochum, einen RGB-LED-Tisch gebaut. In diesem Projekt ging es darum, dass ein RGB-LED-Matrix-Tisch mit 10 Pixeln in der Breite und 20 Pixelnin der Lange gebaut werden sollte, um spater ehemalige 8-bit-Klassiker wie Tetris auf dem Tisch zu spielen. Dafur wurde ein IKEA-Tisch verwendet, um die RGB-LEDs einzubauen. Der Tisch wurde so umgebaut, dass ein Rechteck aus dem Tisch geschnitten und in den Tische in Gitter aus finnischer Holzpappe eingelegt wurde. Zur Verfugung wurden 200 RGB-LEDs und ein Raspberry Pi Zero W gestellt, mit dem die Steuerung der RGB-LEDs ubernommen wurde. Auf die RGB-LEDs wurde ein uberfang aus weiem Milchglas aufgelegt, um das Licht der RGB LEDs zu streuen, womit es besser dargestellt wird. Auserdem wurde eine Android-App geschrieben, die als Controller fur die Spiele verwendet wird. Die Verbindung der Steuerung zu dem Tisch wurde uber Bluetooth hergestellt. Als Programmiersprache wurde Java eingesetzt. Als LED-Typ wurden die APA102 Chips verwendet.
In dem Beitrag werden ich auf mein Programmcode eingehen. Das gesamte Projekt fur den Raspberry Pi sowie fur die Android App ist auf Github zu finden. RPi Anwendung https://github.com/Gurkengewuerz/ledmatrix/ Android App https://github.com/Gurkengewuerz/ledmatrix-android
Raspberry Pi Zero W einrichten
Nach der Standardmaigen Installation eines Raspbian Betriebssystem ist es wichtig den Pi direkt nach dem ersten Start ins WLAN zu hangen, um diesen Headless zu betreiben. Dafur direkt nach der Installation auf der Boot Partition die Datei wpa__suplicant.conf_ anlegen un konfigurieren bspw. nach diesem Tutorial.
Wichtig: Bitte das Root Passwort andern!
sudo passwd root
Anschlieend fur das Projekt Java installieren.
echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | tee /etc/apt/sources.list.d/webupd8team-java.list
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
apt-get update
apt-get install oracle-java8-installer
Um an den GPIO-Pins BSM 9-11 den SPI-Bus fur die APA102 LEDs zu aktivieren, uber das Programm raspi-config in dem Unterpunkt “Interfacing” den SPI-Bus aktivieren.
Programmablauf
Bezuglich des Programmablaufs zwischen dem Client und Server habe ich mir uberlegt, dass der Server mit der laufenden Java-Applikation standig in einer Schleife lauft und auf neue Client Bluetooth-Verbindungsanfragen wartet. Die zu ubertragenden Daten, die zwischen dem Client und dem Server gesendet werden, werden in JSON-Pakete gepackt, damit sie auf beiden Seiten einfach verarbeitet werden konnen.
An den Nutzer werden in einem Funf-Sekunden-Takt uber Bluetooth die aktuellen Statusmeldungen, beispielsweise den Spielstatus (Lauft, Pause, Game Over etc.) oder den Punktestand gesendet. Die Statusmeldungen, die der Client auf seinem Smartphone empfangt, werden dann bei Veranderungen in der Oberflache des Nutzers aktualisiert. Da mehrere Spiele auf dem Server laufen sollen, kann der Nutzer beim Spielstatus “Warten” ein Spiel auf dem Gerat auswahlen. Die getroffene Auswahl wird dann dem Server mitgeteilt, welcher das jeweilige Spiel startet.
Solange ein Spiel lauft und nicht beendet ist, sei es durch manuelles Unterbrechen oder ein Game Over, liest der Server die Tastendrucke aus, die von dem Controller aus der Smartphone-App gesendet werden. Sobald in den Spielmodus Game Over geschaltet wird, werden die aktuellen Daten mit dem Punktestand in eine SQLite-Datenbank geschrieben. Erkennt das Smartphone ein Game Over, so bekommt der Nutzer uber die App ein haptisches Feedback. Sollte der Client seine Verbindung trennen, sei es durch den Verlust der Verbindung oder durch ein beabsichtigtes Trennen, startet die Applikation seinen Bluetooth-Server neu und erlaubt wieder die Verbindung neuer Gerate.
Dieser Aufbau ist stark an eine UDP-Verbindung angelehnt. Wie bei UDP gibt bei dieser Verbindung keine Flusskontrolle zwischen dem Server und dem Client. Des Weiteren werden keine Daten bestatigt. Hatte ich dies eingebaut, ware die Verbindung deutlich getakteter. Von dieser Eigenschaft hatte ich nicht profitiert, da man fur eine Spielsteuerung schon fast in Echtzeit mit der Anwendung kommunizieren muss.
APA102 Ansteuerung
Jeder APA102 Chip besitzt insgesamt acht Pins. Die Betriebsspannung sowie die Masse werden durchgeschleift, um die Spannung an jede LED im Bus zu bringen. Die Datenpins (D) sowie die Taktgeschwindigkeit (C) werden in Input (D<sub>I</sub>/C<sub>I</sub>) sowie Output (D<sub>O</sub>/C<sub>O</sub>) aufgeteilt.
| LED-Pin | Beschreibung | Raspberry Pi Pin (BCM) |
|---|---|---|
| DI | Data Input | GPIO Pin 10 |
| CI | Clock Input | GPIO Pin 11 |
| DO | Data output | – |
| CO | Clock output | – |
| GND | Ground | GND |
| VCC | +5V | 5V |
D<sub>I</sub> ist der Datenbus. Er nimmt die Datenpakete an und schleift sie zu D<sub>O</sub> durch, um die gesendeten Daten an die folgenden RGB-LEDs weiterzuleiten. C<sub>I</sub> ist fur die Taktfrequenz zustandig. Das binare Signal wird von dem Master (RPi) vorgegeben. Das Signal regelt unter anderem die Datenubertragung.
Um die Datenpakete zu verschicken, wird die SPI-Schnittstelle verwendet. Die RGB-LED empfangt ein gultiges SPI-Signal und leitet dieses der nachsten RGB-LED weiter. In dem Datenblatt ist dies so beschrieben, dass die Datenleitung nur wahrend der Anstiegsflanke des Taktsignals beansprucht wird. Dies fuhrt zu dem Problem, dass die Daten, die an die erste RGB-LED geschickt werden, moglicherweise nicht so schnell verarbeitet werden konnen. Um dieses Problem zu umgehen, verzogert der APA102 die Daten auf der Ausgabe um circa einen halben Zyklus. Dieser Entwurf bewirkt, dass die RGB-LEDs keine interne Taktquelle benotigen.
Ein Datenpaket fur den LED-Strip benotigt u.a. ein Start Frame. Dies hat die Auswirkung, dass die RGB-LEDs aktualisiert werden. Dieses Paket muss mindestens 32 Bits gro sein und mit fuhrenden Nullen beginnen. Der Frame mit den Eigenschaften in dem Paket fur die RGB-LED wird anhand der drei fuhrenden Einsen von der RGB-LED erkannt. Auf die Fullbits folgt die Helligkeit. Die Helligkeit kann einen Wert von 0 bis 31 Bits annehmen, wobei 0 fur nicht aktiv steht. Nach der Helligkeit folgen die drei Farben Blau, Grun und Rot. Diese kann man mischen, sodass man uber sechzehn Millionen mogliche Farben erzeugen kann. Die Farben nehmen jeweils acht-Bits ein. Fur jede angeschlossene LED wird dies wiederholt (Fullbit, Helligkeit, Blau, Grun, Rot) gesendet. Am Ende des Pakets folgen 32 Endbits.
Bluetooth-Kommunikation
Fur den Controller wurde die Serielle Bluetooth Schnittstelle RFCOMM verwendet. Fur dieses Projekt habe ich die Bluetooth Library bluecov verwendet. Fur den ARM-Prozessor musste ich eine zusatzliche C-Library sowie das BlueCove Modul GPL installieren. Dies wird unter Linux benotigt, um mit bluez zu kommunizieren.
BlueCove nutzt unter Linux die Schnittstelle bluez, die letzten Endes fur die Bluetooth-Kommunikation zwischen Betriebssystem und Software zustandig ist. Fur die Nutzung von Bluetooth auf dem RPi habe ich aus dem Packet-Manager alle benotigten Programme heruntergeladen.
apt-get install bluetooth bluez-tools blueman libbluetooth-dev
Als ich ein Testprogramm laufen lie, ist das Programm mit einem Fehler abgesturzt. Es konnte keine Verbindung zu dem SDP-Socket aufgebaut werden. Dies lag an der Startoption des Bluetooth-Services unter Linux. Um diesen zu nutzen, muss die Startoption -C mit ubergeben werden. Dafur die Datei /etc/systemd/system/bluetooth.target.wants/bluetooth.service bearbeiten und den Parameter ExecStart verandern.
#ExecStart=/usr/lib/bluetooth/bluetoothd
ExecStart=/usr/lib/bluetooth/bluetoothd -C
Auserdem musste noch den eigebauten Bluetooth-Controller starten.
hciconfig hci0 up
Fur das pairen mit dem Smartphone kann man den Assistenten bluetoothctl auf dem RPi in der Kommandozeile nutzen.
pairable on
discoverable on
Eine erfolgreiche Koppelung bedeutet aber noch nicht, dass man den Datenverkehr von dem Gerat auf Softwareebene mitlesen kann. Dafur muss fur Bluetooth eine neue Konfigurationsdatei fur RFCOMM angelegt werden. In /etc/bluetooth/rfcomm.conf wird fur jedes Gerat, das sich verbinden soll, ein neuer Eintrag erstellt. Dafur wird die eindeutige Hardware-Adresse von dem Gerat benotigt, ob der Konfigurationseintrag bei dem Start des Betriebssystems geladen werden soll, und der Kanal auf der RFCOMM-Schnittstelle fur das Gerat.
rfcomm0 {
bind yes;
device xx:xx:xx:xx:xx:xx;
channel 1;
comment "Smartphone";
}
Sollte bei einem Gerat der Eintrag “bind auf yes” gestellt sein, wird dieses nach einem Neustart automatisch eingebunden. Dadurch wird fur jedes Gerat, das sich verbindet und in der Konfigurationsdatei steht, eine serielle Schnittstelle auf dem Betriebssystem unter /dev/rfcomm0 verfugbar. Diese Schnittstelle wird von BlueCove genutzt, um mit einer aktiven Verbindung zu kommunizieren.
Zusammenbau des Tisches
Um den LED-Matrix-Tisch zu bauen, hatte ich vor den Tisch in einer Schreinerei anfertigen zu lassen. Das bedeutete groen Aufwand, folglich wahlte ich einen Ikea Tisch und baute ihn um, indem ein Rechteck im Tisch ausgesagt wurde. Der Tisch war anfangs zur Stabilitat mit Pappe gefullt, welche ich zur Seite gedruckt habe.
Der Ikea-Tisch ist 90x55 cm gro, es handelt sich um einen weien Lack-Tisch. Das ausgesagte Rechteck ist 70x40 cm gro. In das ausgeschnittene Rechteck habe ich ein Gitter aus finnischer Holzpappe gelegt, um die Pixel voneinander zu trennen. Hier habe ich mich fur 2mm dicke finnische Holzpappe entschieden, da diese mit einem Teppichmesser schneidbar ist. Auerdem ist sie gunstig im Internet zu bestellen.
Als nachstes habe ich die RGB-LEDs gelotet. Hierbei sollte man unbedingt Zeit und viel Geduld mitbringen.
Der Draht, welchen ich fur die Lotungen verwendet habe, hatte einen Durchmesser von 0.5 mm. Wegen der hohen Stromstarke musste ich auf einen etwas dickeren Draht zuruckgreifen, da dieser sonst ziemlich hei werden konnte und ein Sicherheitsrisiko darstellen wurde. Der Draht fur die Stromleitungen hatte einen Durchmesser von 0.8 mm. Ich habe den Strom so verteilt, dass er an vier Stellen von den LEDs eingespeist wird. Das hat den Grund, dass die LEDs sonst zu wenig Strom bekommen und somit nicht hell leuchten oder sogar gar nicht funktionieren.
Im Nachhinein habe ich bemerkt, dass ich nur eine Masse-Leitung verlegt hatte. Das hatte zur Folge, dass es in der Masse zu Engpassen kommen kann.
Als nachstes habe ich ein Netzteil gesucht, welches den RPI Zero W und die RGB-LEDs betreiben soll. Von vorherigen Tests mit 50 LEDs, hatte ich bei voller Helligkeit und der Farbe Wei einen Strom von 2,5 Ampere gemessen. Das bedeutet bei 200 LEDs einen Stromanteil von zirka 10 Ampere. Ich habe mich jedoch fur ein Netzteil mit 5V bei 4A entschieden, da es sehr preiswert war und es zum Testen reichte. Eine Buchse fur das Netzteil habe ich in den Tisch an der rechten Seite eingebaut. Nach ein paar mehr Tests sollte man schon auf ein groeres Netzteil gehen.
Um das Licht zu brechen, musste ich noch eine Plexiglas-Platte oder eine Glasplatte besorgen. Um das Aussehen des Tisches zu verschonern, habe ich mich fur eine Glasplatte entschieden. Damit das Licht gebrochen wird, wurde ein Milchüberfang wei Glas ausgewahlt. Dieses wird haufig fur Tischplatten verwendet und ist mit einer Keramikschicht beschichtet. Da das Glas jedoch 4 mm dick war, konnte es nicht mehr in das ausgeschnittene Rechteck gelegt werden. Deshalb habe ich mich dazu entschieden, das Glas auf den gesamten Tisch zu legen und dieses mit Alu-Leisten an der Seite zu befestigen.
Installation des Projektes via Skript
Fur eine einfachere Installation liegt ein Bash Skript im Github Repository bei.
Weiterentwicklung
Mittlerweile besitzt das Projekt eine zusatzliche API-Schnittstelle um den Tisch per Websocket Commands anstuern zu konnen. Zudem konnen nicht nur Spiele auf dem Tisch gespielt werden, sondern nun auch als “Ambilight” auf Parties o.a. benutzt werden. Dafur habe ich den Tisch um ein Webinterface erweitert uber die man Animationen starten kann.








