Arduino Joystick Shield for PC Game Port Joysticks
What is this thing?
Whether you're trying to write an Arduino game, drive a robot, or simulate the control of a rocket ship, there are lots of fun reasons to use a joystick with your Arduino or Arduino-compatible device. This easy-to-use, fully assembled Arduino shield lets your Arduino sketches access any old-style PC joystick with a 15-pin (DB-15) game port interface.
The shield comes with an Arduino library and example sketch demonstrating how your program can read the joystick's position. The X and Y movement of the stick are returned in steps from -100 (fully up or left) to +100 (fully down or right). Your sketch can also detect button-pushes for up to two joystick buttons.
The Joystick Shield comes with Arduino Stacking Headers, making it easy to combine with other shields to build more complex sketches. Our shield also lets you pick which analog and digital pins it uses -- the X and Y position can use your choice of analog inputs A0, A1, A2 and A3; the buttons can use digital inputs 6, 7, 8, or 9. This flexibility ensures maximum compatibility by letting you avoid pin conflicts if your sketch is using other Arduino pins. You can even stack two of the Joystick Shields on top of each other and use two separate joysticks from your sketch -- perfect for two-person games!
The shield also comes with a prototyping area consisting of a 15x8 matrix of 0.1'' spaced holes, useful if your project needs space for other discrete components.
A joystick with a 15-pin (DB15) game port interface is required, and not included with the shield. (USB Joysticks are not supported.) If you don't have a game-port joystick in your junk drawer, many are available at low cost from your local thrift store, PC recycling shop, and auction web sites such as EBay.
Can I buy one?
- If you're in the United States, you can buy the board on Amazon. If you have Amazon Prime, two-day shipping is free!
- If you're outside the United States, you can buy the board from my eBay Store; eBay will export it using their Global Shipping Program.
Downloads
The Arduino library, including example sketch, can be downloaded here.
The library is also available on github.
You can also download the schematic (PDF) and the Eagle schematic and board layout files for Eagle v6.
Arduino Pin Configuration
The shield uses up to four pins on your Arduino. Two analog input pins are required to sense the position of the stick (one for the X axis, one for the Y axis). Up to two digital pins are needed to sense the state of the two fire buttons.
For maximum compatibility with other shields, the Lectrobox Joystick Shield lets you configure which Arduino pins it uses. The analog and digital pins both have configuration blocks on the shield, with pin selections made by placing jumpers in the desired positions. The pin selection blocks look like this:
The pins used by the X and Y axes are selected using the Analog Select block. The shield can use Analog Inputs A0, A1, A2 and A3. Place a jumper between the "X" and the pin number you wish to use to sense the X axis. Do the same for the Y axis. For example, the diagram below shows how your Analog Select block should look if you want to sense the X axis using analog input A0, and the Y axis using A1.
Other configurations are possible, e.g., using A2 for X, and A3 for Y, as shown below:
Similarly, the Digital Select block is used to pick the digital I/O pins used to sense the joystick's two fire buttons. Various combinations of digital 6, 7, 8, and 9 can be used. For example, configuration below uses digital 6 for the first fire button (called "A"), and digital 7 for the second ("B") button.
To use two shields simultaneously with two joysticks (e.g., for a two-player game), make sure to set all pins to be non-conflicting. For example, configure the first shield to use X0/Y1/A6/B7, and the second to use X2/Y3/A8/B9.
If you do not need to sense the fire buttons, remove the jumpers from the Digital Select block.
Using the Library
To access the joystick from your sketches, first install the PCJoy Library. You don't have to unzip it; in the Arduino IDE, navigate to Sketch > Import Library > Add Library... and select the downloaded zip file. For detailed instructions, check out the Arduino Library tutorial.
As shown in the example sketch PCJoy_Example, the joystick is accessed using a class called PCJoy. Its constructor takes four parameters:
PCJoy(int xAnalogPin, int yAnalogPin, int aDigitalPin, int bDigitalPin);
For example, if you've configured the shield's jumpers to use X0/Y1/A6/B7, use the following declaration:
PCJoy myJoystick(A0, A1, 6, 7);
If you don't need to sense one or both buttons and would rather leave those Arduino pins free for other uses, leave the corresponding jumpers off the shield and pass 0 in place of the pin number.
In your sketch's loop(), use PCJoy's getState() function to read the joystick state. The function returns a structure called PCJoy_State which contains information about the joystick's current position. Fields defined are:
- bool isConnected: true if a joystick is connected, false otherwise. If false, other fields have no meaning.
- uint8_t xPos: X axis position, ranging from -100 (full left) to +100 (full right). 0 means horizontally centered.
- uint8_t yPos: Y axis position, ranging from -100 (full up) to +100 (full down). 0 means vertically centered.
- bool isLeft, isRight, isUp, isDown: convenience functions that classify the joystick position as up, down, left, or right. Uses hysteresis to prevent oscillations. isUp and isDown are mutually exclusive, as are isLeft and isRight. Values are always 0 if the joystick was configured without analog inputs.
- bool aDown, bDown: true if the A and B fire buttons, respectively, are depressed; false otherwise. Values are always false if the joystick was configured without the corresponding digital inputs.
Example Program
#include <PCJoy.h> PCJoy myJoy(A0, A1, 6, 7); void setup() { Serial.begin(9600); } void loop() { // Query the joystick for its state PCJoy_State joyState = myJoy.getState(); // Print the state if (joyState.isConnected) { // X position Serial.print("x="); Serial.print(joyState.xPos); Serial.print(" ("); if (joyState.isLeft) { Serial.print("left"); } else if (joyState.isRight) { Serial.print("right"); } else { Serial.print("horiz-center"); } Serial.print(")"); // Y position Serial.print(" y="); Serial.print(joyState.yPos); Serial.print(" ("); if (joyState.isUp) { Serial.print("up"); } else if (joyState.isDown) { Serial.print("down"); } else { Serial.print("vert-center"); } Serial.print(")"); // Button state Serial.print(" a="); Serial.print(joyState.aDown ? "DOWN" : " UP "); Serial.print(" b="); Serial.print(joyState.bDown ? "DOWN" : " UP "); } else { Serial.print("Joystick disconnected"); } Serial.println(); delay(200); }
Contact
For questions or support, please contact us at info at lectrobox dot com.