The SNESpaduino library enables You to hook up Your old SNES (Super Nintendo Entertainment System) Gamepad as an input device to you Arduino.
Basically, the library does these 3 tasks:
- Easy interfacing – You just need to connect 3 Pins (Latch, Clock, Data)
- Read the buttons’ states – A function reads from the controller, which buttons are currently pressed
- Help You parse the data – Using simple constants, processing the returned data is peanuts for You.
Not only that the library is incredible easy to use, You can also easily get to know the structure of an Arduino library, how these things are developed and what’s happening in the background. All the code is documented, the Commits on GitHub are also full of useful details. If you’re interested, dive in – it’s easy!
Download and Install
You can get the library in several ways:
- Clone the Git repository: git clone https://github.com/TacticalCode/SNESpaduino.git (recommended)
- Download the repository as a ZIP (recommended)
- Direct Download (most likely out of date!)
To ensure you have the super-duper latest code, grab it from GitHub. Just use the git clone command from above on your OS of choice. However, if you don’t have the git program installed, feel free to download the repository as a ZIP. But note: When downloading the repo as a zip, you have to rename the extracted folder SNESpaduino-master (remove the -master)!
If you’re new to libraries, the official Arduino Library reference explains how you can install one. When You have successfully imported the library into the IDE, go over to connect your gamepad.
Connect the SNES Gamepad to an Arduino
The SNES Gamepad has 5 contacts: +5V, GND, Latch, Clock, Data. Here is the pin configuration of the connector (from left to right, starting with the group of 4 contacts). Also take a look at the picture, where pin-numbers as well as color coding is noted:
Connect the gamepad’s GND / 5V to your Arduino’s Ground / +5V. Latch, Clock and Data go to any In/Out pin. Even analog ones. Over the Clock and Latch lines, the Arduino will send data, 5V/GND (HIGH/LOW), to tell the gamepad we’d like to receive the current state of all buttons. Over the Data line, our Arduino will receive that data.
In my examples, I used the pins 19, 20 and 21 of my Arduino Mega, but as said, you may use any In/Out Pin.
Test library and gamepad
Once the library is installed and the gamepad connected to the Arduino, it’s time to test things. The library includes 2 example sketches. Those are available under File > Examples > SNESpaduino. First, load the SNESpaduinoPrintToSerial sketch, compile it and load it onto the Arduino. The project’s code is documented, so you should be able to figure out what it does. If not, leave me a comment ;)
Using the library works like this: First, an instance of SNESpaduino is created, handing over the 3 pin numbers for Latch, Clock and Data lines to the constructor. Next, you can use the function getButtons() which will return the current state of all 12 Buttons as a 16 digit integer. Each bit in that integer represents a button: Is this bit 0 / LOW / False, the button is currently being pressed. So if a bit is 1 / HIGH / True, that means the according button is currently NOT being pressed.
This is due to the controller’s hardware design. Because this might be confusing, getButtons() will by default return the opposite (negative) bit pattern. This way, it’s easier to use If-Statements to check which buttons are being pressed (and seems more intuitive). If you need to have the “raw”, non-inverted output from the controller, call getButtons(boolean return_inverted) with the parameter false: getButtons(false);
The getButtons() function returns a uint16_t. As mentioned above, the bits in this integer represent which buttons are being pressed. To work with the data, here is a table to determine which bit represents which button:
So, if only A is being pressed, getButtons(); returns the value 1111000100000000
IMPORTANT: The last 4 bits (Most Significant Bits, MSB, left) must be ignored! getButtons() ony affects the first 12 bits (Least Significant Bits, LSB, right). So the remaining 4 bits will never be touched, they will always return as 1 (or non-inverting: 0).
Now, using logic operations and a bitmask, individual bits can easily be checked. For this purpose, SNESpaduino.h contains constants (preprocessor directives) BTN_*. These values are the same as the ones above in the table. If you wanted to check if The A button is being pressed, simply apply the logic AND function to the buttons’ states and the bitmask BTN_A. If this statement (button_states & BTN_A) is true, button A is in fact being pressed. See the 2 examples shipped with the library, it’s really simple.
I’d recommend modifying SNESpaduinoPrintToSerial – you can easily get used to the library’s usage while writing a simple function like… Check each individual button if it’s being pressed (and write that to Serial, just like in the example).
Please, feel free to contact me for any further questions, ideas, pull requests and so on. Write a comment or an eMail, or twitter @tacticalcode
All code (and this tutorial) is being published under CC-BY-SA license. So Share, Remix and Hack on!
– Damon Dransfeld