Saturday, April 19, 2014

Building a Fight Stick

I just built a (prototype of) a fight stick.

It was a process.

For a while, everything went off without a hitch. The controller is built around an Arduino Leonardo, which has a couple of very important features. First, the new AVR microcontroller embedded in it supports USB communication directly, without the need for a second chip. This means that the Leonardo can act as a USB host and emulate Human Interface Devices natively, given the right software support. (You can do this with older Arduinos, but you need to reprogram the USB communication chip that is usually used for programming the Arduino. So every time you need to change your code, you need to flash the original software to the communications chip, use that to program the Arduino with your new code, and then re-flash the communications chip with your modified, HID-emulation bootloader, which is a really awkward hack.)

The controller uses Sanwa pushbuttons, which are pretty standard, and started off with a rare, complex joystick called the Ultrastik 360. The Ultrastik is a magnetic analog stick in an arcade joystick form factor.

The most interesting part of this project was the physical act of building the stick. Stripping wires, crimping connectors, cutting holes in cardboard boxes with a dull X-Acto Knife... There's something about a new wiring harness that makes me really happy, I can't quite explain why.

The actual circuitry is pretty simple. Every button or directional input has a pin on the Arduino. These pins are connected to power through a small resistor ("pulled high") and connected to a button, which is connected to ground. This means that, when the button is pressed, the input pin is connected to ground with less resistance than to power, the pin reads low, and we know our button is pressed.

The software problems are significant, but fortunately I didn't have to solve any of them. Writing a new HID Report Descriptor, and the drivers attached to that, is a tremendous amount of very low-level, technical work. Fortunately, the kind people over at the UnoJoy! Project have done it all for me, and it's all open-source, well-documented, and performant. Give them all your pageviews.

I'm still fortunate in that I didn't have to make any modifications to the HID Report Descriptor they gave me. 13 buttons, a D-Pad, and six analog axes as a hard limit could cause trouble for some people, but it was plenty for me.

My first hitch came when it was time to wire up the Ultrastik. It's a very sophisticated piece of hardware, capable of appearing as a Joystick in windows on it's own. It has a nine-pin communication header, which can either be used to read eight buttons (and communicate their state to Windows), or to output four digital values (as an eight-way stick) and two analog values (as an analog stick) to an external source. The ultrastik autodetects which mode to enter when it powers on, based on whether the digital output lines are pulled high or not. Unfortunately, this didn't work, for reasons I still haven't determined. Current theories are:

1. My Arduino isn't pushing quite enough power to the Ultrastik, and I should probably invest in a decent multimeter.

2. I have a bad Ultrastik. I don't think this is the case, but it's a possibility I haven't been able to rule out entirely.

In any case, I couldn't get the UltraStik into output mode. I spent a while talking to Andy at Ultrastik, he was very responsive and helpful, a real pleasure to work with. (As far as I can tell, Andy is UltraStik; they're modified Sanwa joysticks, and it's a very niche market, so I believe he makes them more-or-less by hand.) I sent him some questions, and he gave me more detailed information about the automatic mode selection. When I still had problems, he sent me modified Ultrastik firmware to force the stick into Output mode. Unfortunately, after I installed it, it bricked my stick, and I'm sending it back to Ultrastik for repairs. It's an unfortunate situation, and I feel a little bad writing it here. If someone finds this while researching Ultrastik: I actually recommend it. The hardware is great, it worked well out of the box for most applications (mine is very fringe, most people will use Input Mode) and for people like me with atypical applications, Andy's very helpful. This problem isn't yet resolved, and has run into complications, but I firmly believe that given more time we will, or at least could, make it work.

Unfortunately, I ran out of time. It's the end of the year, and I have a stick that doesn't work. Fortunately, one of my friends, who was assisting with this project, found an old Atari controller in a box in his roommate's closet. These controllers aren't very nice to handle, but they're great to work with. I still mourn the demise of parallel interfaces; they're so intuitively hackable. In any case, wiring up an Atari controller is super simple, and provided some semblance of functionality. You can play flash games with Joy2Key. You can play Super Meat Boy, but it's hard. I can't condone Skullgirls, the Atari stick is just too sticky.

 Here's an awkward video that didn't embed quite right. It's very late, I'm sorry.

1 comment: