{"id":37,"date":"2009-09-10T21:16:53","date_gmt":"2009-09-11T04:16:53","guid":{"rendered":"http:\/\/www.built-to-spec.com\/blog\/?p=37"},"modified":"2010-02-06T10:13:20","modified_gmt":"2010-02-06T17:13:20","slug":"using-a-pc-joystick-with-the-arduino","status":"publish","type":"post","link":"http:\/\/www.built-to-spec.com\/blog\/2009\/09\/10\/using-a-pc-joystick-with-the-arduino\/","title":{"rendered":"Using a PC Joystick with the Arduino"},"content":{"rendered":"<p>I didn\u2019t find any tutorials on how to use a standard PC joysticks\/gamepads with the Arduino directly (someone correct me if I\u2019m wrong), so I thought I\u2019d take this opportunity to write one.\u00a0 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\u2019s not ideal for all projects) or having to make your own entirely from scratch.\u00a0 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.\u00a0 I use an old joystick that I\u2019ve held on to for use with various projects to control the Labywiinth for debug and when we don\u2019t have a PC set up to relay Bluetooth through.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/PC-Joystick.jpg\"><img loading=\"lazy\" class=\"size-medium wp-image-70 aligncenter\" title=\"PC Joystick\" src=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/PC-Joystick-271x300.jpg\" alt=\"PC Joystick\" width=\"271\" height=\"300\" srcset=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/PC-Joystick-271x300.jpg 271w, http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/PC-Joystick-927x1024.jpg 927w\" sizes=\"(max-width: 271px) 100vw, 271px\" \/><\/a><\/p>\n<p>I should clarify here that the PC joysticks\/gamepads I\u2019m referring to here are the old school PC joysticks have a 15-pin D-sub connector rather than USB.\u00a0 These are readily available in a number of places and are generally very cheap (most thrift stores I\u2019ve been in have them for under $5).\u00a0 If they don\u2019t have tons of features, like more than 4 buttons and 4-axis control, they\u2019ll most likely just be a few potentiometers and buttons wired up in the standard joystick port configuration.\u00a0 You can find a good write up on the PC joystick port <noindex><a rel=\"nofollow\" title=\"PC Joystick Port\" href=\"http:\/\/www.epanorama.net\/documents\/joystick\/pc_joystick.html \" target=\"_blank\">here<\/a><\/noindex> including a history of the interface (and some info on circuits <noindex><a rel=\"nofollow\" title=\"PC Joystick Circuitd\" href=\"http:\/\/documents.epanorama.net\/documents\/joystick\/pc_circuits.html\" target=\"_blank\">here<\/a><\/noindex>).\u00a0 It's also worth noting that if you want to use a more advanced joystick with your project and don\u2019t need a stand alone solution, you can always use a PC to relay input from that joystick to the Arduino as described <noindex><a rel=\"nofollow\" title=\"Arduino Joystick Tutorial\" href=\"http:\/\/www.instructables.com\/id\/control_arduino_using_joystick\/\" target=\"_blank\">here<\/a><\/noindex>, but I really like being able to plug straight into the Arduino in most cases.<\/p>\n<p>It is pretty straight forward to create a dongle to connect any of these old school interface devices to your Arduino.\u00a0 First off, you\u2019ll 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 <noindex><a rel=\"nofollow\" title=\"15-pin Female d-sub\" href=\"http:\/\/search.digikey.com\/scripts\/DkSearch\/dksus.dll?Detail&amp;name=L77SDA15S-ND\" target=\"_blank\">cheap one<\/a><\/noindex> can be had for a whopping $1.33.\u00a0\u00a0 You can also cut up an old 15-pin cable extender if you happen to come across one.\u00a0 Next, for each axis you\u2019ll need a resistor to create a voltage divider and for each button you\u2019ll need a resistor to use as a pull up (more on each of these later).\u00a0 I used 100K Ohm resistors for the voltage dividers to measure the X-axis and Y-axis potentiometers and 10K Ohm resistors should be sufficient for pull up resistors for your buttons.\u00a0 Here\u2019s what the resulting circuit would look like if you wired up all the available buttons and potentiometers:<\/p>\n<div id=\"attachment_67\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Joystick-Dongle1.png\"><img aria-describedby=\"caption-attachment-67\" loading=\"lazy\" class=\"size-medium wp-image-67\" title=\"Joystick Dongle\" src=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Joystick-Dongle1-300x168.png\" alt=\"Joystick Dongle Schematic\" width=\"300\" height=\"168\" srcset=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Joystick-Dongle1-300x168.png 300w, http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Joystick-Dongle1.png 981w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-67\" class=\"wp-caption-text\">Joystick Dongle Schematic<\/p><\/div>\n<p>I suggest only wiring up the inputs you\u2019re interested in as I did (in my case, just the X-axis and Y-axis):<\/p>\n<p><a href=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Arduino-Joystick-Setup.jpg\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-43\" title=\"Arduino Joystick Setup\" src=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Arduino-Joystick-Setup-300x225.jpg\" alt=\"Arduino Joystick Setup\" width=\"300\" height=\"225\" srcset=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Arduino-Joystick-Setup-300x225.jpg 300w, http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Arduino-Joystick-Setup.jpg 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>I used a wiring harness \u201c<noindex><a rel=\"nofollow\" title=\"Wiring Harness Sheild\" href=\"http:\/\/www.thingiverse.com\/thing:919\" target=\"_blank\">shield<\/a><\/noindex>\u201d so I don\u2019t accidentally rip out my jumper wires while using the joystick.<\/p>\n<p>If you\u2019re familiar with potentiometers through other <noindex><a rel=\"nofollow\" title=\"Reading Analog Input\" href=\"http:\/\/arduino.cc\/en\/Tutorial\/AnalogInput\" target=\"_blank\">experiments<\/a><\/noindex> with your Arduino (or other microcontrollers) where you hook up a potentiometer and read the voltage on the wiper with the ADC, you may be wondering why we need to use another resistor to measure the potentiometers in the joystick. The answer is, if you look at the schematic of a joystick you\u2019ll notice that only two of the terminals of the potentiometer are wired up.\u00a0 The way you would normally read the position of a potentiometer on the Arduino is to hook up the two outside terminals of the potentiometer to +5V (or whatever voltage you\u2019re operating at) and ground and connect the wiper of the potentiometer to one of the analog channels and read the voltage at the wiper terminal. The reason this works is because the entire potentiometer acts as a <noindex><a rel=\"nofollow\" title=\"Voltage Divider\" href=\"http:\/\/en.wikipedia.org\/wiki\/Voltage_divider\" target=\"_blank\">voltage divider<\/a><\/noindex> with current flowing through the two outside terminals.\u00a0 The location of the wiper is basically where the two resistors in the voltage divider are split, and the total resistance of these two resistors is always the value of the potentiometer (just because of the way the potentiometer is constructed).<\/p>\n<p>To read the joystick potentiometer, we\u2019ll need to set up our own voltage divider with a 100K Ohm resistor:<\/p>\n<div id=\"attachment_41\" style=\"width: 210px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-Divider.png\"><img aria-describedby=\"caption-attachment-41\" loading=\"lazy\" class=\"size-full wp-image-41\" title=\"Voltage Divider\" src=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-Divider.png\" alt=\"Basic Voltage Divider Circuit for Reading a Potentiometer\" width=\"200\" height=\"291\" \/><\/a><p id=\"caption-attachment-41\" class=\"wp-caption-text\">Basic Voltage Divider Circuit for Reading a Potentiometer<\/p><\/div>\n<p>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:<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-vs-Resistance.gif\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-62\" title=\"Voltage vs Resistance\" src=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-vs-Resistance.gif\" alt=\"Voltage vs Resistance\" width=\"430\" height=\"315\" srcset=\"http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-vs-Resistance.gif 537w, http:\/\/www.built-to-spec.com\/blog\/wp-content\/uploads\/2009\/09\/Voltage-vs-Resistance-300x220.gif 300w\" sizes=\"(max-width: 430px) 100vw, 430px\" \/><\/a><\/p>\n<p>You'll notice that, while close, this relationship isn't linear.\u00a0 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 <noindex><a rel=\"nofollow\" title=\"Ohm's Law\" href=\"http:\/\/en.wikipedia.org\/wiki\/Ohm%27s_law\" target=\"_blank\">Ohm\u2019s law<\/a><\/noindex> and solve for R1 in our voltage divider circuit.\u00a0 When we\u2019re done we end up with the following equation:<\/p>\n<p>R1 = 500\/V1 \u2013 100<\/p>\n<p>Where R1 is the resistance in K Ohms and V1 is the measured voltage in volts.\u00a0 This is all well and good if we\u2019re 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:<\/p>\n<p>R1 = 102300\/V1 - 100<\/p>\n<p>Now we can plug in the raw value read from the ADC and we\u2019ll get an integer value from 0-100 that should correspond to the position of the joystick on that axis.\u00a0 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.\u00a0 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.\u00a0 It\u2019s simpler to just modify our equation a bit to get the range we want:<\/p>\n<p>1.8 *(102300\/V1 - 100) = 184140\/V1 \u2013 180<\/p>\n<p>Here\u2019s 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:<\/p>\n<p><code>void setup() {<br \/>\nSerial.begin(9600);<br \/>\n}<\/code><\/p>\n<p><code>void loop () {<br \/>\nlong x, y;<br \/>\nint x_in, y_in;<\/code><\/p>\n<p><code>x_in = analogRead(0);<br \/>\ny_in = analogRead(1);<\/code><br \/>\n<code><br \/>\nif (x_in)<br \/>\nx = 102300\/x_in - 100;<br \/>\nelse<br \/>\nx = -1; \/\/this should only happen if the joystick isn't connected<br \/>\nif (y_in)<br \/>\ny = 102300\/y_in - 100;<br \/>\nelse<br \/>\ny = -1; \/\/this should only happen if the joystick isn't connected<\/code><\/p>\n<p><code>Serial.print(\"X: \");<br \/>\nSerial.print(x, DEC);<\/code><\/p>\n<p><code>Serial.print(\"\u00a0\u00a0 Y: \");<br \/>\nSerial.print(y, DEC);<\/code><\/p>\n<p><code>Serial.println(\"\");<br \/>\n}<\/code><\/p>\n<p>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).\u00a0 There's a simple example for using a <noindex><a rel=\"nofollow\" title=\"Button Tutorial\" href=\"http:\/\/www.arduino.cc\/en\/Tutorial\/Button\" target=\"_blank\">button as an input<\/a><\/noindex> on the Arduino site.\u00a0 The main reason to hook up the buttons to be active low is because some joysticks and game pads have circuits that are powered off of the ground pins that are used for the buttons and the +5V pins that are used for the potentiometers.\u00a0 Most often this circuitry is used to implement some \"turbo\" functionality were the controller itself quickly toggles a button when it is pressed and held.\u00a0 I've tested one controller that I happened to have on hand that had a \"turbo\" mode and it worked properly with the above dongle circuit.<\/p>\n<p>So that's it!\u00a0 You should now be able to put some old joysticks or game pads to work in your upcoming  Arduino projects.\u00a0 Feel free to post any additional questions you might have and\/or corrections I should make to the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I didn\u2019t find any tutorials on how to use a standard PC joysticks\/gamepads with the Arduino directly (someone correct me if I\u2019m wrong), so I thought I\u2019d 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\u2019s 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.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[14,27,18],"_links":{"self":[{"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/posts\/37"}],"collection":[{"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/comments?post=37"}],"version-history":[{"count":31,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/posts\/37\/revisions"}],"predecessor-version":[{"id":74,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/posts\/37\/revisions\/74"}],"wp:attachment":[{"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/media?parent=37"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/categories?post=37"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.built-to-spec.com\/blog\/wp-json\/wp\/v2\/tags?post=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}