Hacking the Wii Motion Plus

I’ve been looking for a 3-axis gyroscope recently, and I came across the Wii Motion Plus. Fortunately, other people have done the hard work of reverse engineering the protocol and written this up elsewhere. In short, it’s a nice simple I2C interface.

So I bought one.
To have a little play with it, I knocked up a simple parallel port I2C interface on some breadboard, using a bunch of random NPN transistors that I had lying around. It doesn’t help that the parallel port on my PC (like most PCs) runs at 5V and the Wii Motion Plus wants 3V3, but that’s what transistors and breadboard are for, after all.

I2C interface on breadboard

What are the LEDs for, you may ask? Well, I had to figure out which parallel port pin was hooked up to which wire somehow, didn’t I? It was easier to recycle and old cable knocked up years ago for another hack than to go out and get a new 25 pin D plug and spend time with the soldering iron.

The Wii Motion Plus is the small white thing in the background, just in front of the power supply.

So I implemented some simple I2C bitbanging code and after shaking the last of the bugs out, I was ecstatic to see some numbers coming out of it that seemed to represent the physics of what I was doing to the device.

Obviously, I couldn’t leave it at that. I wanted to know how it behaved in a slightly more complex test case. So after speeding up the I2C code a bit to get closer-to-realtime readings, I devised a cunning demonstration.

I used SDL and OpenGL to knock up a cube, rotating around its centre. Instead of various non-interactive pretty spinning things that you can do with a cube to make a demo, in this case I integrated the readings from the Wii Motion Plus to form a rotation matrix. Rotating the Wii Motion Plus causes similar rotation to apply to the cube.

After guessing at some scaling factors, I got “close enough”, and I was rather impressed with the responsiveness of it all. Other than the few times when the wires fell out while I was moving it, the system was responsive and quite intuitive. It did drift a little, as expected with a gyro and also as expected when I’m not taking samples as often as I could. I think a proper hardware or microcontroller I2C implementation would be less prone to overload and be able to integrate more accurately.

Here’s the video:

Update: You can pull the source code using monotone from mtn.coolfactor.org (branch org.coolfactor.demo.wiimotionplus), or you can browse it here.

Note: This isn’t polished code, it’s just a hack. It works for the purpose of my demo, but it may not work for yours.

I’ve checked the code in and updated the post with a link to the source code. I don’t have a circuit/wiring diagram, but I’ll upload one if I get round to drawing it.

In the meantime, feel free to try to figure it out. It’s just three single-transistor inverters (NPN transistor, emitter to ground, collector pulled up) – two outputs (SDA, SCL – the top two data bits of the parallel port) and one input (SDA – the ACK signal on the parallel port). Tweak the resistor values until it all works.