Close
0%
0%

A guide to custom Joysticks

An attempt to build the "ultimate" guide to building your own custom game controller

Similar projects worth following
There are a lots of good examples of game controllers/joysticks here on hackaday and even more info in the net about the components, wiring and so on. But in my experience it is pretty time consuming to get all the knowledge together to get going with your own game controller of your dreams.

I am working on my own custom stick for almost 2 years now - part time of course. Now I want to share my experiences and the knowledge I build with you.

My goal is to give some ideas and guidance to all that start building there own stick.
And maybe get some ideas back from the community or other fellow gaming device makers :)

By the way I am not a native speaker so please forgive potential miss spellings as well as bad grammar choices and strange words from times to time..

The Story

I like to play computer games and I spend quite some time with Elite Dangerous. Playing with keyboard, then with a Logitech stick and a gamepad. But for me this was not really working.

The next idea would have been HOTAS. But for me they are too expensive and the are not really doing what I imagined. So I decided to try building my own stick - knowing that this would be a long way. 

I spent 2 year of tinkering (part time of course) to get to where I am now. But it was well worth it so far. Not only because of the stick I have now. But even more because of the knowledge I build in different fields be it, soldering, wood working, electronic components, CAD, 3d print and coding the thing.

So if you are thinking about building your own - go for it! It's fun and educational :)

The vision

So what did/do I want for my "perfect" gaming controller?

Sticks
One stick is by far not enough! Make it 2 better 3. And I hate those big junky sticks you can buy - I want them small and handy. 

Buttons
Big buttons and lots of them. Not the tiny once - I have big fingers ;)

Throttle
A throttle is a must for all flight and space sims!

Immersion
I wanted some immersion. It is so much more fun to have a physical switch/toggle to lower and raise your gear. Or arm your weapons with a protected master switch.
So switches, rotary button thingys - lots of them

Display
There would obviously be a need to show the status of some components like "is the left stick analog now or is it acting as a "wasd" keyborad output. LEDs are cool but a display can show much more... So a display it is.

Nobody starts as a master

It is very important to not set the goals to high to start with. Have a vision but narrow it down to steps you can do!
My first stick looked like this

The whole purpose of it was to get a possible layout and see if I can get some components to work

When this was achieved it was time to build a more durable version and add some more components and get them to run. So I ended up building a wooden case, added a 3rd analog stick and the first switches

The wooden stick worked quite a while but the wiring and especially the placing of the breakout boards was not very well done and some contacts tended to loosen themselves. So it was time for the next level- Go for a even more sophisticated case and better wiring approach - learning form the previous 2 verions. So I decided to construct one in CAD and go for a 3d printed case

Which currently looks like this

Starting this project here on hackaday... I decided to restructure it and go into much more details in the Instructions. Not putting so much info in the logs - for a more structured approach.

So forget about the logs I did in the past - head straight over to the instructions. I will do the major work there (well at least that is what I plan to do now.


Feedback is very welcome so feel free to add your comments!

Stay tuned!

joystick_checkpoint_1.FCStd

FreeCAD file - parts can be exported as STL if you want to print. Be aware tolerance on the parts are tight. If eg the breakout board for the mini stick is a bit different it will not fit...

x-zip-compressed - 424.94 kB - 08/23/2021 at 20:33

Download

full_code_instruction_01.txt

Code for instruction 01

plain - 2.11 kB - 08/21/2021 at 22:11

Download

  • 1 × Teensy 4 https://www.pjrc.com/teensy/ -> maybe a little overkill for this project a arduino pro micro may work too
  • 2 × JH-D400B-M4 analog stick 3 axis 1 button
  • 1 × 2 axis analog stick breakout board of an arduino starter kit
  • 2 × CD74HC4067 16-Chanal Analog Digital Multiplexer Mutliplexing all the axis and buttons
  • 11 × 24mm OEM Arcade Buttons compatible Sanwa OBSF-24

View all 9 components

  • Instruction 6 started

    benkster09/20/2021 at 20:19 0 comments

    The topic of instruction 6 "Solving the PIN Problem - Programming the hardware multiplexer" is a little bit more complex to explain. So I need to split the writing of it in several parts.

    Right now the first part is done but it is not complete yet -> I will continue as soon as I find time for it!

  • Instruction 5 finished

    benkster09/14/2021 at 21:47 0 comments

    I was curios how things will work with an Arduino based board. So I spent some money on some additional components :o)
    This was also a good opportunity to create an instruction on How to setup and code a simple joystick

    Enjoy!

  • Instruction 4 finished

    benkster09/05/2021 at 14:25 0 comments

    Finished instruction 4 -> crimp dupont connectors. Hope the tips and errors I made there will help you to tune your way on how you crimp the connectors.

    If you have further tips -> feedback is always welcome

  • Channing the structure of my project

    benkster08/26/2021 at 17:17 0 comments

    I decided that the way I started this project is a bit chaotic and not very user friendly so I try to restructure things....
    Further more I plan to switch the scope of the project even further to a guide -> focusing more on instructions

    Hope you like the changes!

  • V3 is live

    benkster08/24/2021 at 21:59 0 comments

    All parts are now assembled

    The basic wiring is done

    Further more the code got its first overhaul. And is now also reflecting the new pin order.

    I added it on github for more flexibility

    https://github.com/Benksterinho/multi_axis_joystick

    I will update the instructions soon. 

    Stay tuned :)

  • The construction of the body of the stick

    benkster08/23/2021 at 20:37 0 comments

    I just added the FreeCAD file for the body of the the stick.

    Warning: This is my first real CAD design so do not expect to much finesse in it :-) 

    If its stupid but it works... 

  • 3D Printed parts and basic wiring

    benkster08/23/2021 at 18:02 0 comments

    After almost 40 hours of printing on the sidewinder. The basic body of the V3 Joystick is now ready.

    For sure it is not perfect but for my first self constructed and printed assembly - I am pretty happy with it :)
    The center part is holding the breakout/processing boards.  The heart of it is the teensy 4

    The fitting is pretty tight - so I have no idea if I ever get it our of there again...
    The mini USB connector on the left is the main connector to the PC

    If somebody has tips on how to improve the printing feel free to share them to me. I did basic calibration and extruder setting but well I suppose it can be improved. But since I will not sell it - it's good enough ,)

    I soldered a rail for all the GND and VCC connectors since the teensy only has 2x ground and 1x 3 volt pin

    The 3x4 pins on the right are the signal pins for the multiplexer channel selection. I decided to address both multiplexers in one step -> the pins are vertically connected at the backplane. So it is not possible to independently select channels on only on of the two multiplexers. The teensy will poll the multiplexers (stick axis and buttons) every 20 milliseconds so I did not see any reason to have 2 separate loops. Check the instructions for the actual code.

    Finally all is wired to the teensy:

    Pin 0,1,2,3 for the channel selection -> yellow, orange, green, blue
    Pin 14,15 as input pins -> violet, brown

    The components are:

    upper right    -> the teensy board
    upper left      -> the rail
    bottom          -> the multiplexers

    Next step will be to wire up the buttons and connect the 3 analog stick.

    So stay tuned if you are interested :o)

  • The PIN problem...

    benkster08/21/2021 at 19:59 0 comments

    A common problem for sticks with Arduinos / Teensy as controllers is the the limited number of pins.

    Since I am using the teensy board I will talk about it. As you can see on the pinout https://www.pjrc.com/teensy/pinout.html the teensy 4 has 10 analog and 14 digital pins - where the analog pins can be used as digital pins as well.

    For my current setup there are:

    - 2 x 3 axis sticks and one 2 axis stick plus an analog slide potentiometer -> 9 analog inputs

    - 10 arcade buttons and 8 switches a rotary encoder with a button -> 20 digital inputs

    By using simple arithmetic ;-) it is easy to see that this will not work by directly wiring every input to a pin on the teensy.

    There are 2 common approaches for the button problem:

    - a button matrix

    - a multiplexer

    The Matrix

    There are  tons of excellent articles about the button matrix and a matrix button pad is included in most Arduino starter kits - so I will not cover all the details. Basically it looks like this

    you wire the buttons in a matrix. In the above example the columns are used as outputs -> voltage supplied to them and the rows are inputs.

    The code steps through all the output pins (columns) and reads the values on the input pins. Some would call his this method multiplexing ;)

    As far as I know there are also libraries available for Arduino which to most of the magic for you with debounce and everything. For my 20 digital pins I could have used a 5 by 4 matrix -> 9 pins for 20 inputs is a good deal.

    Further more there is no way to multiplex analog inputs from potentiometers - although this would not have been a a problem in my use case.

    But soldering this matrix in the actual stick seemed a bit annoying  to me... ;). So I dropped this approach.

    The (hardware) multiplexer

    a good alternative for a guy with mediocre solder skills like me is a hardware multiplexer where all the wiring is happening in an IC.  The CD74HC4067 chip was the solution for me. it looks like this:

    Its a 16 channel multiplexer (C0 to C15 in the picture).  16 decimal needs 4 bits to address (S0 to S3) and one signal pin to read the current input (SIG). This means you can read 16 inputs by utilizing 5 pins on your board. The code maybe a bit harder to read but the soldering is straight forward. One pin of the arcade buttons all to ground and the other one straight to the channel of the multiplexer. Where I decided to not directly solder the cables to the multiplexer - used dupont connectors to be a bit more flexible. This looked something like this in my stage 2 model

    The red square are the 2 multiplexers ( one for buttons, one for analog sticks) and all the white cables are the button inputs.

    I will give a instruction on how the code was implemented to use the multiplexers for a joystick later on

    Hope you found this interesting :-)

View all 8 project logs

  • 1
    The basics - know your options

    In this instruction I will talk about hardware options and potential usage ideas of the components. I will not go in the exact details and scientific explanations - there is not need for it because there are tons of excellent articles about all of them in the net if you want more in depth information about them 

    The processing unit

    No matter what kind of function you want to implement, for now, a joystick, gamepad, controller will most likely be a USB Human Interface Device (HID). If you take a look at the USB specifications and how they are implemented - if you are not an absolute nerd or professional programmer - only thinking about implementing this on your own is a nightmare ;). But there are solutions out there that got you covered!

    Right now I know of 2 microcontroller options that can act as an USB HID device out of the box:

    • The Arduino Pro Micro
    • The Tennsy USB development boards

    The Arduino Pro Micro is the cheaper option but it is by far not as powerful as the Teensy 4 (more RAM, higher frequency...)  The good question now is - which to take. Planning to work with multiplexers I played it save a chose the Tennsy to be on the save side. 

     If you have experience with the Pro Micro -> please let me know about it

    Important Info: You can buy the boards with or without connectors on them. So if you do not have a soldering iron yet -> buy the preconfigured once! 

    Sticks

    A game controller without any kind of stick - well for me - is not really interesting so we want to have sticks. There are 2 kind of sticks:

    • analog sticks
    • digital sticks

    A digital stick is basically four buttons or micro switches that are triggered by some kind of physical mechanism . A good example is the direction pad on eg. the xbox controllers. Shown in this picture the switches on a salvaged xbox 360 controller

    the characteristic of a normal switch is: it is on - or off ( 0 or 1 - digital..) there is no indication "how hard" the button is pushed.
    Good thing on a custom gaming device -> you can choose in the code what kind of function ( a button press, a keyboard key, a mouse button) it will trigger. So it is pretty easy to build a digital stick on your own. 

    The analog stick on the other hand is build out of at least 2 potentiometers. A potentiometer is basically a variable resistor that will let through more or less voltage. The microcontroller will read that input on an analog pin and will show it as a integer value between 0 and 1023.  For example: If the joystick is in the middle / idle position - x and y axis both show a value round about 512. It might be of by 50 or something, that is not unusual -> that's what analog stick calibration is for :) If you push x axis to the left - value will decrease and reach 0 at the end - moving right it will increase up to 1023

    Very important: most potentiometers used in analog sticks work on a linear scale, meaning the value will steadily increase or decrease along the axis. The other type is logarithmic, meaning that the change of value differs along the axis. Something like this:

    Try to go for linear ones for your project!
    There are ways to transform logarithmic outputs to linear via code or wiring but this is making things very complicated. I had the bad luck that the 3 axis sticks I bought been linear on the x and y axis but logarithmic on the z rotate axis :(

    That said be also be aware that it is no problem at all to make an analog stick behave like a digital one in your code...

    So my recommendation is go for analog sticks only!

    But there is another very important limiting factor. Its not like you can add stick after stick and use them as analog axes and get away with it without problems. Windows ( I think it is actually DirectX but not sure about it) can only handle 6 axis

    X, Y, Z, Z rotate, Slider left, Slider right 

    So if you plan to use 3 sticks like I do at the moment, it is not possible to use all of them as analog axes. The little stick I use is either used to act as "wasd" input or arrow keys -digital if you like ...

    Potential Use cases for sticks:

    • Have one stick as your classic joystick -> x,y axes and maybe z rotate -> eg. to fly your plane or spaceship
    • Use the second stick to move your head in game or for directional thrusters. Elite dangerous has a normal and alternative flight setting so you can have both options - as needed
    • program one stick to act as a digital input -> eg simulate arrow buttons. It' s pretty cool to use the little stick under the thumb to navigate in game menus ,)

    Buttons

    Well Buttons are buttons and that's it for me and by that I mean Joystick buttons. Some of the sticks you can buy have a button included in the sticks as well.
    For me bigger buttons are better. But that depends on your taste. There are buttons with LEDs to illuminate the button when you push them and much more. So pick you poison there.

    Most if not all buttons are digital. If you wonder how the analog shoulder buttons on the xbox controllers work. That's done with a pretty nice concept.

    It is actually a rotary potentiometer (red brackets) attached to a nice mechanic that will rotate the pot when pressing down the button. 
    If you use your imagination and scale this concept up - bam there is your option for the paddles of your next driving stick project ;)

    Toggles/switches

    The main difference between a switch and a button is that a switch will stay in the position while a button will automatically jump back once you release it.
    Most common are On/Off switches but there are also On-On switches. I bought On-On they look like this

    On-Off switches have "2 legs" while the On-On has "3 legs". I use mine as On-Off switches by just connecting 2 off the 3 legs because the number of pins used becomes an issue very quickly. More on this in anther instructions

    The use for the switches are for me two main concepts:

    • Use them as a keyboard key press -> logically it is like a "one state change - press and release a key (the same key usually)"
      It is also possible to code it the way to act on status change -> key goes from on to off -> "M" key press and release. On to off -> "ESC" key pressed and released
      eg. enter a map and leave it...
    • As the physical representation of an IF Statement -> "If the switch is on - the little stick acts as arrow keys - else the stick acts as 'wasd' keys"

    Sliders

    Sliders are just another type of potentiometer. For the microcontroller - they work exactly the same as described in the stick.  From joystick perspective it is usually used as the Z axis or left/right slider
    I think they are best known from those huge mix tables in music studios

    But be careful, as far as I read, especially in these studio equipment - logarithmic pots seem to be preferred! 
    For a gaming device go for linear ones!

    Rotary knobs

    Those thingys

    The question you need to ask yourself on this is: 

    • Is the position of the knob meaning something -> like turn up the volume or throttle up and down
      Then this knob will have a limit amount of turns or even only some degrees angle from low to high
      => go for a rotary potentiometer -> but keep in mind analog input requires an axis which are limited in the joystick implementation in Windows!
    •  It is important to know in which direction the knob is turned -> like choose the next or the previous target in your space sim
      The knob can be turned unlimited...
      => go for a rotary encoder -> they send a digital signal so you can eg. do a key press/release when turned left/right and so on

    Rotary encoders often have a button included engaged when you press the knob. Tons of information about them in the net if you want to know how they work internally.  

    But one thing is worth to mention: They come in 2 flavors if you buy them!

    The plane rotary encoders need a support wiring with capacitors and resistors if you want to do it by the books (maybe it works without - did not try it) You end up soldering something like this... ;)


    In the spirit of: Why buy something cheap if you can build it for 2 times the money on your own *lol*

    I recommend to go with breakout boards for the encoders. They are cheap and you are on the save site with them. 
    If you want to learn something and improve your solder skills - go for the plane ones

    Displays

    Lots of options here as well. OLED ones with color - without color. Lots of sizes. But this all is not worth anything if your micro controller cannot get it working :(
    Especially the Teensy is very picky on this topic. Two main reasons:

    • Voltage for operations
    • Availability of libraries

    First thing is pretty obvious. The teensy operates only on 3 V while some controllers support only 5V or both. No clue what the Arduino Pro Micro supports
    So if you choose your display - pay attention to the voltage they can operate on. 

    The other  thing is a bit more complex. While the teensy is arduino compatible with the teensyduino addon for the Arduino IDE - some libraries are not!
    The only display controller that worked out of the box for me on the teensy is the SSD1306 with the Adafruit SSD1306 and GFX libs...
    So pay attention to the display specs here as well!

    Finally connection options of the display. (O)LED Displays need a huge amount of pins if you wire them natively! So go for a breakout board with a dedicated controller here as well! I used a I2C based one but I guess SPI would work as well

    Feel free to add your comments on this topic. I will gladly add additional info to this instruction if it is useful!

  • 2
    The PIN problem

    Now that you have selected your components. The info in this instruction is essential before you can start to wire up things!

    A common problem for sticks with Arduinos / Teensy as controllers is the the limited number of pins the breakout boards have.

    Since I am using the teensy board I will talk about this one only.
    As you can see on the pinout https://www.pjrc.com/teensy/pinout.html the teensy 4 has 10 analog and 14 digital pins - where the analog pins can be used as digital pins as well.

    For my current setup there are:

    • 2 x 3 axis sticks and one 2 axis stick plus an analog slide potentiometer -> 9 analog inputs
    • 11 arcade buttons, 3 buttons overall on the sticks,  8 switches a rotary encoder with a button -> 23 digital pins 

    By using simple arithmetic ;-) it is easy to see that this will not work by directly wiring every input to a pin on the teensy.

    So if you do not use this many components forget about the rest of the instruction. Wire them straight to your board - no problem

    Else - there are 2 common approaches for the button problem:

    •  a button matrix
    •  a multiplexer

    The Matrix

    There are  tons of excellent articles about the button matrix and a matrix button pad is included in most Arduino starter kits - so I will not cover all the details. Basically it looks like this

    you wire the buttons in a matrix. In the above example the columns are used as outputs -> voltage supplied to them and the rows are inputs.
    The code steps through all the output pins (columns) and reads the values on the input pins. Some would call his this method multiplexing ;)

    As far as I know there are also libraries available for Arduino which to most of the magic for you with debounce and everything. For my 23 digital pins I could have used a 5 by 5 matrix -> 10 pins for 23 inputs is not to bad of a deal.

    But soldering this matrix in the actual stick seemed a bit annoying  to me... ;). So I dropped this approach.

    Further more there is no way to multiplex analog inputs from potentiometers - although this would not have been a a problem in my use case.

    The (hardware) multiplexer

    a good alternative for a guy with mediocre solder skills like me is a hardware multiplexer where all the wiring is happening in an IC/breakout board.  The CD74HC4067 chip was the solution for me. it looks like this:

    Its a 16 channel multiplexer (C0 to C15 in the picture).  16 decimal needs 4 bits to address (S0 to S3) and one signal pin to read the current input (SIG). This means you can read 16 inputs by utilizing 5 pins on your board.
    The code maybe a bit harder to read but the soldering is straight forward. One pin of the arcade buttons all to ground and the other one straight to the channel of the multiplexer. Where I decided to not directly solder the cables to the multiplexer - used dupont connectors to be a bit more flexible. This looked something like this in my stage 2 model

    The red square are the 2 multiplexers ( one for buttons, one for analog sticks) and all the white cables are the button inputs.

    Summary

    Do not forget to consider the "Pin Problem" in your planning.
    Choose your preferred option and plan your wiring accordingly

    As always - feedback and comments are welcome 

  • 3
    Prototype wiring - Part 1: Flying wires

    After choosing your components and thinking about the "PIN Problem" it is time to take the next step forward -> build a prototype.

    Before we start: Most of the time I do not do a scientific approach. I more do an empiric approach. 

    • Build
    • Test and/or fail
    • rethink 
    • improve
    • repeat

    This means, most of the time I am not using any wiring plans at all and I tend to be very "pragmatic" - not to say sloppy - when setting up test setups.
    I know of tools like fritzing and similar but that's not my thing, so for now - I will not provide any fancy wiring plans. 

    But of course if you more like the scientific approach you should plan out your wiring with some software or on a piece of paper first... That said - lets start 

    I would not recommend to start with all the components together. It is better to start component by component and extend your functionality step by step. This way you will not loose the overview (that fast ;) ) and troubleshooting is much easier on a small setup. 

    Some small steps to go for test wirings may be:

    • Get your first analog stick working as a joystick
    • add some buttons to the setup
    • add the sliding pot
    • add some switches

    For the (O)Led display I would recommend a separate test setup.

    The way your first prototype may look like depends much on the equipment you have on your disposal besides your game devices components. There are some absolute essential in my humble opinion. Out of the box ( :-) ) these are:

    If you own an Arduino already - 2 of them should be pretty familiar 

    • breadboard (in the middle)
    • preconfigured cables with different dupont connectors (on the right)

    Those 2 are included in pretty much every starter kit. Not that common there are the "Crocodile Clamp" cables (on the left).
    Well at least, that is what I call them. If there is another name in english for them -> let me know. 

    The reason why they are so important is - a lot of the components will not come with any cables at all. Like arcade button, the big sticks and switches. Most of the time they are prepared to solder cables directly to them - with those little "legs"

    For a prototype - I at least - do not want to solder anything. Maybe you do not have a soldering iron at all, for now. So the crocodile clamps are a good workaround. If you combine them with the female-female dupont cables you are all set!

    So a real life setup to test the dual sticks looked like this:

    But be warned if you want to wire a complete prototype like this - things might get a bit messy ;)

    Seems a bit stupid - but if it's stupid and it works... :o)

    Of course all the wiring is not worth much if there is no code to support it. I will add Coding instructions later on. But if you want to start testing immediately checkout this tutorial for the teensy it has all info you need for a basic stick: https://www.pjrc.com/teensy/td_joystick.html

    Next instruction will be on how to build a more durable, but still flexible wiring  

View all 6 instructions

Enjoy this project?

Share

Discussions

Fred wrote 09/27/2021 at 08:55 point

Thanks for sharing these informations!

I developped a board to control a 3 axis analog joystick through I²C, which may interest you:

https://framagit.org/fma38/joystick_node

https://wiki.logre.eu/index.php/Joystick_Node

  Are you sure? yes | no

PixJuan wrote 09/04/2021 at 20:44 point

I used a Teensy4 for my crank controller, but I agree it's overpowerful for the task. I needed both a USB host port, to plug a mouse, and a usb client port, to act as a HID, so in my case it was the perfect fit.

The board pointed by Eric looks nice, a cheaper alternative would be using a 2$ STM32 "blue pill board, it seems to support USB-HID since some guy did a rubber-ducky like device with it

https://github.com/satoshinm/pill_duck

  Are you sure? yes | no

benkster wrote 09/05/2021 at 14:53 point

thanks for the input PixJuan. I will take a look at it. I am not sure if all HID boards can act as a joystick… The description of some only mentioned Mouse and Keyboard not joystick. After all it seems we have to try some of the boards ;)

  Are you sure? yes | no

eric wrote 09/01/2021 at 22:26 point

Hey there! You mention only knowing of 2 boards that work as HID devices, but if you look at Adafruit's stock - almost all their boards (or at least a large portion of them) can work as HID devices. So one of them *might* suit your needs better.

  Are you sure? yes | no

benkster wrote 09/02/2021 at 17:12 point

Hey Eric! Thanks for the tip. I will definately take a look at it. I plan to build a small simple stick in the near future and will go for an arduino then. Any recommendation from your end?

The teensy is pretty overkill for a stick I guess and relative expensive as well

  Are you sure? yes | no

eric wrote 09/02/2021 at 22:11 point

This one's really good and only $7.50 USD. https://www.adafruit.com/product/4600

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates