Introduction: Magnetic Sensor Arcade Spinner

A number of arcade games used spinner controllers, the most famous being Arkanoid and Tempest. The Atari 2600's Driving Controller for the Indy 500 game is also a low-resolution example. Spinner controllers differ from paddle controllers like those for Pong and Breakout (and the NES port of Arkanoid), because a spinner allows unlimited 360 degree rotations, while paddle controllers have a limited range of motion.

Spinner controllers are usually made with an optical rotary sensor (though the Atari Driving Controller uses physical metal contacts), but I went for one using a Hall-effect I2C magnetic absolute rotary sensor, together with a ball-bearing mounted knob with a matching round magnet. The sensor detects the rotation of the magnet, and so we can mount the sensor under the knob, and stick the magnet under the knob, and get no-contact position.

This reduced cost (especially since I had free samples of the sensor and magnet from Austria Microsystems in my supplies: thank you!), simplified implementation, and has a nice low profile. The ball-bearing mount for the spinner lets the spinner keep on spinning by itself for many rotations--it feels very satisfying.

I also added four buttons: two nice big arcade buttons and two cheap tactile switches with a cap glued on. And, eventually, I added a port where I can plug in a Wii Nunchuck controller for games like Mad Planets that need a joystick in addition to a spinner.

The microcontroller scales the 4096 per rotation resolution to 1200, as that seems to be what popular commercial USB spinners are at.

For USB support, I used an stm32f103c8t6 blue pill microcontroller (clones for about $2 and originals for about $3 on Aliexpress) with the libmaple-based Arduino core and my USB Composite library. Source code for the firmware is here. The resulting device emulates a three-button mouse with the spinner controlling the horizontal motion of the pointer, together with a keyboard mapped from the fourth button and the Nunchuck buttons. I made the bindings to work fairly well with the Internet Arcade emulations on archive.org. Also, if you hold down the third button while powering on the device, it switches to Stelladaptor mode, which Atari 2600 emulators should pick up and map as a Driving Controller.

Version 1 used tactile switches with glued on caps for the more rarely used buttons 3 and 4. Version 2 uses 3D printed arcade buttons encasing caps.

Much of this is 3D printed.

Supplies

  • AS5600 or AS5601 encoder IC in SOIC-8 (about $4 from DigiKey). You can buy AS5600s on a breakout board (with a magnet included, but the size of the magnet may be insufficient), so that might save a bit of work, but the breakout boards may be too big to fit my design.
  • SOIC-8 breakout board (unless you encoder has one). I used this one from Aliexpress; if you use a different one, you may need to change some of the dimensions of the 3D-printed parts; mine was 11.94x11.58 mm.
  • Diametrically magnetized (this is crucial) 6mm diameter 2.5mm height neodymium magnet. I used Austria Microsystems' AS5000-MD6H-1. This or this might work.
  • one smoothly rolling 608 bearing
  • stm32f103c8t6 blue pill board
  • two 4.7K-10K resistors
  • TTL serial to USB adapter
  • two 30mm arcade buttons (SANWA OBSF30 compatible, like these)
  • two 6x6mm tactile switches
  • 3D printer and filament
  • optional: Wii Nunchuck, adapter board (like this) and two more resistors in the same range

Total parts cost, not counting the Nunchuck, should be around $20, plus shipping.

Step 1: Solder to Breakout Board

It's really crucial that the AS5601 chip be centered on the board so that the center of the magnet is no more than 0.25mm from the center of the chip. I have a little 3D-printable jig for centering.

To solder the chip, put a dab of tacky PVA craft glue (I use Aleene's) in the center of the PCB. Orient the chip so that its pin 1 (see photo) is connected to the pin labeled 1 on the PCB (My PCB has different numbering on the top and bottom, and it is the top numbering that is right for it) and place it in the jig with the PCB on top. Center the chip (see below for details). Wait for the glue to set (30-60 minutes), remove from jig, and solder with fine solder and a fine-tip iron.

The potentially tricky thing is centering the chip. Once the chip is in the jig, you can shift it slightly by poking it with a fine screwdriver. My first try was just to eyeball it, and that is the PCB that I have in my spinner--it works fine. But if you want verifiable precision, read on for another way I found.

Precision Centering

First take a macro photograph of the chip, carefully ensuring the camera is vertical. Import the photograph into Inkscape or some other image editor (I prefer vector to pixel for this), and draw some lines from opposite chip features, like opposite corners of the chip or places where the legs come out of the package. (Be careful: the AS560x has asymmetric beveling on the top surface. It is the bottom surface that needs to be centered, I believe, not the top surface.) I would do several of these for greater precision. See screenshot.

For me, this identified the lower right bump of the "8" in the second line of text as the center of the AS5601 (and when I tried it with an AS5600, it was the lower end of the stroke in a "5"). I also drew a red circle of radius 0.25 mm (I knew the chip package was 4.9 x 3.9 mm, so I could scale it) to see what my placement tolerance would be.

The centering jig has a sighting hole. You need to align the part of the chip you identified as the center in the sighting hole. If you have good eyesight, you can eyeball it. I also successfully used a microscope. But the best method for me was to use an illuminated magnifying glass.

Once you are done soldering, you can take another macro photograph and verify centering on the PCB in your image editor.

Step 2: Upload Firmware

The firmware uses the libmaple based Arduino core for the stm32f103c8t6. You can follow the Arduino setup directions here, get my sketch source code from here, compile it and upload it.

However, if you don't want to bother compiling the code, you can just download the binary here (click on "View raw") and upload the firmware to the blue pill as follows. Make the following connections:

  • Blue pill A9 to serial adapter RX
  • Blue pill A10 to serial bridge TX
  • Blue pill ground to serial bridge ground

(Actually, I am lazy and usually just plug both the blue pill and the serial adapter to the the same computer, and the grounds are close enough that I don't bother with the direct ground connection.)

On the blue pill, there are two sets of jumpers, each on a trio of pins. Make the first jumper (B0) join the center pin with the right pin (center to B0+ or center to 1, depending on labeling). Make the second jumper (B1) join the center pin with the left pin (center to B1- or center to 0, depending on labeling).

Power up the blue pill via its USB port (if you connect it to the computer, the computer will likely complain about an unrecognized USB device; ignore that). Start the Flash Loader Demonstrator. Choose the COM port for your serial adapter (the Windows Device Manager can help there). Choose "Remove protection" if available. Choose a 64kb rather than 128kb flash version. And download the firmware binary file into the device. Unpower everything and then move the first jumper to left+center. 

Step 3: Initial Spinner Assembly

Download the 3D printable files. If you use the same size PCB as I have (11.94 x 11.58 mm), you can just print directly. Otherwise, you will need to change pcbSizeX and pcbSizeY in the OpenSCAD file. (If the sizes of these are large enough, you will need to enable supports when printing.)

At this point you want to decide if you want the simple top-mounted tactile switches for buttons 3 and 4 that I had in Version 1, or if you want the fancier 3D-printed buttons 3 and 4, and choose the matching version of the top plate.

Print the knob and top plate of the spinner box.

Press fit the magnet into the depression in the knob axle, and press fit the bearing over the axle.

This is a good time to check that the pin numbers on the PCB match the ones on the IC (use a continuity tester).

Make the following connections between the sensor PCB and the blue pill, ensuring the wires come out of the bottom of the PCB and into the top of the blue pill PCB:

  • sensor pin 7 (SCL) to blue pill B6
  • sensor pin 6 (SDA) to blue pill B7
  • 4.7K-10K resistor between blue pill B6 and ground
  • 4.7K-10K resistor between blue pill B7 and ground
  • sensor pin 2 (3V3) to blue pill V3
  • sensor pin 4 (GND) to blue pill ground

Press fit the PCB with the magnetic sensor into the rectangular hole.

Press fit the knob bearing into its slot on the spinner box. If it's too loose, add a bit of tape to the sides of the bearing. If it's too tight, sand the holder. (Or reprint with different tolerances in the OpenSCAD file.)

Plug into USB port. If all goes well, it will be recognized as a mouse, and the spinner will control the horizontal axis.

Step 4: Buttons

Buttons 1 and 2

Snap arcade buttons into the two big button slots on the top plate for buttons 1 and 2.

Buttons 3 and 4

For Version 1 (top-mounted tactile buttons), just put the legs of tactile buttons through the small holes. You may need to straighten the legs with pliers.

For Version 2, get the 3D print files for the buttons. The wells and plungers for the buttons are designed for 5mm high (from base to top of button) tactile buttons. If yours are a different size, use the Thingiverse customizer or OpenSCAD to change them (the crowns don't care about the button height). Print two wells, two plungers, and an x2 crown (with two holes). I recommend printing the wells and plungers with as high resolution as you can to make the vertical motion less bumpy.

Straighten the legs of the button and fit it into into the well with legs sticking out the button (this is tricky; I used needlenose pliers to fit it, and you may need to tweak the tolerances in the customizer or sand a little to fit). Put the plunger on top (with the stepped side up). Make sure that the wider part of the plunger does not protrude at all beyond the top of the well or else the button won't work reliably; if you have this problem, increase the vertical tolerance. Snap into a crown and make sure it works. For smooth motion, you may want to sand the inside of the wells and the edges of the plunger.

Then glue the well into the crown with a bit of superglue, and put some drops of superglue into the button slits by the legs. Glue the whole button assembly into the top plate.

Wiring

For each button, connect one leg to ground. Then connect the opposite leg (on the tactile buttons, just use one diagonally opposite to it) as follows

  • button 1 (lower arcade button) - blue pill A6
  • button 2 (upper arcade button) - blue pill A7
  • button 3 (left tactile button) - blue pill B0
  • button 4 (right tactile button) - blue pill B1

Test to ensure that buttons 1, 2 and 3 generate mouse 1, 2 and 3 presses, while button 4 generates a keyboard period.

Step 5: Mount

Print the bottom of the case and the PCB holder for the blue pill. Slide the blue pill PCB into the PCB holder. Screw it to the bottom of the case. Screw on the top. And you should be done, unless you want to do the nunchuck connector (see last step).

If you like, you can glue a 3D-printed button cap on your Version 1 tactile buttons. I have not been super happy with these, though, which is one of the reasons I went for Version 2 in the end.

Step 6: Playing on Archive.org

While archive.org has lots of in-browser emulated arcade games that use the spinner, the default settings for its in-browser Emularity emulator do not enable mouse control, and a USB spinner is a one-axis mouse. You need to tweak the internal Emularity settings to use the games with the spinner.

Here's what you need to do. Go to a game on archive.org but do not press the start button yet. Instead, put the following into your browser address bar (note: Chrome won't let you copy and paste the "javascript:" part so you'll have to enter that manually) and press enter:

javascript:MAMELoader.extraArgs=(z)=>({extra_mame_args:['-mouse','-keepaspect']});AJS.emulate()

(This also fixes a full-screen aspect ratio issue.)

To save yourself the typing, you can also install this as a bookmarklet. You can try to drag the Emularity Mouse link from this page on my blog into your bookmark bar. If that fails, create a bookmark to a random page, and right-click to edit it, and change its URL to the javascript code above. Then to start a game in mouse mode, just click on your bookmark.

Step 7: Game Calibration

With default firmware, the spinner has 1200 steps per turn. Most classic arcade games used a lot fewer steps per turn. Here is a table. If you're using MAME, you can scale down the sensitivity to match the game. For instance, the table says that Tempest is 72 steps per turn. You need a sensitivity of 72/1200*100=6 percent. In MAME, go to the menu (TAB by default), choose Analog Controls, choose Dial Sensitivity, turn it down do 6 (use arrow keys), and then go back to the game with TAB.

Step 8: Optional: Wii Nunchuck Port

Desolder the pins on your nunchuck adapter board.

Make the following connections:

  • Minus to blue pill ground
  • Plus to blue pill 3.3V
  • D (SDA) to blue pill B11
  • C (SCL) to blue pill B10
  • 4.7K-10K resistor from D to Plus
  • 4.7K-10K resistor from C to Plus

My soldering got really terrible, and I ended up having to pot the whole thing with hot glue.

Print the nunchuck adapter holder. It will be oriented as in the picture above (screw hole at the top) looking from the outside of the spinner box.

Press fit the nunchuck adapter board into the rectangular hole. The adapter board has three traces on the top side and two on the bottom side. It should far enough into the rectangular depression in the holder that contact can be made by a nunchuck from the outside of the box. Put a small screw from the outside of the box into the holder to keep it in place, and consider gluing the bottom of the holder to the buttom of the box.

The Nunchuck joystick should generate arrow key presses and the nunchuck buttons should generate left CTRL and ALT. This works well as default settings for some Internet Arcade games on archive.org.

Magnets Contest

Participated in the
Magnets Contest