Introduction: USB Keyboard Joystick

About: Educator, entrepreneur, photogeek.

It's simple to make custom USB keyboard and mouse controllers.

I use a few keyboard shortcuts when rating pictures in Adobe Lightroom, and found that I can be even faster using a simple game controller joystick. I mocked it up on a breadboard with two components I already had in my workshop and found that it worked great, but it needed a nicer "cabinet" for it to live on my desk.

Because it is Arduino based, customizing the joystick functions and add additional buttons, dials, or other controls is easy.

There are three sections to this project:

  • Hardware
  • Software
  • Desk-worthy case to hold said hardware


Step 1: Hardware


I wanted to use a small Arduino board to keep this build as compact as possible. I have a few Pro Trinkets but they don't work well for keyboard and mouse simulation because USB isn't fully implemented on the Trinkets. For this project I used a 5V 16MHz Itsy Bitsy from Adafruit that can use standard HID libraries to be a keyboard and mouse over USB.


This is the type of joystick that is used in game controllers. They are two axis and have a switch that is temporary on when the stick is pushed in. They are easy to find online. If you want to buy just one they can be anywhere from $4 to $10, but can be bought in bulk 10 packs on Amazon for about $11.

Note, the similar joysticks from Adafruit and Sparkfun have different pinouts than all the other ones you may find online. Pay attention to that when you hook it up.

On the Arduino, this projects uses A0 for the switch, A1 for the X axis and A2 for the Y axis. This leaves 19 other input pins for you to get creative with.

The joystick 5v comes from the 5v USB power (labeled as such on the Itsy Bitsy). And it has a ground - connect it to the Arduino ground.

Step 2: Software

The Arduino code is very straightforward. I've programmed it specifically for a few Lightroom keyboard shortcuts I use for rating pictures. Pushing the switch toggles between Loupe ("e") and Grid ("g") view. Moving the joystick left and right goes to the previous (left arrow) or next (right arrow) picture. Pushing the stick up adds a star to the rating ("["), and pushing it down removes the flag ("u"). (Trust me, this makes sense to the way I rate my images.) You can change the code to do whatever you want.

The main loop first reads the switch state. If it changed from HIGH to LOW it toggles and types either 'e' or 'g' to switch between Loupe and Grid view.

Next, the program maps the analog values of the joystick (0 to 1024) to a different range (-5 to +5). The code recognizes +/- values of 5 as actions for sending characters, so you have to move the joystick near the end of its range to send a keyboard shortcut. They joystick then has to pass through 0 before it will send another keystroke. The code to do this is quite short and I think pretty elegant. The net effect is that you have to be intentional about your motions and it won't accidentally send out a stream of the same keystroke (which my first version of the code did!).

You can use the mouse library and the analog values from the joystick to control your cursor, scrollwheels, volume controls, or any other analog(ish) function.

Step 3: Case, Part 1 - Design and Cutting

Having a breadboard living on my desk just didn't look cool, and the ergonomics were not ideal either. Time to design a case.

This would be an ideal project to 3D print a case for. I don't have a 3D printer but I do have a laser cutter, so everything looks like a laser cut project to me now. This design took an evening to design in Adobe Illustrator, including playing with a lot of different concepts like a simple stick, a more organic shape using laser cut hinges, and boxy shapes.

I started by holding the breadboard at different heights and angles, and decided that an angle of 30° at a height of about 80 to 100mm from the desk would be comfortable. The final design looks a bit like a small flight joystick and feels comfortable to hold.

The original Adobe Illustrator file along with DXF and PDF versions are included below. (The DXF and PDF haven't been tested on a laser cutter.) The file also includes top and side views of the joystick for you to use in laying out your own project.

There are two thicknesses of material used in this design. Everything but the top is 0.187" 'utility' plywood from the local big box store. A 2' x 4' sheet is only about $8. The design uses 5mm as the thickness for the .187" wood in the design, and it assembles perfectly. The top is 3mm plywood to allow extra clearance for the thumbgrip on the joystick. This project would be nice in clear acrylic, too.

A couple notes about the benefit of making prototypes: I did a test cut and assembly with cardboard first which helped find one design mistake. When I cut the wood version the first time I also discovered that the top plate was very fragile by the hole, so I redesigned the tabs to add extra strength there. I also found that the joystick was hitting the side of the case, so I made two changes: I moved the mount to center it better, and I used 3mm wood instead of 5mm on the top. The uploaded design file has all those changes in it - just be sure to cut the top piece from the thinner wood.

Step 4: Case, Part 2 - Paint and Assembly

With all the pieces cut I did a final dry assembly and temporarily mounted the joystick. Everything was good, so I glued up all the pieces except the top. It isn't possible to install the joystick after the top is attached so that will come later.

The bottom right corner of the top would poke into the bottom of my thumb so I rounded off the bottom corners with some quick sanding.

If you like the laser cut look, or if you made this out of acrylic, you're done! I wanted a nicer finish to the piece to go with my desktop. I gave it a base coat of black paint and then few coats of Rust-oleum Forged Hammered Burnished Amber. I used this product on the trim of my desk, so this ties the pieces together. I also like the metallic finish look of this paint. I masked off the inside of the finger joints where the top fits so the paint wouldn't spoil the fit.

The joystick and Arduino were wired up with black wires and shrink tubing to keep it looking clean, and the wires were cut to a length that looked right when installed.

The joystick screws in place on the center strut. The screws I had were a little long, so I shortened them by screwing them through the unused wood and sanded the tips back with a tabletop sander. The Arduino doesn't have mounting holes, so it was hot glued it in place.

With everything mounted I snapped the top into place without gluing. It fits tight enough to hold itself in and isn't structurally important.

Step 5: Completion

The finished project looks great on my desk.

The first thing I used it for was to edit the pictures for this Instuctable.