USB Arcade Joystick using a Minimus 32

Sparkfun and their various resellers offer arcade style joysticks and buttons. I put them together to make a controller for MAME and such.

The joystick in action



The joystick I got was this, which turns out to be a Seimitsu LS-32 clone made by ZIPPYY. Most sparkfun resellers seem to only sell the short-shaft version, which is really too short if mounting to anything thicker than a few milimeters. Hardboard is fine, the 12mm pine I originally tried really isn't. This shop sells the longer version, which would have been a better bet had I known. They also have diagrams of the base plate which are very handy.


There are 2 sorts of buttons available, cheap convex and more expensive concave. The concave ones are definitely worth the extra 80p, they feel like the real thing and the others are somewhat dissapointing in comparision. Both take the same mounting holes though, a 28mm hole-cutter drill bit is perfectly sized for both buttons.


A cheap AVR development board that I have a page about. I used the Minimus 32 here but will probably switch to the cheaper one at somepoint.



Whilst skip-raiding for a bit of hardboard to mount everything through, I came across a hand-made draw that was exactly the right size and design. So this bit was pretty easy. Thanks, anonymous furniture assembler! The base is a rectangle of chipboard with a hardboard base screwed on. A bit of a rubbish draw, but perfect here.

I planned out the layout first using inkscape, which you can download here. This also shows how the base is constructed. The rear edge is taller than the others, presumably this was as a handle but it tilts the joystick slightly towards you, and gives space for the USB cable to come out.


The source code can be found at https://github.com/lentinj/usb-arcade-joystick/

The firmware is a slightly modified version of LUFA's joystick demo program. By default the demo tries to use the built-in controls of whatever board it's being compiled for---a Minimus doesn't have a joystick, so compilation out-of-the-box fails. We instead use a custom button and joystick drivers, using PB0--7 for button inputs and PC4--7 for the joystick directions. The button inputs are debounced using a vertical counter. The joystick didn't seem to need it, so no debouncing was added there.


The wiring is dead simple, since the chip has built-in pull-up resistors. Connect each switch to the relevant port and ground. i.e. Button 1--8 attach to the minimus' PB0--PB7 pins, joystick directions to PC4--7, and then the other end of all the buttons go to GND. The joystick and more expensive buttons have 'lucar' blade terminals which you can buy connectors for instead of soldering directly. The buttons fit perfectly, you may need to squish the connector slightly for a snug fit.

Inside view of the joystick
There, that makes it obvious doesn't it?


The 'joystick' package in Debian includes a program called 'jstest', which gives you a simple display of joystick values. Plug the joystick in and watch dmesg, you should see something like:

usb 2-1.2: new full speed USB device number 12 using ehci_hcd
usb 2-1.2: New USB device found, idVendor=03eb, idProduct=2043
usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-1.2: Product: LUFA-Powered Arcade Joystick
usb 2-1.2: Manufacturer: lentinj Industries
input: lentinj Industries LUFA-Powered Arcade Joystick as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input14
generic-usb 0003:03EB:2043.0006: input,hidraw0: USB HID v1.11 Joystick [lentinj Industries LUFA-Powered Arcade Joystick] on usb-0000:00:1d.0-1.2/input0

Then use jstest to ensure the buttons are all working and the right way around:

# jstest /dev/input/js0
Driver version is 2.1.0.
Joystick (lentinj Industries LUFA-Powered Arcade Joystick) has 2 axes (X, Y)
and 8 buttons (Trigger, ThumbBtn, ThumbBtn2, TopBtn, TopBtn2, PinkieBtn, BaseBtn, BaseBtn2).
Testing ... (interrupt to exit)
Axes:  0:     0  1:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:on

You're now ready to go play games!