Saturday, November 12, 2011

Analog Joystick with Arduino!

I have a old Gravis Blackhawk joystick that i dug up to use with my Arduino. I opened up the back, and it doesn't have any electronics, just a circuit board splitting out the DB15 connector to all the buttons etc(no ICs etc). It has 3 buttons on the stick, a throttle pot and another button on the base, and of course the X + Y axis slider pots for the stick. All the buttons are each wired to a pin of the DB15 connector and the other side goes to GND. The X + Y axis and the slider are connected to +5v, GND and a pin for each on the DB15.

The Arduino programming was really simple. All i had to do was read 3 analog ports for the X,Y and throttle pots, and 4 Digital pins for the buttons. Then I put them all into a string like: "X,Y,SpeedPot,btn1,btn2,btn3,btn4" and printed to serial. Also, this Arduinio code uses millis() rather than delay to be more precise in delays. 

I finally made the C# interface app, but never posted it, so you can find it HERE as a zip*
*note: the file is .zip but I renamed it to '.zipp' to get around Google's file protection. Download it, then remove a 'p' from the end of the file name and extract! Below in comments, let me know if you have any issues.

Picture and Scheme of joystick:

#define Xaxis 3  //Joystick X axis Analog pin 3
#define Yaxis 4  //Joystick Y axis Analog pin 4
#define SpeedPot 5  //Pot in base for speed, Analog pin 5

int XaxisVar = 0;  //...analog pin 3---X axis
int YaxisVar = 0;  //...analog pin 4---Y axis
int SpeedVar = 0;  //...analog pin 5---Speed pot

#define TrigBtn 2  //trigger button, digital 2
#define MidBtn 6  //Button below trigger on joystick, digital 3
#define LowBtn 4  //Lowest button on the joystick, digital 4
#define BaseBtn 5  //button on base of joystick, digital 5

int TrigBtnState = 0;  //Stores the state of TrigBtn
int MidBtnState = 0;  //...MidBtnState
int LowBtnState = 0;  //...LowBtnState
int BaseBtnState = 0;  //...BaseBtnState
int HypDelayTime = 100;  //time you want the code to loop at. will be used to figure actual delay time(see end of code).

void setup()

  for (int pin=2; pin<=6; ++pin)  //sets all digital pin 2-5 as input and enables internal pullups.
    pinMode(pin, INPUT);  //sets button pins to input
    digitalWrite(pin, HIGH);  // sets the pull up.

void loop()
  int TimeInt = millis();  //record time at begining of main loop

  XaxisVar = analogRead(Xaxis);  //Read X-Axis postion
  YaxisVar = analogRead(Yaxis);  //Read Y-Axis postion
  SpeedVar = analogRead(SpeedPot);  //Read Speed Pot postion

  TrigBtnState = digitalRead(TrigBtn);  //read status of buttons on joystick
  MidBtnState = digitalRead(MidBtn);  //...
  LowBtnState = digitalRead(LowBtn);  //...
  BaseBtnState = digitalRead(BaseBtn);  //...

  //Just serial ouput formatting...
  String Comma = String(",");
  String Data = String(XaxisVar + Comma + YaxisVar + Comma + SpeedVar + TrigBtnState + Comma + MidBtnState + Comma + LowBtnState + Comma + BaseBtnState);

  int TimeEnd = millis();  //record time at the end of main loop

  //the DelayTime is the time so that the code actually repeats at 1000ms.
  //"Time we actualy want to delay"="EndOfCodeTime"-"BeginingOfCodeTime"="time taken for code to execute"-"hypothetical delay"(what we wanted to delay(1000ms))
  int DelayTime = HypDelayTime - (TimeEnd-TimeInt);
  //Serial.println(DelayTime); //prints delay time. is about ~980ms, so we can tell that all the signal reading and formating takes 20ms.


  1. another implementation with support digital gamepads

  2. Can i use the joystick for flight simulator?

    1. youd have to get some sort of program to create a virtual joystick with the values from the arduino.

  3. Thanks for this wonderful information on Joystick controllers. I found it very informative for gamers like me. Well, if someone is looking to buy a new PC controller for hardcore gaming then it is recommended to check this list of PC game controllers. I bet you will surely find the best one for your needs on this link.