Introduction: Add a Little Two Analog Axis Thumb Joystick to Your Existing Joystick.

Picture of Add a Little Two Analog Axis Thumb Joystick to Your Existing Joystick.

After I bought a Thrustmaster Flight Hotas Stick X for Elite Dangerous, I wanted two additional analog axes for lateral/vertical thrust.

After some googling, I stumbled over this nice blog entry: Turning an Arduino Leonardo into a joystick and after reading it, I knew what to do :)

The ATmega32U4 on that board has a USB core build into it, which makes building various USB HID devices very easy.

You only need some basic soldering skills to perform this Instructable, no deeper electronics knowledge is assumed!

This mod gives you a standalone analog joystick with just two axes.

It's so small, you can mount it to a bigger joystick.

I used scotch double sided mounting tape which works really well, to stick it to the throttle stick on my hotas.

Step 1: Hardware

Picture of Hardware
  1. Sparkfun Pro Micro (or some other board with an ATmega32U4, check eBay).
  2. Thumb slide joystick (search eBay for "PSP 1000 Joystick").
    Sparkfun also has them:
  3. 4 pieces of wire and a soldering iron.

Just solder the 4 pads of the joystick to GND/VCC/A2/A3 pins of your Pro Micro (see image with pin assignments).

Use double sided mounting tape or Sugru to mount the stick to your joystick.

Step 2: Software

Picture of Software

Arduino (tested with v1.0.5).

Download and unzip it into your arduino/hardware folder.

This adds some new items to Tools->Board (follow the sparkfun hookup guide if you have problems).

Make backups of your original HID.cpp and USBAPI.h files inside your arduino/hardware/arduino/cores/arduino folder and replace them with the two files from this Instructable. (Move the backup files out of the original folder or Arduino will complain if they have .cpp or .h as the extension!).

In the file HID.cpp are three lines starting at line 27.

// #define KBAM_ENABLED

In my version of the file, #define THUMBSTICK_ENABLED is uncommented which is fine for our two axis joystick.

If you later want to use one of the other settings for a project, just uncomment the line you need (only one at a time!).

Download thumbstick.ino and open it with the Arduino IDE set the board to SparkFun Pro Micro 5V/16MHz and upload the sketch.

Depending on the orientation of the joystick you might have to swap the second and third parameters to the map() functions from "400, -400" to "-400, 400", this inverts the axes.

Now Windows should have a new entry named "USB IO Board" under game controllers.

Elite Dangerous supports multiple joysticks at once but if you want to use it with a game that only supports one joystick, you can bind different joysticks together into a virtual one with UJR and vJoy.

Step 3: Conclusion

The Pro Micro is a really cool little device that makes it super easy to build your own joystick, mouse or keyboard device.

If you want more axes or additional buttons have a look at the example at Turning an Arduino Leonardo into a joystick this gives you a 6 axis, 32 button, 2 hat switch - monster :)


Yuuseki made it! (author)2017-09-29

This guide is a little outdated sadly, because the Arduino software changed.
The provided thumbstick.ino script code doesn't work out of the box any longer.
What I had to do was
1) open the sparkfun hookup guide
2) follow instructions to install drivers and Arduino addon from there
3) follow ThanitK's link to MatthewH's guide and install the Joystick library from there
4) under Tools -> Board, select the "SparkFun Pro Micro" board from the previously installed Arduino addon from the hookup guide
5) include the Joystick library (I went with "Joystick")
Then I went ahead and fiddled with the code in the Sketch file, this is the result, all working on my end:
short video of it in action (pay attention to the monitor in the background, my character is moving as I press the joystick):

Yuuseki (author)2017-09-28

Updated Hookup Guide link:

Make sure to install the drivers from there.
I also used the Arduino addon from the hookup guide, not the one in this instructable (the one you unzip to arduino/hardware).
So instead of selecting the "Sparkfun Pro Micro 5V/16MHZ" board, I picked "Sparkfun Pro Micro".
My own Sketch is basically the provided thumbstick.ino, but modified thanks to ThanitK's comment.

I included the "Joystick" library from in my Sketch, called "Joystick.begin()" in setup() and in the loop function, where the original Sketch calls "Thumbstick.setState(&thumbSt)", I call "Joystick.setXAxis()" and "Joystick.setYAxis()"

ThanitK made it! (author)2017-07-30

jump there to say Thanks for this Idea :D

I 'm success to made a mini joystick but in little bit difference in process.

1. I use Arduion 1.8.3

2. I use Arduion library for Game Controller/Joystick from form MatthewH

3 then I modify thumbstick.ino to call library (2)

//Program this use
//1. Keyes Thumb Joystick Module for Arduino
//2. Sparkfun Pro Micro ATmega32U4 5V/16MHZ
//3. Arduino 1.8.3 with Sparkfun Pro Micro driver
//Thanit Kebsiri
//Thank you to
//1) Matthew Heironimus from
//2) metanurb from
#include "Joystick.h"
0, 0, // Button Count, Hat Switch Count
true, true, false, // X and Y, but no Z Axis
false, false, false, // No Rx, Ry, or Rz
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering
const bool DEBUG = false; // set to true to debug the raw values
//--- make sure you point to the right pin :)
int xPin = A1;
int yPin = A2;
int xZero, yZero;
int xValue, yValue;
int xTrans, yTrans;
int xCur, yCur;
int xMaxRange , xMinRange;
int yMaxRange, yMinRange;
int deadzone = 5; // smaller values will be set to 0
void setup(){
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
if(DEBUG) {
// seting max min range for send to joystick
// because my joystick not point to center
// you will data from debug
// from my joystick
//xRage 610/2 -> 305
//yRange 680/2 -> 340
xMaxRange = 257;
xMinRange = -257;
yMaxRange = 257;
yMinRange = -257;
// calculate neutral position
xZero = analogRead(xPin);
yZero = analogRead(yPin);
//-- need logial joystick point to center ( 0 - 1024)
xTrans = 511 - xZero;
yTrans = 511 - yZero;
// Initialize Joystick Library
Joystick.setXAxisRange(xMaxRange, xMinRange);
Joystick.setYAxisRange(yMinRange, yMaxRange);
void loop(){
// read instance joystick positon
xCur = analogRead(xPin);
yCur = analogRead(yPin);
// trick it
xValue = xCur + xTrans - 511;
yValue = yCur + yTrans - 511;
// dead zone blocking
if(abs(xValue) < deadzone) {
xValue = 0;
if(abs(yValue) < deadzone) {
yValue = 0;
if(DEBUG) {
this is for checking my joystick
//-- joystick positon : Center , Max , Min : Range ->Range Use
//-- xCur 508 , 863 , 251 : 612 ->610
//-- yCur 482 , 799 , 110 : 689 ->680
//-- so my range x -257 0 +355 --> set range 257
// x -371 0 +317 --> set range 371
Serial.print("xCurrent: ");
Serial.print(" yCurrent: ");
Serial.print(" <> xZero: ");
Serial.print(" yZero: ");
Serial.print(" <> X: ");
Serial.print(" Y: ");
//-- if value jump out of maxrange setting
if ( xValue > xMaxRange )
xValue = xMaxRange;
if ( xValue < xMinRange )
xValue = xMinRange;
if ( yValue > yMaxRange )
yValue = yMaxRange;
if ( yValue < yMinRange )
yValue = yMinRange;
//-- Send to USB

ThanitK (author)ThanitK2017-07-30

the code is look mess but it work! :D

SverreV made it! (author)2017-03-20

Wow! This works great.

I think I'll add some more buttons to this magnificent stick too :)

alexkyriak (author)2016-11-27

Looks really interesting, have ordered parts to try this myself.

Question: Is it possible to add two thumbsticks onto one Pro Micro board? I see additional A0 and A1 inputs on the diagram. Thanks!

AleksejV made it! (author)2016-09-28

Looks stupid but works like a charm!
i just removed the mouse nipple completly (didnt realy work anyway) and replaced it with an psp joystick.

Thx a ton for the tutorial!

the100thmonkey made it! (author)2016-05-29

All sorted!

the100thmonkey (author)2016-05-24

Thank you for the tutorial - it's inspired me to try this out.

I read that this won't work on the 1.6.9 IDE. Would anyone be able to point me in the direction of a tutorial that works on that version, or point out the changes necessary to get it working? I'd like to learn from looking at a working example and build up my knowledge from there.

Thanks again.

Well, I got it working by switching to 1.0.5-r2. :)

Now I just need to calibrate it properly - I'm getting the looping that other commenters have reported.

RadekJ3 (author)2016-05-05

All works fine! Though this puzzles me, Everytime I restart my computer I need to upload the sketch again. (and then calibrate) Is that just the way these things go? Or is it some win 10 thing?

eitand made it! (author)2016-03-28

Made It!
So cool, now i have some spare buttons i can use.

DaveC88 (author)2015-12-18

I see you are using connectors for the wires, can you advise me on what connectors to use, or if there are headers for this board?

ElliottZ (author)DaveC882015-12-20

Hi Dave, I just soldered wires directly to the arduino micro, after thorough testing of course. For more temporary connectors, these work well: ( )

DaveC88 (author)2015-12-14

I am a little confused, what is the best USB power supply for that the Sparkfun Pro Micro?

adamx38243 (author)2015-08-06

Same error as Sponge...

C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h:31:2: error: 'ring_buffer' does not name a type
ring_buffer *_cdc_rx_buffer;

Currently running 1.6.5

leviwilner (author)adamx382432015-11-19

It wont work running higher versions of the IDE.

leviwilner (author)2015-11-19

Hi, I got it to work with Arduino IDE 1.0.5. But, The joystick is looping. For example: if I push up on the thumbstick the + will move upward. As I continue to move the thumbstick up to it's full extent, the + loops to the bottom, so now I'm going 'down' while the stick is pointing up.

I have the same problem with the Y axis. I have a feeling that the problem is in the .ino file, but I can't be sure. Any help would be appreciated... Thanks :)

Vindicore made it! (author)2015-07-09

Made it!

Also found that there was spare joining cable inside the throttle which I tugged out, so the HOTAS X now fits around my keyboard!

Thinking about routing the wire through the throttle but may think about putting on some extra buttons first, if I can think of any use for them!

IgorT4 (author)2015-04-09

Will the code work with a plain arduino micro?

IgorT4 (author)IgorT42015-04-10

All right, got myself a clone called leonardo pro micro, it's seen as an arduino leonardo. Wouldn't upload unless you install arduino leonardo drivers and select the board as an arduino leonardo. Other than that, works like a charm.

Vindicore (author)IgorT42015-07-07

Where did you find the Leonardo drivers?

IgorT4 (author)Vindicore2015-07-07

In the arduino software folder, in the driverspark subfolder.

Vindicore (author)IgorT42015-07-07

I have no driverspark subfolder? Did you use the latest Arduino software or the old version linked here?

IgorT4 (author)Vindicore2015-07-08

The old version, alternatively you can do a manual install through the device manager and let windows rummage through the files by itself.

Vindicore (author)IgorT42015-07-08

Got it working, thanks for the help! I'll post pictures tomorrow once I find some double sided tape to stick it on.

Vindicore (author)IgorT42015-07-08

Manual install isn't working - I somehow have the device recognised as a Arduino Micro and if I try to install drivers for the Leonardo it fails every time. No idea how I can stop the PC recognising it as the wrong device.

IgorT4 (author)IgorT42015-04-10

Here you go

Vindicore (author)2015-07-07

Having this problem:

Found programmer: Id = "B»"; type =

Software Version = . ; Hardware Version = .

avrdude: error: buffered memory access not supported. Maybe it isn't

a butterfly/AVR109 but a AVR910 device?

I have this Pro Micro:

Vindicore (author)Vindicore2015-07-07

Also I still have a yellow warning in Device manager and the device is called 'Ardiuno Micro', is this right?

Vindicore (author)Vindicore2015-07-07

And I have a steady green and red LED along with one regularly flashing red one?

BeatnBreak. (author)2015-06-24

Great tutorial!

What should the code look like, if I want to have two analog thumbsticks? :)

sponge11790 (author)2015-04-21

I'm getting a compile error....

C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h:31:2: error: 'ring_buffer' does not name a type
ring_buffer *_cdc_rx_buffer;

Can someone help me with this? I'm still in the learning process obviously.

JasonW16 (author)sponge117902015-05-11

I'm getting the same error; did you manage to resolve this?


In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:224:0,

from thumbstick.ino:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h:31:2: error: 'ring_buffer' does not name a type

ring_buffer *_cdc_rx_buffer;


Error compiling.

NathanB15 (author)JasonW162015-06-09

Same error i had. If you use the Arduino software v1.0.5 it will work.

OuTLaW66613 (author)2015-03-31

Ok all rewired and it's totally solid for the most part. The Y axis is
now off a little though. When I push up on the stick it doesn't go
completely to the top and when I push down it cuts of the bottom and
registers up top. Anyone else run into this issue?

NathanB15 (author)OuTLaW666132015-06-09

Yep, same problem here. Did you fix it at all?

IgorT4 (author)2015-04-07

Man i'm really bad at soldering, took me 30 mins to get wires to stick to the psp stick...

OuTLaW66613 (author)2015-03-30

So I got it all wired up and running but I ran into a little more trouble. When I go into the controller settings the axises are going a little nuts. There just not stable, I'm heading to the electronics store here in like an hour to get some more desoldering wick. I had soldered on some headers on thinking the connection would be fairly solid but I think that's where my problem is. Going to resolder and report back.

OuTLaW66613 (author)2015-03-24

So, I'm having some issues getting everything to compile, but from grimngor's post I think I found the issue. I had a feeling the Arduino IDE was too up to date. I'll do some digging around and see if I can't find 1.0.5 and post back.
Hey grimngor you don't happen to have any pics of the inner workings do you? I'd love to see that!

grimngor made it! (author)2015-03-22

Well Guys it was tough but I made it! I managed to tune the hotas to place the arduino and all wiring internally. In the software side of things I had difficulties with versioning. I wa downloading the correct 1.0.5 Arduino software, but I was getting problems because of the sparkfun tools being downloades for a newer version of Arduino. So In case you have problems, be sure to download the proper one:

Thanks for all your comments, they were so helpful!

elfyn (author)2015-02-10

Like the guide.

But its taken me a long time to get to the stage im at now, was running Arduino: 1.0.6 just like waigong.lee was. When i realised what the problem, i managed to upload the sketch.

But i still cant get it to work. The board dose not come up as a game contraller, so i cant use Vjoy to configure, as it dose not detect it, but comes up as "SparkFun Pro Micro 5V/16MHz" under Comm ports on device manager. Is this a driver issue, ive installed the Sparkfun drivers, and then selected them from the list of drives under Sparkfuns when installing the drivers for the device, is this the corect way.

ReaperAlex (author)elfyn2015-02-18

do a sanity check against those instructions. also mine shows as "HID Keyboard" in devices and printers, but if i open the game controller screen from my main joystick then i can see my pro micro as "USB IO Board". i've not tried vjoy as elite: dangerous lets you use more than 1 stick, so i didn't have to merge them. but just checking windows can see it in the game controller screen is the first thing to get working.

ReaperAlex made it! (author)2015-02-09

seeing as i never liked the rocker axis on the throttle i decided to mount the thumbstick where the rocker was. taking the throttle to bits was nice and easy, you don't need to unscrew the base. the rocker then slots out when you unscrew the mounting bracket and potentiometer.

the good news is the spring is attached to the pot, not the plastic lever, so it will stay centred and not mess with key bindings. the bad news is the gap it leaves is huge. i plugged it with a piece of cardboard cut to shape and more cardboard strips to press it into place with the mounting bracket. to get the curve without using glue i made a wedge shaped bit of cardboard.

this gave me a nice solid feeling platform to build off. i mounted the thumbstick on the far side, it's almost flush thanks to the shape of the throttle there. i used black sugru to keep the thumbstick in place and to fill in the remaining gap. you need to be careful not to go over the top of the thumbstick as the whole surface is needed for movement. one regular sachet was enough for what you see in the pic. i've not mounted the pro micro yet as i intend to add some more buttons on when i have some more time for hacking.

great instructable, this has been my first use of an adruino, a soldering iron in about 15 years, my first hack to some hardware i own and my first use of sugru. all in all i'm very pleased how things have gone. so thanks for the guidance and inspiration!

JarosławB1 (author)2015-01-31

I used the 'replacement' psp joystick but they are crap. I recommend using original psp joystick.

waigong.lee (author)2015-01-20

Hi, I get this error when trying to upload the sketch:

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows NT (unknown)), Board: "Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328"
thumbstick:1: error: 'ThumbState_t' does not name a type
thumbstick.ino: In function 'void setup()':
thumbstick:23: error: 'thumbSt' was not declared in this scope
thumbstick.ino: In function 'void loop()':
thumbstick:38: error: 'thumbSt' was not declared in this scope
thumbstick:49: error: 'Thumbstick' was not declared in this scope

Can you help please?

waigong.lee (author)waigong.lee2015-01-20

Sorry, I've got past that problem (I hadn't installed the sparkfun drivers) but now get this when attempting to upload the sketch:

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows NT (unknown)), Board: "SparkFun Pro Micro 5V/16MHz"
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:117: error: prototype for 'void Serial_::begin(long unsigned int)' does not match any in class 'Serial_'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\/USBAPI.h:33: error: candidate is: void Serial_::begin(uint16_t)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:122: error: prototype for 'void Serial_::begin(long unsigned int, byte)' does not match any in class 'Serial_'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\/USBAPI.h:33: error: candidate is: void Serial_::begin(uint16_t)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp: In member function 'virtual int Serial_::available()':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:133: error: 'peek_buffer' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp: In member function 'virtual int Serial_::peek()':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:141: error: 'peek_buffer' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:143: error: 'peek_buffer' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp: In member function 'virtual int Serial_::read()':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:148: error: 'peek_buffer' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp: In member function 'virtual size_t Serial_::write(uint8_t)':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:163: error: no matching function for call to 'Serial_::write(uint8_t*, int)'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:161: note: candidates are: virtual size_t Serial_::write(uint8_t)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp: At global scope:
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:166: error: prototype for 'size_t Serial_::write(const uint8_t*, size_t)' does not match any in class 'Serial_'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\CDC.cpp:161: error: candidate is: virtual size_t Serial_::write(uint8_t)

metanurb (author)waigong.lee2015-01-20

I'm not sure what changed from 1.0.5 to 1.0.6, can you try it with the 1.0.5 version?

waigong.lee (author)metanurb2015-01-20

Thanks, got it working.

waigong.lee (author)waigong.lee2015-01-26

Quick question. Now it has been set up will it just plug and play on any computer or will I have to install the Arduino software (not just drivers) to run it?

About This Instructable




More by metanurb:Add a little two analog axis thumb joystick to your existing joystick.Androino! Control an Arduino from your Android device using a cheap bluetooth module.
Add instructable to: