Raspberry Pi: Arcadeautomat

Es heißt zwar Arduino Hannover, aber unser Sichtfeld ist nicht so stark beschränkt, als dass wir nicht für anderes offen wären. Für mich war der Raspberry der Einstieg in die Hardwareprogrammierung, und angesichts des hier liegenden Arsenals an Microcontrollern und Mini-Computern immer noch aktuell. Die Geschichte über einen (erneut) ausgearteten Arbeitsauftrag – und eigentlich bin ich kein Zocker.

Ein ganz normaler Tag in der Hochschule:

Herzlich willkommen bei der Veranstaltung »Programmieren Projekt«. […] Ziel dieser Veranstaltung ist, dass Sie ein Arcadespiel selbstständig in Java programmieren. Als beispielhafte Vorgaben haben wir Jump ’n‘ Run, Scrollshooter oder Bomberman.

Bildschirmfoto 2015-01-22 um 23.11.30Eigentlich war es Gruppenarbeit, aber meine Kommilitonen konnten sich nicht so ganz aufraffen, so schrieb ich innerhalb eines Monats ein Jump ’n‘ Run Spiel. Läuft zwar nicht ganz reibungslos und das dritte Level ist unmöglich, aber an sich doch ganz interessant. Nebenbei auch ein Leveleditor im Hauptmenü mit F2 erreichbar. Den Sourcecode gibt es auf meinem GitHub.
In einer Mathevorlesung war mir mal wieder langweilig und ich studierte Angebote bei eBay und AliExpress. Ich werde dabei leider schnell schwach und kaufe dann gleich sofort. So waren dann ganz schnell zwei Joysticks und 16 Buttons bestellt. Nachdem ich den Händler für die Buttons anschreiben musste, dass noch kein Status im Tracking auftaucht, bemerkte er, dass das Paket gar nicht übergeben wurde. Also noch mal verschickt. Geliefert wurden dann allerdings 18 – in der Beschreibung waren 2 Start Knöpfe (die mit dem Toiletten Aufdruck), je 4 Rote, Grüne, Gelbe und nur 2 Blaue. Warum nur zwei Blaue konnte ich mir nicht erklären, aber im Paket waren dann ja auch 4 davon drin.
Einen Bildschirm ersteigerte ich bei eBay für effektiv €3,84. Ein Münzeinwurf rundete das ganze ab. Im Nachhinein bestellte ich einen Zweiten, da der Erste seine Funktion erfüllte. Münzzähler sind zwar eher ein Gimmick, aber nett zum Ablesen, wenn wirklich mit Geld gespielt wird.

Zur Verbindung habe ich neben normalen Kabelschuhen an Knöpfen und Joysticks XH-Verbinder auf der Platine benutzt. Leider lassen die sich nicht so gut mit meiner Zange krimpen, wie Dupont-Verbinder. Da brauche ich wohl andere Backen in der Zange. Was allerdings unabdingbar ist für viele Kabel und ich ohne Vorbehalt empfehlen kann, ist eine automatische Abisolierzange, ich bevorzuge bei Werkzeug dann doch die deutsche Knipex. Funktioniert sogar bei Flachbandkabeln mit Ø 1mm Isolierung.

In der Zwischenzeit überlegte ich mir ein Konzept, wie man die Ansteuerung realisieren kann. Auch wenn der Raspberry Pi B+ mehr Pins hat, reichen würden die nur knapp: 2×4 (für Joysticks), 13 für die Taster und zwei für die Münzeinwürfe, in Summe 23 Pins. Zur Verfügung stünden max. 26.
Erste Idee: Shift-Register. Probleme taten sich schnell auf: alles müsste mit PullUps versehen werden. Nicht unmöglich, aber nervig. Außerdem müsste man ständig Polling betreiben, da man nicht informiert wird, ob sich was geändert hat. Bei dem Gedanken erinnerte ich mich an die Port-Expander, die ich vor langem mal bei Conrad kaufte. Zwei MCP23017 und einen MCP23008 hatte ich noch hier. Beide haben Interrupts und ich muss somit nicht alle Pins ständig abfragen.

Der MCP23008 ist ein 8-Bit Portexpander, also eigentlich perfekt für die beiden Joysticks. Der MCP23017 bietet eine 16-Bit Erweiterung, reicht für 13 Tasten. Die Interrupts der beiden 8-Bit Register habe ich bei letzterem IC zusammen gelegt, wenn sich etwas ändert, kann ich auch gleich alle 16 abfragen. Beide werden über I2C angesteuert, eine SPI-Variante wäre auch verfügbar, ich habe mich aber mit I2C angefreundet und SPI wäre doch für diese Verwendung zu viel des Guten.

IMG_5693

Der Raspberry bietet auf allen Pins Interrupts, was doch oft vorteilhaft ist. Die Münzeinwürfe wurden als Interrupt definiert, die Portexpander anfangs auch. Letzteres war nicht allzu gut:
Wird eine Taste gedrückt oder der Joystick bewegt, so wird die Abfrageroutine für den Expander ausgeführt. In der Zeit sind die anderen Interrupts inaktiv. Wird während dieser Zeit eine Aktion durchgeführt (andere Taste, Münze einwerfen), so wird der Interrupt komplett ignoriert. Also alle 5ms die Interrupt-Ausgänge der Postexpander abfragen und die Tasten somit auch noch gleich entprellt.
Als Vorlage diente die RetroGame Library von Adafruit, von der eigentlich kaum noch etwas über blieb. Für die GPIOs nutzte ich meine Lieblings-Library WiringPi. Dort gab es auch für die Portexpander fertige Klassen, allerdings waren die nicht in dem Umfang, wie ich sie brauchte, also habe ich die gesamte I2C Kommunikation direkt über die Registeradressen erledigt.

Warum eigentlich 13 Tasten? 6 Tasten für jeden Spieler plus je eine zum Starten (1/2 Player) und noch eine Shift-Taste. Mit dieser sind dann Funktionen, wie Einstellungen, Wechsel des Bildschirms oder Herunterfahren auf den anderen Tasten erreichbar.
Auf der Rückseite des Automaten befinden sich LAN-, Klinken-Buchse, RS232- und VGA-Anschluss. Der VGA-Anschluss wird durch den Bildschirmwechsel als Eingang für den Monitor verwendet. Das ganze erfolgt über einen KVM-Switch. Die elektronische Ausführung ist sehr simpel aufgebaut: wenn an einem PS/2 Anschluss für die Tastatur 5V anliegen, denkt das Teil, der Rechner wäre an. Schaltet in dem Falle also die Bilddaten durch, allerdings muss zum Umschalten der Strom kurzzeitig komplett getrennt sein. Der Raspberry hat nur HDMI oder Composite als Ausgang, also kaufte ich noch einen HDMI-VGA-Adapter – wahrscheinlich dann insgesamt teurer, als hätte ich gleich einen Bildschirm mit DVI-Eingang ersteigert. Neben dem Bildschirm werden auch noch die Tasten intern deaktiviert – macht ja keinen Sinn, wenn man nicht sieht, was man macht. Stattdessen werden die Tasten über die RS232 (allerdings mit TTL-Pegel) mit zwei Bytes im Schema #Taste an/aus ausgegeben. So kann dann hinten ein ATmega32u4 beispielsweise drangehängt werden und über USB eine Tastatur emulieren. So kann man auch andere Spiele mit den Joysticks zocken.

Das Gehäuse gestaltete ich soweit in Illustrator, fast fertig für die CNC. Allerdings stellte sich später heraus, dass die Münzeinwürfe zu niedrig eingezeichnet wurden. Aber erst mal alles Schneiden, Verschrauben und Leimen.

Der Bildschirm wird durch die Relais komplett vom Netz getrennt, wenn der Raspberry hoch-, runterfährt oder ausgeschaltet ist. Unten ist die Konsole abklappbar, die Rückwand ebenso abnehmbar. Das Netzteil mit 8A@12V vielleicht etwas überdimensioniert…

Optisch sollte das ganze auch noch etwas her machen. Ganz so kahl sollte es dann doch nicht aussehen. Die Smash Bros Wii U Charaktere sind einfach optimal. Kurz vektorisieren, skalieren, richtig platzieren und die Daten in den Druck geben. Druckzeit für die permanent Folien 2-3 Tage. Genug Zeit, der Kiste einen Anstrich zu verpassen, wo keine Folie hin kommt. Anstrich, naja, eher unprofessionell mit der Lack-Sprühdose rumgefuchtelt. Vorher den Bildschirm nicht ausgebaut, der hat dann einen Tropfen abbekommen. Glasreiniger drauf und rubbeln. Ein Teil ist zwischen die Folien gelaufen, aber nach einigen Tagen wieder verflüchtigt. Den Rest mit der Rasierklinge ganz vorsichtig bearbeitet. Überreste zum Glück nicht mehr sichtbar.

Oben im Marquee, der keiner wirklich ist, verstecken sich 08/15 IKEA LED-Streifen auf 12V. Verblendet mit Plexiglas, rückseitig mit grüner Klebefolie kaschiert. Akustisch mussten ausgediente Logitech Boxen herhalten, 4W@6Ω, verstärkt mit einem PAM4303.
Da die Münzeinwürfe wie erwähnt etwas zu niedrig angesetzt waren, musste ich da etwas Basteln. Ein 50 Cent Stück versteckte sich etwa 8mm im senkrechten Auswurf, konnte somit nicht umkippen. Da unten eine Lichtschranke eingebaut ist, werden keine weiteren Münzen durchgelassen, sollte der Auswurf verstopft sein. Die Münzen mussten eh weg transportiert werden, können sich ja nicht übereinander Stapeln. Mit einem Magnet konnte man sie auch nicht anziehen, also fiel eine Münz-Stapel-Roboter mit Elektromagnet auch weg. Stattdessen kam mir eine viel simplere Lösung: Ich entfernte hinten etwas vom Plastik, sodass die Münze genug Höhe zum raus rollen hat. Von alleine rollt die aber nirgends hin, sondern fällt stumpf vertikal runter. Dafür missbrauchte ich meine Kabelklemmen, die ich mal im Hunderterpack bei eBay kaufte. Vorne etwas abgeschnitten, dadurch waren sie eine schiefe Ebene auf 2cm Breite. Unter den Münzeinwurf geklebt und die Münzen rollten in den Innenraum, gebremst von isolierter Kabelage. Allerdings klemmte es anfangs noch etwas, Hardware-Debugging mittels Kamera drin und dann an den Stellen nachfeilen oder die Schräge in der Position versetzen.

Als Software für die Emulation bildet das fertige RetroPie Image die Grundlage. Als Frontend wird dabei EmulationStation genutzt. Im Hintergrund verstecken sich zahlreiche Emulatoren, größtenteils aber RetroArch. Mehr Details zu dem RetroPie Projekt gibt es im Wiki auf GitHub.
Neben den Arcade-Joysticks können frontseitig auch Gamepads über USB angeschlossen werden. Dann hat Super Mario auch wieder das richtige Flair aus den alten grauen NES-Zeiten.

Inzwischen wurde der Raspberry Pi B+ gegen einen 2 B ausgetauscht, einige Librarys neu kompiliert und RetroPie neu aufgesetzt (Installation aus den neuen Binares, die bereits wenige Tage später für den 2 B verfügbar waren). Somit läuft jetzt auch N64 flüssig. Um meinen Tasten-Interpreter wieder zum Laufen zu bringen, musste ich lediglich wiringPi aus der Git aktualisieren und neu kompilieren. Das Programm selbst musste nicht neu kompiliert werden. An der Decke klebt eine Halterung für die GoPro, sehr unscheinbar durch die schwarze Farbgebung.

Zum Abschluss noch das Antesten im Video von einem Freund:

*Info: In diesem Beitrag verweisen orangefarbende Links auf Affiliates.