Atari 2600 Joystick to USB HID Joystick

Atari 2600 joysticks are as simple as it gets internally. Only six of the pins on the connector are needed, for the five switches (one each for the four directions, one for the single button) and a common connection, so it's trivial to wire one up to a microcontroller and read input from it. You don't even need to connect +5V since there's no active circuitry inside, but external pull-up resistors are needed since there are no internal ones. It's just a little more complicated for reading paddles or the keyboard controllers, but that's a project for another day. Since it's so simple and uses an off-the-shelf DE-9 connector, the design caught on and became a de facto standard and got used in lots of home computers in the 1980s, so there are tons of compatible joysticks out there of varying quality. Here's the pinout for a basic joystick:

DE-9 connector, console (male) end
Pin Function
1 Up
2 Down
3 Left
4 Right
5 N/C
6 Button
7 +5V
9 N/C

My current prototype is using a Digispark Pro clone which is total overkill, but I happened to have one sitting around after finishing the Sega Genesis controller USB converter. The hardest part of the project by far was scrounging up a compatible joystick that would actually trigger reliably — after thorough cleaning, I was able to get one Wico joystick least working well enough to test the converter. Since then, I found a Coleco Gemini joystick in the junk bin of a local store that works great after cleaning out the vintage dust and dead bugs. Sometime in the (hopefully) near future I'll see about getting the project off the breadboard and into a more permanent form using a regular cheap Digispark clone and a shift register. Any digital I/O pins can be used, the example code just uses whichever ones happened to be convenient.

#include <DigiJoystick.h>

#define NORTH 6
#define SOUTH 7
#define WEST 8
#define EAST 9
#define BUTTON 10

byte buttons = 0b00000000;
byte xdir = 128;
byte ydir = 128;

void setup() {
  pinMode(NORTH, INPUT);
  pinMode(SOUTH, INPUT);
  pinMode(EAST, INPUT);
  pinMode(WEST, INPUT);
  pinMode(BUTTON, INPUT);

void loop() {
  xdir = 128;  
  ydir = 128;  

  buttons = digitalRead(BUTTON) ? 0b00000000 : 0b00000001;

  if (digitalRead(NORTH) == LOW)
    ydir = 0;
  else if (digitalRead(SOUTH) == LOW)
    ydir = 255;

  if (digitalRead(WEST) == LOW)
    xdir = 0;
  else if (digitalRead(EAST) == LOW)
    xdir = 255;

  DigiJoystick.setButtons((byte)buttons, 0x00);

The current prototype using a Digispark Pro

Glamour shot!

Final destination?