Leonardo Wiichuck Mouse

The Arduino Leonardo’s big new feature (thanks to its ATmega32u4 chip) is the ability to emulate a keyboard and/or mouse. This brings up so many possibilities for alternative control schemes for a computer. In this article I’ll show you how to grab the input from a Wii Nunchuck and get your computer to detect it as a mouse.

Wiichuck on Leonardo

I’ve worked with the Wii Nunchuck many times in the past including the Basic Robot I posted about a while back. Unfortunately the physical Wii Chuck adapter, while still a great way to breakout the pins for a nunchuck, is no longer as simple as plugging into pins A2-A5 as it was used on an UNO.
The major difference here is that the Arduino Leonard uses a different microcontroller than was used in the UNO. Because of this the pin mappings for certain functions are now different. One function that has been relocated is the pins used for I2C which is how the Wii Nunchuck communicates with the Arduino. On the UNO (and other boards based off of the ATmega328) the SDA is shared with A4 and the SCL is shared with A5. This is convenient because pin A3 can be used as power and A2 can be used as ground which allows 4 consecutive pins to be used for the Wii Chuck to plug into. However with the Leonardo and its new chip the SDA is shared with D2 and SCL is shared with D3 (they are also broken out to their own pins). In order to connect the Wii Chuck to the Arduino Leonardo you have to use a breadboard to make the appropriate connections.

In addition to the physical change in the pins there are references in the Wii Chuck Library for Ground and Power pins by using the “ports” which are also different. This requires editing the nunchuck_funcs.h file when using it with the Arduino Leonardo. With all that in mind, here is how to complete the project:

  1. Create a New Project with the following code:
    //Wiichuck Mouse
    //Fork Robotics 2012
    
    #include
    #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();
    }
    
    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();
        xReading = map(xReading, 38, 232, 0, range);
        int xDistance = xReading - center;
        if (abs(xDistance) < threshold) {
          xDistance = 0;
        }
    
        // read the y axis
        int yReading = nunchuck_joyy();
        yReading = map(yReading, 38, 232, 0, range);
        int yDistance = yReading - center;
        if (abs(yDistance) < threshold) {
          yDistance = 0;
        }
    
        // move the mouse
        if ((xDistance != 0) || (yDistance != 0)) {
          Mouse.move(xDistance, -yDistance, 0);
        }
      }
      loop_cnt++;
      delay(1);
    }
    
  2. Save the project and close Arduino IDE
  3. Download nunchuck.funcs.h
  4. Save it to the Project folder
  5. Open the project and click the tab for nunchuck_funcs.h
  6. Remove the following lines:
    // Uses port C (analog in) pins as power & ground for Nunchuck
    static void nunchuck_setpowerpins()
    {
    #define pwrpin PORTC3
    #define gndpin PORTC2
        DDRC |= _BV(pwrpin) | _BV(gndpin);
        PORTC &=~ _BV(gndpin);
        PORTC |=  _BV(pwrpin);
        delay(100);  // wait for things to stabilize
    }
    
  7. Press upload

Once the code finishes uploading you should now be able to move the joystick to move the mouse, click C for left click and Z for right click.

Uploading code and using USB emulation

One lesson I learned from this processes is that the Leonardo uses the same processor for running sketches and communicating over USB. The challenge here is that when you emulate a USB device this can overwhelm the Arduino and prevent you from uploading new code. You can avoid this in 2 ways:

The first is to have some way to enable or disable device emulation this could be by pressing a button to enable or disable the device or only sending data when a button is held down.  The second way is to only send data when there is valid input. In this sketch I opted for the latter. It’s done with an if…then statement:

if ((xDistance != 0) || (yDistance != 0)) {
      Mouse.move(xDistance, -yDistance, 0);

What this does is eliminates the sending of null updates when the joystick is centered, allowing you to upload code.

This is a very quick and simple way to demo this feature but there are many other possibilities. It is possible to use the accelerometer in the Wii Nunchuck to move the mouse but I found it hard to control. More importantly it’s possible to use any component that you can interact with can now be a computer interface: hall sensors, distance sensors, or RFID readers. If you’re working on something similar leave a comment, I’d love to hear about it.

One thought on “Leonardo Wiichuck Mouse

  1. Pingback: Arduino Leonardo as a joystick | Gistlabs

Leave a Reply