SNESpaduino – Super Nintendo Gamepad für Arduino

Mit der SNESpaduino library ist es möglich, SNES (Super Nintendo Entertainment System) Gamepads (Controller) als Eingabegerät für einen Arduino zu nutzen.

SNES Gamepad an Arduino anschließen

Das Super Nintendo Entertainment System Gamepad kann einfach mit dem Arduino verbunden werden

Die library erfüllt die 3 Aufgaben:

  • Einfaches Interfacing – Es müssen nur 3 Pins für Latch, Clock und Data angegeben werden
  • Button-Status auslesen – Die Funktion liest aus, welche Buttons aktuell gedrückt sind
  • Hilfe beim Parsen – Durch Konstanten können die Werte einfach verarbeitet werden

Neben der einfachen Bedienung lässt sich anhand der library ebenfalls gut nachvollziehen, wie eine Arduino library aufgebaut ist, wie sie entwickelt wird, und vor allem was genau „im Hintergrund“ geschieht. Der gesamte Code ist ausführlich Kommentiert, die einzelnen Commits auf GitHub enthalten dazu noch informative Details.

Download und Installation

Die library kann auf mehrere Wege bezogen werden:

Am besten ist es, die neuste Version von GitHub herunterzuladen. Am einfachsten geschieht dies mit dem Klonen des Repositories (Befehl siehe oben). Wer git nicht installiert hat, kann auch direkt die ZIP-Datei von GitHub herunterladen. Der entpackte Ordner heißt allerdings SNESpaduino-master und muss daher noch umbenannt werden („-master“ muss entfernt werden)!

Wie die library installiert wird, ist in der offiziellen Arduino Library Referenz erklärt. Wurde die library korrekt installiert und ist in der IDE nutzbar, kann als nächstes der Controller angeschlossen werden.

HowTo: SNES Gamepad anschließen

Das SNES Gamepad verfügt über 5 Kontakte: +5V, GND, Latch, Clock, Data. Die Pin-Konfiguration des Steckers, von Links nach Rechts (die 4er Kontaktgruppe links):

Nr 1 2 3 4 5 6 7
Zweck +5V Clock Latch Data N/C N/C GND
Farbe Weiߟ Gelb Orange Rot Braun
SNES Gamepad Connection

Pin-Konfiguration und Farbcodes des SNES Controllers

Um das Gamepad mit dem Arduino zu nutzen, wird GND mit einem Ground-Pin am Arduino verbunden, die +5V werden auch direkt vom 5V Pin am Arduino geliefert. Die Anschlüsse für Latch, Clock und Data werden an beliebige digitale In/Outputs angeschlossen: Über Latch und Clock sendet der Arduino 5V/GND, also HIGH/LOW (OUTPUT), über die Data-Leitung empfängt der Arduino 5V/GND (INPUT).

Ich nutze beispielsweise die Pins 19, 20 und 21 an meinem Arduino Mega. Es kann aber jeder In/Out Pin genutzt werden. Auch die „analogen“ Pins.

Library und Gamepad testen

Sind library und Controller bereit, können beide getestet werden. Die library liefert aktuell 2 Beispiel-Sketches mit. Diese sind unter Datei > Beispiele > SNESpaduino aufrufbar. Als erstes kann das Beispiel SNESpaduinoPrintToSerial geladen, kompiliert und übertragen werden. Der Programmcode ist durch Kommentare dokumentiert und sollte leicht verständlich sein.

Als erstes wird eine Instanz von SNESpaduino erstellt, der Konstruktor wird mit den 3 Pin-Nummern für die Latch, Clock und Data Leitungen aufgerufen. Danach kann durch den Aufruf von getButtons() der aktuelle Status der Buttons abgefragt werden. Dabei wird aus dem Controller gelesen, ob die einzelnen Buttons gedrückt oder nicht gedrückt sind. Das Ergebnis liefert getButtons() als 16-Stellige Ganzzahl wieder.

Da aus dem Controller eine 0 (LOW, False) ausgelesen wird, wenn ein Button gedrückt ist (also eine 1 / HIGH / True wenn ein Button nicht gedrückt ist), wird das Ergebnis standardmäßig invertiert (logisch negiert) wiedergegeben. Das macht es einfacher, die Daten durch If-Abfragen zu verarbeiten. Es können aber auch die nicht-invertierten (/negierten) Daten wiedergegeben werden, indem getButtons(boolean return_inverted) mit dem Parameter false aufgerufen wird: getButtons(false);

Daten Verarbeiten

Die getButtons() Funktion liefert ein uint16_t zurück. In dieser Ganzzahl sind die Bits entsprechend für die Button-Status aufgeführt. Welches Bit für welchen Button steht, wird aus folgender Tabelle ersichtlich:

Nr. 12 11 10 9 8 7 6 5 4 3 2 1
Button R L X A RIGHT LEFT DOWN UP START SELECT Y B
Wert 2048 1024 512 256 128 64 32 16 8 4 2 1
HEX 0x800 0x400 0x200 0x100 0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01

Wird also nur der Button A gedrückt, gibt getButtons(); folgenden Wert zurück: 1111000100000000

WICHTIG: Die letzten 4 Bits (Most Significant Bits, MSB, links) sind zu vernachlässigen! getButtons() ändert nur die ersten 12 Bits (Least Significant Bits, LSB, rechts). Daher sind die übrigen 4 Bits nicht genutzt und werden standardmäßig immer mit dem Wert 1 (oder nicht-invertiert mit dem Wert 0) wiedergegeben.

Durch logische Operationen mit einer Bitmaske können nun die einzelnen Bits abgefragt werden. Dafür sind die Konstanten (preprocessor directives) in SNESpaduino.h BTN_* angegeben. Diese Werte entsprechen den oben angegebenen Werten. Durch logische AND-Verknüpfung der wiedergegebenen Button-Status und der konstanten Bitmaske kann, wie im Beispiel ersichtlich, geprüft werden, ob ein Button gedrückt wurde.

Wer die beiden Beispiele der library sorgfältig durcharbeitet und etwas experimentiert (SNESpaduinoPrintToSerial eignet sich gut dazu, den Code zum Üben zu modifizieren) sollte schnell verstehen, wie die Daten zu parsen sind.

Kontakt

Für weitere Fragen, Anregungen, Pull Requests usw. bin ich immer gern zur Verfügung. Hinterlasse einfach einen Kommentar, schreibe eine Mail, twitter an @tacticalcode…

Die library ist unter CC-BY-SA 3.0 lizensiert. Also immer schön Teilen, Modden, Hacken!

MfG
Damon Dransfeld

Dieser Eintrag wurde veröffentlicht in Arduino
Bookmarken: Permanent-Link Schreibe einen Kommentar oder hinterlasse einen Trackback: Trackback-URL.
Achtung: Wordpress interpretiert bestimmte Zeichenfolgen als Markup und verändert diese. Nutzt für Programmcode lieber Gist oder PasteBin-Services und verlinkt die Code-Schnipsel.

Post a Comment

Ihre E-Mail wird niemals veröffentlicht oder verteilt. Benötigte Felder sind mit * markiert

*
*

Du kannst diese HTML Tags und Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>