Sunday, August 05, 2012

Interfacing Atari 2600 Joystick to Arduino

Cleaning up the study the other day i found an old joystick from an Atari 2600.  So like everything else, I tried to connect it to my Arduino :)

The Arduino "button" example uses pull-down resistors, but after awhile i realized that approach wasn't going to work. This joystick switches to ground, meaning that any voltage going to say the Fire button will "dissapear" when the button is pressed. Same for each of the directions too, because this is a "digital" joystick, they're all just buttons inside the joystick.

So the answer is to measure what's going *into* the joystick, not what's coming out. For each of the joystick pins we send 5v into the joystick, and monitor that voltage. If there's 5v going in, then nothing has happened. But if that suddenly drops to near nothing, then a button has been pressed.

Figure 1: Current limiting resistors.

 Interfacing Atari Joystick to Arduino:
 Returns output of Atari 2600 9 pin joystick to Arduino serial console.
       +---------> Right
       | +-------> Left
       | | +-----> Down
       | | | +---> Up 
       | | | | 
 5 \ x o o o o / 1
    \ x o x o / 
   9 `~~~~~~~' 6
        |   |
        |   +----> Button
        +--------> Ground
 pinout via
 The circuit:
 * 5v through 10k resistor to each of the 5 joystick output pins
 * Arduino ground to Joystick ground
 * 5 data wires from joystick inputs to the arduino pins in the format:
    5V -> 10K resistor > Data to Arduino > Joystick Input
 created 2012 by Julius Roberts
 This example code is in the public domain.

// constants won't change. They're used here to set pin numbers:
const int FireButtonPin = 2;     
const int JoystickUpPin = 3;
const int JoystickDownPin = 4;
const int JoystickLeftPin = 5;
const int JoystickRightPin = 6;

void setup() {
  // initialize the Joystick pins as inputs:
  pinMode(FireButtonPin, INPUT);     
  pinMode(JoystickUpPin, INPUT);
  pinMode(JoystickDownPin, INPUT);
  pinMode(JoystickLeftPin, INPUT);
  pinMode(JoystickRightPin, INPUT);


void loop(){
  // read the state of the pushbutton value.  Because we're using a
  // pullup resistor, the value for each of the variables will normally 
  // be 1, and 0 when pressed.  This is the opposite of normal 
  // programming logic where 1 = true.  So we invert the variable using
  //  the map function  
  int FireButtonState = digitalRead(FireButtonPin); 
  FireButtonState = map(FireButtonState,0,1,1,0); 
  int JoystickUpState = digitalRead(JoystickUpPin); 
  JoystickUpState = map(JoystickUpState,0,1,1,0);
  int JoystickDownState = digitalRead(JoystickDownPin); 
  JoystickDownState = map(JoystickDownState,0,1,1,0);
  int JoystickLeftState = digitalRead(JoystickLeftPin); 
  JoystickLeftState = map(JoystickLeftState,0,1,1,0);
  int JoystickRightState = digitalRead(JoystickRightPin);  
  JoystickRightState = map(JoystickRightState,0,1,1,0);

  // output the setting to the serial console
  Serial.print("Fire: "); Serial.print(FireButtonState);
  Serial.print(" Up: "); Serial.print(JoystickUpState);
  Serial.print(" Down: "); Serial.print(JoystickDownState);
  Serial.print(" Left: "); Serial.print(JoystickLeftState);
  Serial.print(" Right: "); Serial.println(JoystickRightState);

1 comment:

nate808 said...

I think you are ok if you use just the ground near the power section. At least it looks like it works for this guy: