Jun 19

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.

Apr 26

Basic Arduino Robot

The Arduino is a great way to get started in the world of DIY electronics and robotics. This project pulls together a few key items to interface with an Arduino. This robot is controlled through the joystick of a Wii Nunchuck (although you could just as easily use the accelerometer) and has a 2 wheel drivetrain similar to the design used by iRobot’s Roomba. Here are all the supplies needed for this project:

Supplies

  • 1 Arduino
  • 1 breadboard
  • 2 full rotation servos
  • 2 servo wheels
  • Breakaway headers
  • 1 Ball Caster
  • 1 Wii Nunchuck
  • 1 WiiChuck adapter
  • 1 9v battery with connector (or other battery pack)
  • 4 AA batteries and holder
  • Blank CD
  • 2 sided tape

Construction

The blank CD provides a frame for the robot. The servos are attached to the top with 2 sided foam tape and a ball caster is taped to the bottom of the CD in the front. This is called a two wheel drivetrain and is controlled by the speed each wheel rotates at. If both wheels spin at the same speed the robot goes forward, if one spins faster than the other then the robot goes in the direction of the slower wheel.

Wiring the robot is the next step. An easy way to keep this organized and allow for future expansion is to setup the wiring on a small breadboard. Servo’s typically come with a 3pin female connector; to be able to plug these into the breadboard you need breakaway headers. The Wiichuck is plugged directly into the analog pins of the Arduino.

This robot requires different power sources for the Arduino and for the servos. Servos draw a high current so if only one battery pack is used the Arduino would lose power when the wheels started to spin. One thing to remember when using multiple power sources is to tie them all to a common ground.

Here is a diagram of the setup:

Once everything is connected, all you need to do is stack the components onto the platform and connect the power. You can also wrap a rubber band around the breadboard, Arduino and battery pack to prevent it from slipping

Sketch

Here is the code to make the whole thing run:

// Simple Robot controlled with Wii Remote
// ForkRobotics
//

#include <Servo.h>
#include <Wire.h>
#include "nunchuck_funcs.h"

//Create Servo Object for Left Wheel
Servo RightWheel;
Servo LeftWheel;

int loop_cnt=0;
int speed,direction,LeftRotate,RightRotate;

void setup()
{
  RightWheel.attach(5);  // attaches the Right Wheel to pin 5
  LeftWheel.attach(6);  // attaches the Left Wheel to pin 6

  // initilization for the Wiichuck
  nunchuck_setpowerpins();
  nunchuck_init();
}

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

    nunchuck_get_data();
    speed  = nunchuck_joyy(); // reads joystick y axis (range of 38-232)
    direction  = nunchuck_joyx(); // reads joystick x axis (range of 25-223)

    // Converts the joystick input to the servo output range
    speed = map(speed, 38, 232,0,180);
    direction = map(direction, 25, 223,-90,90);

    // The joystick floats a little, this reduces jitters when it's near center
    if (speed >= 87 && speed <= 93) speed = 90;
    if (direction >= 87 && direction <= 93) direction = 90;

    // Translates the joystick reading to the rotation speed for each wheel
    RightRotate=speed-direction;
    LeftRotate=(180-speed)-direction;

    // Writes the rotation speed to the servos
    RightWheel.write(RightRotate);
    LeftWheel.write(LeftRotate);
  }
  loop_cnt++;
  delay(1);
}

If you try to upload or verify this code directly you will get this error:

Before you can compile and upload the code you need to put a copy of the nunchuck_funcs.h file from the WiiChuck Project http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available in the same folder as the sketch. Follow these steps:

  1. Save the sketch
  2. Close Arduino IDE
  3. Copy the nunchuck_funcs.h file into the sketch folder
  4. Reopen the sketch
  5. Upload

The result

The result is a basic robot that has direct control through the Wii remote.

I consider this a starting point for more complex projects. Adding bumpers or distance sensors would allow for the robot to do obstacle avoidance or a camera pointed through the hole of the CD could allow line tracing.