Using an NES controller with a Gameduino

The NES game controller is a popular controller for Gmaeduino-style games. It has a four-way direction pad and four buttons labelled "Select", "Start", "A" and "B" - perfect for retro gaming!

Theory

These controllers use a serial interface to communicate with the console. The state of each button is sent in sequence along a single 'data' wire and the other wires are there to supply power and control signals to the chip (the chip used is a "4021 shift register" if you want to google it). This means there are only five connecting wires no matter how many buttons the controller has on it.

The wires are:

+5V
5 Volt power supply.
GND
Ground connection.
STROBE
When this line goes LOW the chip loads the state of all the controller's buttons into its internal register.
CLOCK
When this line goes from LOW to HIGH the serial chip's internal register shifts one bit to the left (the next button appears on the DATA wire).
DATA
Connected to the output of the chip's shift register.

Step 1: Identify your wires

The first step in connecting the controller is to find out the color of each of the wires in your controller. Cut the plug off, leaving a few inches of cable attached to it, then strip back the cable as shown in the photo below.

You'll need a multimeter (or anything else which lights up or buzzes when a complete circuit is made). If the probes of your multimeter/gadget don't fit in the holes in the plug (mine didn't!) then use a paperclip as an adapter.

I once used a garage door opener as a circuit tester...whenever the door
opened it meant there was a complete circuit!

Identify all the wires which connect to the pins listed above and write them down. Luckily the person who chose the plug for the NES chose one which is unambiguous no matter which way you look at it (very good choice!)

My wires were colored as follows:

+5V
 Red 
GND
 Brown 
STROBE
 Black 
CLOCK
 Yellow 
DATA
 Orange 

Step 2: Connect it to your Gameduino

Now you need to connect the controller to your Gameduino. Strip the wires on the end of the cable which connects to the controller and get soldering!

How you do this is up to you and depends on what materials you have available and how tough it needs to be (are children going to fight over the controller...?)

I used some Arduino header pins for mine so it's easy to connect and disconnect. If you want something permanent you could solder the wires to a shield like I did with my TV game joystick or even to the bottom of the Gameduino itself (the Gameduino also has some nice holes to tie the cable firmly to the board...)

Header pins - no Arduino owner should ever be without them...
Put +5V and GND in one group and STROBE/DATA/CLOCK in another.
Split the pin block in two and connect it to the Gameduino. Double-check
the +5V and GND wires - very bad things can happen if you get them wrong!

nb. I connected my controller to the Arduino analog pins - analog pins can work exactly the same as digital pins but are much less likely to conflict with other Arduino shields and SPI devices.

Step 3: Write some code

Reading the controller is quite easy:

In Arduino code it looks something like this:

// Pin definitions - where the wires are connected
#define NES_DATA A0
#define NES_STROBE A1
#define NES_CLOCK A2

// Configure the Arduino pins for an NES controller
Joystick::Joystick()
{
  pinMode(NES_DATA,INPUT);     digitalWrite(NES_DATA,HIGH);
  pinMode(NES_STROBE,OUTPUT);  digitalWrite(NES_STROBE,HIGH);
  pinMode(NES_CLOCK,OUTPUT);   digitalWrite(NES_CLOCK,HIGH);
}

// Read the next button
static byte readNesBit(byte button)
{
  const bool b = (digitalRead(NES_DATA)==LOW);
  digitalWrite(NES_CLOCK,LOW);
  digitalWrite(NES_CLOCK,HIGH);
  return (b)? button: 0;
}

// Read complete controller state
void Joystick::read()
{
  ...
  digitalWrite(NES_STROBE,LOW);
  buttons  = readNesBit(buttonA);
  buttons |= readNesBit(buttonB);
  buttons |= readNesBit(buttonSelect);
  buttons |= readNesBit(buttonStart);
  dpad  = readNesBit(0x01);
  dpad |= readNesBit(0x02);
  dpad |= readNesBit(0x04);
  dpad |= readNesBit(0x08);
  digitalWrite(NES_STROBE,HIGH);
}

(nb. The code is included in my Universal Joystick Reader and can be selected by
changing a #define in "joystick.cpp")

Return to main page...