Skip to content

Simple project for connecting NES/SNES gamepads to a computer using an Arduino.

Notifications You must be signed in to change notification settings

jared6502/arduino_gamepad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 

Repository files navigation

--------------------------------------------------
Simple Gamepad Interface Using an Arduino
--------------------------------------------------

This is a set of simple programs for attaching SNES controllers to a computer.

/sketch - the code that runs in the Arduino
/feeders - programs that run on the computer end to feed button press events to the OS

--------------------------------------------------
Arduino Sketch
--------------------------------------------------

Button code reference:
A - A
B - B
X - X
Y - Y
S - Select
T - Start
^ - Up
v - Down
< - Left
> - Right
L - L shoulder button
R - R shoulder button

	NES and SNES controllers are very simple devices. They consist of one or two (depending on controller type and age) shift register ICs with pullup resistors on the inputs that are shorted by carbon pads every time a button is pressed. They have three signals of importance - latch, clock, and data. These control the shift register IC(s) within the controller. A high pulse on the latch input stores the current state of the buttons into the shift register. After latching the current button state, data is shifted out bit by bit on the low-to-high transition of the clock signal. Each bit shifted out corresponds to the state of a button. NES controllers only have 8 inputs and will only transmit 8 bits, while SNES controllers transmit 12.

Button order:
     0123456789ABCDEF
NES  ABST^v<>--------
SNES BYST^v<>AXLR----


Example of timing - SNES gamepad, B, Y, and right held at the same time - note low = pressed

        ___
latch _|   |____________________________________________________________________________________________________
      _______    __    __    __    __    __    __    __    __    __    __    __    __    __    __    __
clock        |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |__|  |________
        |B       |Y    |S    |T    |^    |v    |<    |>    |A    |X    |L    |R    |-    |-    |-    |-
                        _____________________________       ____________________________________________________
data  xx_______________|                             |_____|

	While the button order change between NES and SNES may seem odd (A/B becomes B/Y), it makes sense due to the physical button layout. It also means that NES and SNES controllers are interchangeable whenever the extra buttons are not needed, such as in games like Super Mario.

NES
  ^
<   > - - B  A
  v

SNES
  L         R
  ^         X
<   > - - Y   A
  v         B

  These bit streams are gathered from up to 8 different controllers using only ten I/O pins by sharing the clock and latch signals across all controller ports. Once data is gathered from all controllers, it is streamed out through the serial port. A "packet" of input data normally starts with 0x00 0xFF, as this is not a button combination that is possible on the majority of NES/SNES gamepads and their clones. It is then followed by eight 16-bit words of data.
  
Packet format:
     start       |    gamepad 1    |...|    gamepad 8
76543210 76543210|76543210 76543210|...|76543210 76543210
00000000 11111111|BYST^v<> AXLR----|...|BYST^v<> AXLR----

In this case, the bits are 1 = pressed, 0 = not pressed, which is the opposite of the raw input signal state.

--------------------------------------------------
Feeders
--------------------------------------------------

/feeders/windows
Contains a simple feeder program made from the vJoy feeder example. It reads the button inputs from the serial port and feeds them to the vJoy driver. It requires the installation of the vJoy driver to function. Building and using it may require installing a specific version of the driver and/or SDK. This feeder was originally built and tested with vJoy 2.1.8 on both Windows 7 and Windows 10.

/feeders/unix
Contains a simple C program that reads the button inputs from the serial port and feeds them to the OS using libevdev. This should build correctly using the command:
gcc arduino_evdev_feeder.c -levdev -o feeder

Depending on OS, you may have to specify include and library paths. An example of this is in the file build.sh.

When the feeder program is executed, it should create the appropriate event* devices under /dev/input. Functionality can be verified using evtest, showing proper delivery of events.

About

Simple project for connecting NES/SNES gamepads to a computer using an Arduino.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published