I didn’t find any tutorials on how to use a standard PC joysticks/gamepads with the Arduino directly (someone correct me if I’m wrong), so I thought I’d take this opportunity to write one. These input devices can make controlling your projects easy and there are a few controller schemes you can choose from rather than being locked down to a standard game controller (as awesome as the NES controller is, it’s not ideal for all projects) or having to make your own entirely from scratch. Interfacing with these old devices is pretty easy as well since you don't need to decipher any protocol to communicate with them and you can generally figure out what's going on with them with just a simple multimeter. I use an old joystick that I’ve held on to for use with various projects to control the Labywiinth for debug and when we don’t have a PC set up to relay Bluetooth through.
I should clarify here that the PC joysticks/gamepads I’m referring to here are the old school PC joysticks have a 15-pin D-sub connector rather than USB. These are readily available in a number of places and are generally very cheap (most thrift stores I’ve been in have them for under $5). If they don’t have tons of features, like more than 4 buttons and 4-axis control, they’ll most likely just be a few potentiometers and buttons wired up in the standard joystick port configuration. You can find a good write up on the PC joystick port
It is pretty straight forward to create a dongle to connect any of these old school interface devices to your Arduino. First off, you’ll need a 15-pin female D-Sub connector (preferably with solder cups for ease of construction), which you can get from old PC riser cards (486 or older generally) or a quick Digikey search will reveal that a
I suggest only wiring up the inputs you’re interested in as I did (in my case, just the X-axis and Y-axis):
I used a wiring harness “
If you’re familiar with potentiometers through other
To read the joystick potentiometer, we’ll need to set up our own voltage divider with a 100K Ohm resistor:
This is the same circuit that is wired up to each potentiometer in the dongle schematic, I've just shown the potentiometer inside the joystick for clearity. If we graph out the voltage we would measure as we varied the 100K potentiometer in the joystick, it would look something like this:
You'll notice that, while close, this relationship isn't linear. If we want to go from this measured voltage to the actual resistance of the potentiometer in the joystick (which is a presumably linear indicator of the actual position of the potentiometer) we can apply
R1 = 500/V1 – 100
Where R1 is the resistance in K Ohms and V1 is the measured voltage in volts. This is all well and good if we’re measuring the voltage with a multimeter, but since the Arduino reports measured voltage as an integer on a scale from 0-1023, we need to scale our equation:
R1 = 102300/V1 - 100
Now we can plug in the raw value read from the ADC and we’ll get an integer value from 0-100 that should correspond to the position of the joystick on that axis. I needed to adjust the range a bit for the Labywiinth project so that the position of the joystick was mapped to 0-180 with 90 being the center. To do this you could multiply the result by 1.8 but this will require a floating point operation or some additional integer operations to do properly. It’s simpler to just modify our equation a bit to get the range we want:
1.8 *(102300/V1 - 100) = 184140/V1 – 180
Here’s some sample Arduino code that reads the position of a joystick who's X-axis and Y-axis are connected to ANALOG0 and ANALOG1, respectively, and reports the resistance (position) of each axis back over the serial connection:
void setup() {
Serial.begin(9600);
}
void loop () {
long x, y;
int x_in, y_in;
x_in = analogRead(0);
y_in = analogRead(1);
if (x_in)
x = 102300/x_in - 100;
else
x = -1; //this should only happen if the joystick isn't connected
if (y_in)
y = 102300/y_in - 100;
else
y = -1; //this should only happen if the joystick isn't connected
Serial.print("X: ");
Serial.print(x, DEC);
Serial.print(" Y: ");
Serial.print(y, DEC);
Serial.println("");
}
As far as using the buttons on the joystick or game pad go, just treat them as a regular button, but remember that it's wired up to be active low (you'll read a 0 on the pin the button is connected to when it's pressed and a 1 when it's not). There's a simple example for using a
So that's it! You should now be able to put some old joysticks or game pads to work in your upcoming Arduino projects. Feel free to post any additional questions you might have and/or corrections I should make to the comments.
[…] Check out the full writeup at Craigs site here. […]
Nice writeup.
I will have to give it a try when I find my old joystick.
[…] showing our labyrinth in action at the Missouri state fair. He also publish this article “Using a PC Joystick with the Arduino“. Since older game port joysticks can be bought at thrift stores for around $3 its another […]
[…] FCS (the joystick) was just an old game controller joystick. Easy; someone had put up this page with instructions. I needed a few resistors and scratched my head a lot dealing with the simple […]
[…] keresgéltem (mint említettem, rengeteg az Arduino tutorial), megtaláltam ezt a cikket: http://www.built-to-spec.com/blog/2009/09/10/using-a-pc-joystick-with-the-arduino/ mintha nekem írták volna! Pontosan az, amire szükségem van. Mellesleg a léptetőmotorhoz is […]
[…] from “Built to Spec” [link] and modified to allow for different types of Gameport […]
[…] http://www.built-to-spec.com/blog/2009/09/10/using-a-pc-joystick-with-the-arduino/ […]
Nice writeup. Coincidentally I created a shield with the appropriate connectors on it that makes this a little easier – at lectrobox.com/joystick.
Cheers!
[…] 15p D Sub, and wire it for 2 joystick operation if you want, or stack a second shield. See http://www.built-to-spec.com/blog/2009/09/10/using-a-pc-joystick-with-the-arduino/ for more info. A Y Splitter Cable would allow two joysticks to a single port in this scenario. The […]
[…] found several useful guides online for hooking up a joystick, so decided I could hook up the Pro Pad. The Pro Pad […]
Most old controllers are all or nothing on their axes, in my experience which is somewhat limited. My question is, can I use a more modern joystick, such as,https://www.amazon.com/gp/product/B00OS4ILFK/ref=oh_aui_search_detailpage?ie=UTF8&psc=1 in the same way you are using an older joystick?
Yes, you can use that particular one as I’ve done here but I think you’ll need to substitute out a 5K resistor for the math to work out for you. You could always just hook the wiper directly to the analog pin you want, one end to ground, and one end to Vcc (5V or 3.3V depending on the flavor of Arduino you’ve got). Look up the standard potentiometer analog examples on Arduino’s website for more info on how to do that:https://www.arduino.cc/en/Tutorial/AnalogInput