Introduction: USB Wiichuck Mouse Using an Arduino Leonardo

This instructable will (retroactively) show how I turned a Wii Nunchuck into a mouse for my PC. I built this device about a year and a half ago, when I was first getting into hobby electronics and microcontrollers. I didn't share it because I thought there was already a similar project on here. Turns out, all of the other Wiichuck mouse projects on here are of slightly different flavors.

This particular build uses an Arduino Leonardo as an intermediary between the Wii Nunchuck and a USB cable, as well as a case to keep it all neat and tidy. The code for this project was not written by me originally. I did modify the code to fit my own needs and work with my board, software version and Wiichuck.  Unfortunately, I didn't think I would be sharing this project and thus the original author of the code is lost to me. The nunchuck library, however, was written by Tod E. Kurt  http://todbot.com/blog

Step 1: Prepare Hardware

Since I didn't actually own a Wii, to begin, I first went out and bought a new Wii Nunchuck for $20.  After getting the Nunchuck home, I realized that it required a special proprietary tri-wing screwdriver to open up (opening the Nunchuck up ultimately turned out to be pointless, but I was originally wanting to do something similar to this project by ampu.

While I was waiting for the tri-wing to arrive, I hacked the connector off of the end of the cable and began researching which was which. The Nunchuck runs on +5 V logic voltage and communicates with the Wiimote using I2C. It turns out, the cable coloring is not exactly standard and it took some poking around with a multimeter and later some experimenting inside the Arduino IDE serial monitor to get the voltage, ground, SDA and CLK lines sorted out.  After soldering some jumper cables to the ends of all of the wires for easy interfacing with the Arduino I/O ports, I was ready to move on.

Or not. I may have jumped the gun slightly here, because this was all before the Arduino Leonardo existed and all I had was an Uno. Since the Uno can't act as a USB host, the project effectively stalled here for six months until; Lo! What is that on the horizon? The Leonardo you say?? Can act as a USB host you say? Onward with the Wiichuck mouse!

Step 2: Software

After receiving my shiny new Leonardo, I began looking into how I was going to get it all working. Since the Wiichuck uses 5 V power and communicates via I2C, the wiring was relatively simple. I simply hooked up the 5 V, GND, SDA and SCL lines to the corresponding ports on the Leonardo and I was ready to go.

The software was a bit more difficult. It took me quite some time and a lot of experimentation to find code that was going to work for what I needed. As I mentioned earlier, both the Nunchuck function library (which I've included in this instructable) and the original source code (which I can't seem to get to upload correctly, so I'll just copy and paste below) were written by others and then modified for my purposes.

Essentially, what the code does is use the Nunchuck library to get data from the 'Chuck every 10 ms. Having set a range for the mouse to move in, the code uses this range to determine the resting threshold of joystick. After the main loop reads the C and Z buttons and outputs them as the left and right mouse buttons, the code then goes on to read the x and y axes. After subtracting the center position value from the received reading, the resultant absolute value is compared to the threshold variable. If the value is less than the threshold for movement, the move distance is set to 0, otherwise the move distance is the read distance. If either the x or y distance is not 0, the mouse moves the corresponding distance.

It should be noted that this whole process can work just as well with the accelerometer. Instead of using the nunchuck_joyx and y functions, one could feasibly use nunchuck_accelx and y. I wouldn't reccomend it, however. The results when attempting to use the mouse can be.....squirrely. 

//Wiichuck Mouse
//Brian Krukoski
//April 2012
//red-+5, white-gnd, green-sda, yllw-clck

#include <Wire.h>
#include "nunchuck_funcs.h"
int loop_cnt=0;

// parameters for reading the joystick:
int range = 40;               // output range of X or Y movement
int threshold = range/10;      // resting threshold
int center = range/2;         // resting position value

boolean mouseIsActive = false;    // whether or not to control the mouse
int lastSwitchState = LOW;        // previous switch state

void setup() {
  // initilization for the Wiichuck
  nunchuck_init();
  // take control of the mouse:
  Mouse.begin();
  Serial.begin(9600);
}

void loop() {
  if( loop_cnt > 10 ) { // every 10 msecs get new data
    loop_cnt = 0;
    nunchuck_get_data();

    //right and left click control
    int leftState = nunchuck_cbutton(); 
    if (leftState) Mouse.press(MOUSE_LEFT); else Mouse.release(MOUSE_LEFT);
    int rightState = nunchuck_zbutton();
    if (rightState) Mouse.press(MOUSE_RIGHT); else Mouse.release(MOUSE_RIGHT);

    // read the x axis
    int xReading = nunchuck_joyx(); //calls on nunchuck_funcs library for x axis reading
    xReading = map(xReading, 38, 232, 0, range); // 38 and 232 arbitrarily determined through experimentation, maps to 0 and preset range
    int xDistance = xReading - center;
    if (abs(xDistance) < threshold) //if absolute value of xDistance is less than predefined threshold....
      {
        xDistance = 0;
      }

    // read the y axis
    int yReading = nunchuck_joyy(); //calls on nunchuck_funcs library for y axis reading
    yReading = map(yReading, 38, 232, 0, range); // 38 and 232 arbitrarily determined through experimentation, maps to 0 and preset range
    int yDistance = yReading - center;
    if (abs(yDistance) < threshold) //if absolute value of yDistance is less than predefined threshold....
      {
        yDistance = 0;
      }

    // move the mouse if the readings were above 0
    if ((xDistance != 0) || (yDistance != 0)) {
      Mouse.move(xDistance, -yDistance, 0); // -yDistance ensures inverted style joystick
    }
  }
  nunchuck_print_data(); //prints nunchuck data to serial monitor for debugging purposes
  loop_cnt++;
  delay(1);
 
}

Step 3: Making It Permanent

Now that I had the project working, it was time to make it a little more permanent. With nothing but some jumpers plugged into an Arduino, it was pretty easy to accidentally disconnect lines during uses. I even yanked the USB cord out once or twice.

At the time I built this project, I was working for a company making power supplies. I had a number of scrap molded plastic cases that were a wonderful size for fitting an Arduino into. I first drilled some holes into case where I attached some PC standoffs on which to mount the board. After that, I cut a hole in the side of the case to run some wires through. I initially tried to run the Nunchuck cable itself through this hole in the side, but that left no space for the USB cable. I ended up running the Nunchuck cable through a hole in the lid, which worked out more or less perfectly.

I kept all of the cables in place and insulated with a little bit of Sugru. I had gone a bit overboard on the hole I cut in the side and had to shore that up with some Sugru as well. I left enough space that I could plug or unplug the USB cable from the board easily even when the case was sealed up.

There you have it, my Wiichuck Mouse. Works pretty well actually. My only complaint at this point is that it's a bit of a pain to have to click on scroll bars when browsing the web. At some point I would like to add a pushbutton that when pressed, reads the accelerometers and uses that data like a mouse scroll wheel. Some day....