Archives

All posts for the month January, 2015

I bought a Super Advantage joystick on eBay with the intent of making it a USB stick for my computer.  This isnt as hard as it sounds.

The SNES controller is a very simple device that uses shift registers to get the state of all the buttons from the pad into the SNES using only 3 wires.

Heres how that works, in a nutshell.

You have 12 buttons, XYBALR Start Select, and the 4 directions on the D-Pad.  These buttons are connected to a shift register that takes all those individual buttons and turns it into 2 bytes; 16 bits of information, of which 4 bits are not used.

In code, it looks like this

So our little shift register has 3 lines that we care about (plus power, but that’s going to be a given); these are the CLOCK, DATA and LATCH/STROBE lines.  The way these are used is quite simple.  The CLOCK is always ticking, HIGH,LOW,HIGH,LOW, etc.  each tick of the clock will push one bit out of the shift register down the DATA line.  The LATCH tells the shift register to ‘latch’ or store all the states that are currently present into its internal buffer so they can be shifted out.

So the entire procedure is this, LATCH pulse, then 16 CLOCK pulses, for each you read the DATA line, a 0 means a button is pressed, a 1 means it isn’t, then you start over.  The order of the buttons is always the same, B, Y, SELECT, START, Up, DOWN, LEFT, RIGHT, A, X, L, R.  Using the microcontroller, we can actually just store that into an int.  There’s a library for arduino that can do all this for you.  Grab it here.

Now comes the fun part; making that work as a USB joystick.  I’m using an arduino pro micro.  It has an ATmega 32u4 microcontroller on it that has USB functionality.  Unfortunately, the defualt arduino configuration does not allow for joystick type HID devices, so I’ve used the information from http://www.imaginaryindustries.com/blog/?p=80 (UPDATE: READ BELOW)to add that capability.  Now we just need some glue code.

Thats about it really.


 

UPDATE:  Apparently that blog is down, so I’ll mirror that information here. Original by Connor.

I recently bought a Arduino Leonardo in the interest of updating the interface in an old arcade-style controller I occasionally use to playMAME games.

As such, I needed to figure out how to get the leonardo to properly act like a joystick.
Anyways, this is heavily based on drake250’s work, which is on the freetronics forum here. HelmPCB’s USB Joystick (BAD LINK) site was also a useful reference.
There is a useful list of HID descriptors here.
Also, the “HID Descriptor Tool” from usb.org is also very useful for seeing how HID descriptors are put together. Get it here.

In the end, I wound up rewriting most of the drake250’s HID descriptor myself, based on some of the USB.org docs, and the HID Descriptor Tool.

Anyways, here are my modified files you would need to turn your own leonardo into a joystick. These files support an 8-axis joystick, with two hat-switches, and 32 buttons.
If you want fewer buttons/axes/whatever, you can either just ignore the things you don’t need, or modify the HID descriptor yourself. As it is, for everything the HID descriptor currently specifies, it only needs 12 bytes per PC-update, so I’m not too worried about the extra axes causing issues or slowing things down.

leoJoy-Arduino-1.01
The windows joystick info dialog only seems to be able to display 7 axes. I’m fairly sure the eighth axis there. However, since the built-in windows dialog works almost the time, I have not found any tools for looking at joystick readouts other then the built-in windows dialog. I mean, how may people have an 8-axis joystick anyways?
Also, the HID documents seem to also support the belief that the HID spec allows a maximum of 63 buttons. However, again, the windows tools for inspecting a joystick only support 32. You could add more quite easily, but you would have to test their functionality yourself.

Modified arduino files (replace the files in {arduino executable dir}\hardware\arduino\cores\arduino\ with these):

USBAPI.h
HID.cpp

And the main source file:

 leoJoy.ino 

It’s contents:

The interesting thing here is JoyState_t, which is a struct that stores the state for all the joystick controls.

The struct is defined in USBAPI.h as such:

Continuing on with the contents of leoJoy.ino:

This section just generates random values and sets the analog axes to them. Each bit in buttons is also set in sequence, using bit-shifting.
It also steps through the different hat-switch positions. It steps hatSw1 fowards, and hatSw2 backwards. Lastly, the throttle axis it linearly ramped.

The last (and most important thing) here is

This is the function that actually sends the values in the joySt struct to the computer.

At this point, all that is needed to make a useable joystick is to replace the contents of loop() with something that actually reads hardware buttons.


Anyways, everything is under the arduino license (I think it’s GPL, but the only file I edited with a license actually looks to be BSD-ish. Anyways, do whatever, just don’t be an ass).

 

snes3

SNES2

snes1

I decided to upgrade my G27 shifter.  I’m not using it with a G27 wheel, so it’s possible to do a few things with it. The shift registers inside the stick are configured for 16 buttons; the 4 red, the 4 black in the top quad, the Dpad counts as 4 and the reverse pushdown takes one, that leaves 3 buttons that can be counted, but are not present.  I was never able to trace one of them out, so I was only able to add 2 buttons to my stick.
IMG_0717

Heres the button I’m gonna put in.  Its the horn button left over from my custom wheel mod.

 

IMG_0718

I made a hole!  actually, It was bigger than it was supposed to be so I had to cut even more.  It’s flush mount instead of being proud of the surface like I had wanted.

 

IMG_0719

A bit of a gap, but not too terribly noticeable.  I’ll make some ABS cement later to fill it, but the hot glue on the backside is doing a decent job.

 

IMG_0721

Here is the circuit board, note the unpopulated J12 connector location.  This is where the large button connector will go.  On the G25, this is where the mode switch connects.  I went ahead and drilled a hole in the face for the mode LED to poke through, and added that as well.  It doesn’t have any real functionality apart from blinky lights when you press the button.

 

IMG_0722

The bottom of R109 and the lower pad of R76 on the far left (white wire) are the connection points for the other button.  The black connector was added.  It has 3 pin in it, but only 2 are connected; I’m fresh out of 2 pin connectors.

 

IMG_0723

Everything fits nicely.

 

IMG_0724

And here it is all reassembled.  Not too bad, I don’t think.  I’m thinking of using these as Engine Start/Nitrous buttons.

 

IMG_0726

Obligatory Blinkenlights.