Inspired by this github repository https://github.com/burks10/Arduino-SNES-Controller and the accompanying YouTube video https://www.youtube.com/watch?v=93oCS9nF_y0, I want to write down the steps I followed to get a SNES controller working on a PC without bying any SNES adapters or permanently and irreversibly modifying the controller.
The idea is that an Arduino is used to adapt the SNES controller to a USB HID Joystick device that the PC can use to control an emulator. For that the Arduino’s USB connector chip MEGA16u2 that takes care of the USB protocol on the Arduino is reprogrammed by flashing custom firmware to it. The solution also is able to flash back the original Arduino USB firmware, so you will not permanently alter your Arduino.
The USB firmware is contributed by the UnoJoy project which has it’s repository under https://github.com/AlanChatham/UnoJoy. UnoJoy supports the PS3 controller out of the box but not the SNES controller. burks10 added a sketch that is able to interpret the SNES commands and insert them into the data structures that the UnoJoy project mandates.
The software architecture is as follows. The USB protocol mandates that the USB controller inside your PC polls USB HID devices for input state. That means that the MEGA16u2 chip on the Arduino is constantly polled for input data. The custom UnoJoy firmware that is flashed to the MEGA16u2 will read a dataForController_t data structure from the sketch that runs on the Arduino. It will return this information back to the USB controller. The sketch on the Arduino will poll the SNES controller and it will interpret the signals as button or dpad presses. It will fill in the dataForController_t with the SNES controller’s button state. This is how a button press makes it from the SNES controller through the MEGA16u2 chip, through USB, through the PC’s USB controller to the emulator.
When the newly flashed Arduino is plugged in into the PC, it will register with the operating system as a HID Joystick. Selecting this HID Joystick in your emulator allows you to read input from this device.
Here are the steps in detailed order:
Hint / Important
Turn off USB Helper
Turn off all tools that might interfere with USB such as USB Overdrive.
Wire Up the SNES controller to the arduino.
Locking at the controller plug, there is a rounded corner and a flat corner.
Putting the flat corner on the left and the rounded corner on the right, the pins are numerate 1 through 7:
| 1 2 3 4 | 5 6 7 )
Connect Pin 1 on the controller to 5V on the Arduino, that means:
Controller Pin 1 <-> Arduino 5V
Controller Pin 2 <-> Arduino Pin 6
Controller Pin 3 <-> Arduino Pin 7
Controller Pin 4 <-> Arduino Pin 12
Controller Pin 7 <-> Arduino GND
Upload the correct sketch to the Arduino
git clone https://github.com/burks10/Arduino-SNES-Controller.git
Open Arduino IDE on the file snes/snes.ino
As a board, select the ardunio uno.
Validate and upload the sketch.
Install the dfu-programmer
see https://www.arduino.cc/en/Hacking/DFUProgramming8U2
sudo port install dfu-programmer
Install libusb and libusb-compat
Turn on DFU mode
Short the 2 pins closest to the USB port to enter DFU mode
Prepare the flashing of new firmware for the Ardunio USB controller chip
git clone https://github.com/AlanChatham/UnoJoy.git
cd UnoJoy/UnoJoy
Edit the file TurnIntoAJoystick.command file
Replace all occurences of ./dfu-programmer by dfu-programmer
Make it executable and run the command file:
chmod a+x TurnIntoAJoystick.command
./TurnIntoAJoystick.command
Connect the Ardunio to the PC
Unplug the arduino and plug it back in
Check if MacOS has detected a controller
MacIcon in the top left > About this Mac > Overview > System Report … > USB > check if there is an entry alled ‘UnoJoy Joystick’
Reverting the process (Getting back the normal Arduino Behaviour)
If you want your arduino back, enter DFU mode again.
While the arduino is plugged in to USB, short the pins shortest to the USB port.
Modify the file TurnIntoAnArduino.command and replace all occurences of ./dfu-programmer by dfu-programmer
Make it executable and run the command file:
chmod a+x TurnIntoAnArduino.command
./TurnIntoAnArduino.command