Control Your Robot Using a Wii Nunchuck (and an Arduino)

94,897

185

53

Introduction: Control Your Robot Using a Wii Nunchuck (and an Arduino)

After wearing myself out playing Wii Boxing I got to thinking wouldn't it be great if I could use this to control my robot, (looking to my left hand).

Looking around the internet I found a bevy of people doing similar things, (links to everyone just below the video). So what follows is a re-packaging of all their hard work, resulting in a robot controllable by both the Wii nunchuck's joystick or more interestingly its accelerometers.

A quick video of my Arduino Controlled Servo Robot - (SERB) being controlled by a Wii nunchuck.


(resources)
  • (here) - Arduino Code - Chad at WindMeadows.com has written excellent arduino code for reading the Wii nunchuck. Code which I have included pretty much verbatim in this project. if you're interested in more technical details this is where to look.
  • (here) - Nunchuck Details - WiiLi.org has a great wiki about all things Wii, this is a link to a page that describes the nunchucks protocol and how to calibrate your nunchuck.
  • (here) - WiiChuck Adapter - Tod of todbot.com very kindly produced a small adapter to make plugging your nunchuck into a breadboard particularly easy.

(similar projects)
  • (here) - Wireless Nunchuck Control - Frank over at Society of Robots went one step further adding a wireless link so he can control his Arduino robot with all the tilt and twist fun from afar.
  • (here) - Nunchuck Controlled Pan and Tilt Camera - Using a Nunchuck and an Arduino to control the pan and tilt of a camera.
  • (here) - Nunchuck and Arduino Controlled Canoe - Finally a rather epic project that uses an Arduino, nunchuck, servos and small trolling motor to drive a Canoe.

(if you have an Arduino nunchuck project you've completed drop me a line and it can be added here)
(shameless plug)
To check out more of our lovely open source projects - oomlout.com

Step 1: Parts & Tools

Only a few parts to collect before we get wiring and programming

Robot - (Arduino Controlled Servo Robot - (SERB) )
( build your own , or purchase a lovely kit ($175)
  • We use an Arduino Controlled Servo Robot - (SERB) however any Arduino powered dual servo robot will work. Other options (here)

Electronics - ($24)
  • Wii Nunchuck - ($20) - (Amazon) , or at your closest Blockbuster or CircuitCity
  • WiiChuck Adapter - ($4) - A small circuit board that allows you to plug your nunchuck into a breadboard without modifying it. (if you don't want to use your nunchuck on your Wii you can save yourself four dollars and simply cut the connector off and plug the wires directly into your breadboard) - (FunGizmos)
  • Assorted pieces of Breadboard wire - (22 AWG solid)

That's it onto Wiring it up

Step 2: Wiring

Wiring this up could not be simpler, and requires only four wires.

Explained
  • Data - (d) - (green) - Arduino Analog 4
  • Clock - (c) - (yellow) - Arduino Analog 5
  • Ground - (-) - (white) - Arduino gnd
  • +3.3v - (+) - (red) - Arduino 5v (although the Arduino is a 3.3 volt device it seems to work without adverse effects at 5 volts)

Pictorially
  • refer to the attached wiring diagram (05-(NUSE)-Wiring Diagram.pdf)

Step 3: Programming

The Wii Nunchuck is now connected to the Arduino's i2c port. For those of you (including myself) who don't really understand what that means do not fret, just rest assured, it is a good thing. If you would like to know more of the nitty gritty details they can be found (here)

(many thanks to chad at windmeadow.com for doing the research and writing really easily understood Arduino code to interact with the Wii nunchuck, the program below includes his code virtually unchanged).

What it does
  • The program will default to using the nunchucks joystick for control. If you push the stick forward your robot will go forward, reverse, backwards and so on.
  • If you hold down the "Z" button (the big one on the front). Your robot will now move based on the tilt of the nunchuck. Tilt forward to go forward...
  • Finally if it isn't quite working the program will send the state of the nunchucks buttons, joystick and accelerometers, every second over the Arduino's USB port. (just open the debug window at 9600 to see this data)

For those interested in simply getting it going.

Copy and Pasting
  • Copy the Arduino code from below
  • Paste it into the Arduino development environment.
  • upload and start playing

Using the Code in Your Own Program
  • First initialize the nunchuck by calling nunchuck_init ();
  • Next every time you wish to update the values of the nunchuck in your sketch call readNunchuck();
  • Next to directly access the values call getNunValue(Variable Constant); (ex. YAXIS)
  • Finally if you wish to use the accelerometer but have it scaled to a number of Gs (ie. 1 g = 1 force of gravity). you can call getXGs();, getYGs(); or getZGs();

Appendix 1 - _SERB_WiiNunchuckControl.pde


//START OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42 
//-------------------------------------------------
/*
 * Wiring Details
 * white  - ground
 * red    - 3.3+v  - 5 volts seems to work
 * green  - data   - Analog 4
 * yellow - clock  - Analog 5
 */

#include  #include   #undef int #include   uint8_t outbuf[6];		// array to store arduino output int cnt = 0;                    // counter used for nunchuck comunication int ledPin = 13;  int nunchuckValues[] = {0,0,0,0,0,0,0,0,0,0}; //An array to store the nuncheck values  /*  * The index of each value within the nunchuckValues[] array  * ie. XSTICK value is stored at nunchuckValues[XSTICK] (0)  */ #define XSTICK 0      //The joystick values      #define YSTICK 1 #define XAXIS 2       //The three accelerometer values      #define YAXIS 3         #define ZAXIS 4  #define ZBUTTON 5     //Front button values  (0 when pressed)   #define CBUTTON 6   #define XAXISDELTA 7  //Change in accelerometer data from last read; #define YAXISDELTA 8    #define ZAXISDELTA 9   //Nunchuck G calculating Constants /*  * For scaling the raw values from the nunchuck into G values  * Details on callibration and the maths can be found at  *    http://www.wiili.org/index.php/Motion_analysis  (Copied from http://www.wiili.org/index.php/Motion_analysis)      Zero Points        x_0 = (x_1 + x_2) / 2\,y_0 = (y_1 + y_3) / 2\,z_0 = (z_2 + z_3) / 2\,      One G points        x = \frac{x_{raw} - x_0}{x_3 - x_0}y = \frac{y_{raw} - y_0}{y_2 - y_0}z = \frac{z_{raw} - z_0}{z_1 - z_0} */  /* Not all of these are used and could be deleted (kept to make interpretting math's  * Easier 0-Zero G Value 1-Value when laying on table 2-Value when resting on nose  * 3-Value when resting on side (left side up) */ #define X0 500  #define X1 500 #define X2 500 #define X3 711  #define Y0 465 #define Y1 481 #define Y2 621 #define Y3 449  #define Z0 578 #define Z1 785 #define Z2 575 #define Z3 582  //END OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42  //------------------------------------------------------  //-------------------------------------------------------------------------- // START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE #include   #define LEFTSERVOPIN  10   #define RIGHTSERVOPIN  9  #define MAXSPEED 10  //due to the way continuous rotation servos work maximum speed is reached at a much lower value than 90 (this value will change depending on your servos) (for Parallax servos)  Servo leftServo;  Servo rightServo;   int leftSpeed = 100;  //sets the speed of the robot (left servos)                        //a percentage between -MAXSPEED and MAXSPEED int rightSpeed = 100;  //sets the speed of the robot (both servos)                        //a percentage between -MAXSPEED and MAXSPEED int speed = 100;      //used for simple control (goForward, goBackward, goLeft, and goRight                       //a percentage between 0 and MAXSPEED   // END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE //--------------------------------------------------------------------------  long lastPrint; //a long variable to store the time the wiimote state was last printed #define PRINTINTERVAL 1000  //the number of milliseconds between outputting the nunchuck state over the usb port #define DEADBAND 20         //A percentage away from center that is interpretted as still being zero   void setup(){   Serial.begin(9600);   //Starts the serial port (used for debuging however makes servos jumpy)   nunchuck_init ();     // send the nunchuck initilization handshake   serbSetup();         // adds the servos and prepares all SERB related variables   lastPrint = millis(); }   void loop(){   readNunchuck();       //Reads the current state of the nunchucks buttons and accelerometers   if(!getNunValue(ZBUTTON)){     moveWiiAcelerometer();            //moves the wii deoending on the nunchucks acceleration values    }else{     moveWiiJoystick();   }   if((millis() - lastPrint) > PRINTINTERVAL){  //If a second has passed since last printing nunchuck values print them     printData();          //print nunchuck values     Serial.println();     //add an enter     lastPrint = millis(); //store current time as lastPrint   }  }  void moveWiiAcelerometer(){  moveDifferential(getYGs() * (float)100,getXGs()*(float)100);  }  void moveWiiJoystick(){  moveDifferential(map(getNunValue(YSTICK),30,220,-100,100),map(getNunValue(XSTICK),30,220,-100,100));  }  //Takes in a speed and a direction input (like a joystick) and translates it to speed commands  void moveDifferential(int speed1, int direction1){   speed1 = deadBandFilter(speed1);   direction1 = deadBandFilter(direction1);   setSpeedLeft(speed1 + direction1);   setSpeedRight(speed1 - direction1); }  int deadBandFilter(int value){  if(value > -DEADBAND && value < DEADBAND){value = 0;}  else{    if(value > 0){value = value - DEADBAND * 100 / (100-DEADBAND);}    else{value = value + DEADBAND * 100 / (100-DEADBAND);}  }  return value;  }   //START OF NUNCHUCK ROUTINES //-------------------------------------------------------------------------------------------------------   //Calculates and returns the xAxis acceleration in Gs float getXGs(){   return ((float)getNunValue(XAXIS) - X0) / (X3 - X0); }  //Calculates and returns the yAxis acceleration in Gs float getYGs(){   return ((float)getNunValue(YAXIS) - Y0) / (Y2 - Y0); }  //Calculates and returns the zAxis acceleration in Gs float getZGs(){   return ((float)getNunValue(YAXIS) - Z0) / (Z1 - Z0);   }  //START OF NUNCHUCK Reading CODE - For more in depth information please visit the original source  //of this code http://www.windmeadow.com/node/42  //--------------------------------------------------------------- void readNunchuck(){   Wire.requestFrom (0x52, 6);	// request data from nunchuck   while (Wire.available ()) {       outbuf[cnt] = nunchuk_decode_byte (Wire.receive ());	// receive byte as an integer       digitalWrite (ledPin, HIGH);	// sets the LED on       cnt++;     }    // If we recieved the 6 bytes, then go print them   if (cnt >= 5) {         nunchuckValues[XSTICK] = outbuf[0];         nunchuckValues[YSTICK] = outbuf[1];         int tempNun_xAxis = outbuf[2] * 2 * 2;          int tempNun_yAxis = outbuf[3] * 2 * 2;           int tempNun_zAxis = outbuf[4] * 2 * 2;         nunchuckValues[ZBUTTON] = 0;
nunchuckValues[CBUTTON] = 0;

// byte outbuf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((outbuf[5] >> 0) & 1) { nunchuckValues[ZBUTTON] = 1; } //checking if Z button is pressed (0=pressed 1=unpressed)
if ((outbuf[5] >> 1) & 1) { nunchuckValues[CBUTTON] = 1; } //checking if C button is pressed (0=pressed 1=unpressed)
if ((outbuf[5] >> 2) & 1) { tempNun_xAxis += 2; } //adding second least significant bit to x_axis
if ((outbuf[5] >> 3) & 1) { tempNun_xAxis += 1; } //adding least significant bit to x_axis
if ((outbuf[5] >> 4) & 1) { tempNun_yAxis += 2; } //adding second least significant bit to y_axis
if ((outbuf[5] >> 5) & 1) { tempNun_yAxis += 1; } //adding least significant bit to x_axis
if ((outbuf[5] >> 6) & 1) { tempNun_zAxis += 2; } //adding second least significant bit to z_axis
if ((outbuf[5] >> 7) & 1) { tempNun_zAxis += 1; } ////adding least significant bit to x_axis

nunchuckValues[XAXISDELTA] = tempNun_xAxis - nunchuckValues[XAXIS];
nunchuckValues[XAXIS] = tempNun_xAxis;
nunchuckValues[YAXISDELTA] = tempNun_yAxis - nunchuckValues[YAXIS];
nunchuckValues[YAXIS] = tempNun_yAxis;
nunchuckValues[ZAXISDELTA] = tempNun_zAxis - nunchuckValues[ZAXIS];
nunchuckValues[ZAXIS] = tempNun_zAxis;
}
cnt = 0;
send_zero (); // send the request for next bytes
}

int getNunValue(int valueIndex){
return nunchuckValues[valueIndex];
}

void nunchuck_init (){
Wire.begin (); // join i2c bus with address 0x52
Wire.beginTransmission (0x52); // transmit to device 0x52
Wire.send (0x40); // sends memory address
Wire.send (0x00); // sends sent a zero.
Wire.endTransmission (); // stop transmitting
}

void send_zero () {
Wire.beginTransmission (0x52); // transmit to device 0x52
Wire.send (0x00); // sends one byte
Wire.endTransmission (); // stop transmitting
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x) {
x = (x ^ 0x17) + 0x17;
return x;
}

//END OF NUNCHUCK CODE - For more in depth information please visit the
//original source of this code http://www.windmeadow.com/node/42
//---------------------------------------------------------------

//------------------------------------------------------------------------
//START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES

/*
* sets up your arduino to address your SERB using the included routines
*/
void serbSetup(){
setSpeed(speed);
pinMode(LEFTSERVOPIN, OUTPUT); //sets the left servo signal pin
//to output
pinMode(RIGHTSERVOPIN, OUTPUT); //sets the right servo signal pin
//to output
leftServo.attach(LEFTSERVOPIN); //attaches left servo
rightServo.attach(RIGHTSERVOPIN); //attaches right servo
goStop();
}


/*
* sets the speed of the robot between 0-(stopped) and 100-(full speed)
* NOTE: speed will not change the current speed you must change speed
* then call one of the go methods before changes occur.
*/
void setSpeed(int newSpeed){
if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
//make it 100
if(newSpeed <= 0) {newSpeed = 0;} //if speed is less than 0 make
//it 0
speed = newSpeed * MAXSPEED / 100; //scales the speed to be
//between 0 and MAXSPEED
}

/*
* sets the speed of the robots rightServo between -100-(reversed) and 100-(forward)
* NOTE: calls to this routine will take effect imediatly
*/
void setSpeedRight(int newSpeed){
if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
//make it 100
if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
//it -100
rightSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
//between -MAXSPEED and MAXSPEED
rightServo.write(90 - rightSpeed); //sends the new value to the servo
}

/*
* sets the speed of the robots leftServo between -100-(reversed) and 100-(forward)
* NOTE: calls to this routine will take effect imediatly
*/
void setSpeedLeft(int newSpeed){
if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
//make it 100
if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
//it -100
leftSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
//between -MAXSPEED and MAXSPEED
leftServo.write(90 + leftSpeed); //sends the new value to the servo
}

/*
* sends the robot forwards
*/
void goForward(){
leftServo.write(90 + speed);
rightServo.write(90 - speed);
}

/*
* sends the robot backwards
*/
void goBackward(){
leftServo.write(90 - speed);
rightServo.write(90 + speed);
}

/*
* sends the robot right
*/
void goRight(){
leftServo.write(90 + speed);
rightServo.write(90 + speed);
}

/*
* sends the robot left
*/
void goLeft(){
leftServo.write(90 - speed);
rightServo.write(90 - speed);
}

/*
* stops the robot
*/
void goStop(){
leftServo.write(90);
rightServo.write(90);
}
//END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES
//---------------------------------------------------------------------------


//START OF PRINT ROUTINES (can delete if not using)
//---------------------------------------------------------------

//Prints the Nunchucks last read data (must call NUN_readNunchuck(); before calling
void printData(){
Serial.print("XJoy= ");Serial.print (getNunValue(XSTICK), DEC); Serial.print ("\t");
Serial.print("YJoy= ");Serial.print (getNunValue(YSTICK), DEC); Serial.print ("\t");
Serial.print("XGs= ");Serial.print (getXGs() * 1000, DEC); Serial.print ("\t");
Serial.print("YGs= ");Serial.print (getYGs() * 1000, DEC); Serial.print ("\t");
Serial.print("ZGs= ");Serial.print (getZGs() * 1000, DEC); Serial.print ("\t");
Serial.print("ZBut= ");Serial.print (getNunValue(ZBUTTON), DEC); Serial.print ("\t");
Serial.print("YBut= ");Serial.print (getNunValue(CBUTTON), DEC); Serial.print ("\t");
}

//END OF PRINT ROUTINES
//--------------------------------------------------------------------

Step 4: Finished

I hope you've gotten it working and are having fun tilting and driving.

If its not quite working leave a message or send us an e-mail at help@oomlout.com and we'll try our best to help you get it working.

(shameless plug)
For more fun open source projects try visiting us at oomlout.com

Share

    Recommendations

    • Fix It! Contest

      Fix It! Contest
    • Creative Misuse Contest

      Creative Misuse Contest
    • Metalworking Contest

      Metalworking Contest

    53 Discussions

    Links still down

    What I want to know is where did you get the o-rings for the robot. I want to build this one, thanks

    larystoy

    sir how can i downloads using nunchuck to control robot

    Hi there, I am recently working on this project. I've built my own servo bot, and I'm currently trying to get my wii nunchuck controlled SERB to work by following your instructables, but it doesn't seem to work. I followed the wiring of the project, and the robot runs when I upload the SERB test code and run it, however, once I upload the code for the nunchuck, both servos immediately run in the same direction continuously, and that's all that it will do, pressing buttons or moving the joystick around on the nunchuck does not do anything to the servos. I used the code posted here http://oomlout.com/tmp/SERB_WiiNunChuckControl.txt (I did fix some syntactical errors, so it compiles fine.) I was wondering if it is a wiring problem? (Using the wired nunchuck, green goes to analog 4 and yellow to analog 5, red goes to arduino 5v and white to gnu).

    I am also currently using futaba s3003 servos, which arent continuous rotation servos (but I've cut the bit that stops it from turning 360 degrees, and I'm not sure if this is the problem, since the robot works well when another code is uploaded).

    I'm currently having some trouble here, so it would be great if you could fix this problem for me. Thanks loads!!

    //START OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42
    //-------------------------------------------------
    /*
    * Wiring Details
    * white - ground
    * red - 3.3+v - 5 volts seems to work
    * green - data - Analog 4
    * yellow - clock - Analog 5
    */

    #include
    #include

    #undef int
    #include

    uint8_t outbuf[6]; // array to store arduino output
    int cnt = 0; // counter used for nunchuck comunication
    int ledPin = 13;

    int nunchuckValues[] = {0,0,0,0,0,0,0,0,0,0}; //An array to store the nuncheck values

    /*
    * The index of each value within the nunchuckValues[] array
    * ie. XSTICK value is stored at nunchuckValues[XSTICK] (0)
    */
    #define XSTICK 0 //The joystick values
    #define YSTICK 1
    #define XAXIS 2 //The three accelerometer values
    #define YAXIS 3
    #define ZAXIS 4
    #define ZBUTTON 5 //Front button values (0 when pressed)
    #define CBUTTON 6
    #define XAXISDELTA 7 //Change in accelerometer data from last read;
    #define YAXISDELTA 8
    #define ZAXISDELTA 9

    //Nunchuck G calculating Constants
    /*
    * For scaling the raw values from the nunchuck into G values
    * Details on callibration and the maths can be found at
    * http://www.wiili.org/index.php/Motion_analysis
    (Copied from http://www.wiili.org/index.php/Motion_analysis)
    Zero Points
    x_0 = (x_1 + x_2) / 2\,
    y_0 = (y_1 + y_3) / 2\,
    z_0 = (z_2 + z_3) / 2\,
    One G points
    x = \frac{x_{raw} - x_0}{x_3 - x_0}
    y = \frac{y_{raw} - y_0}{y_2 - y_0}
    z = \frac{z_{raw} - z_0}{z_1 - z_0}
    */

    /* Not all of these are used and could be deleted (kept to make interpretting math's
    * Easier 0-Zero G Value 1-Value when laying on table 2-Value when resting on nose
    * 3-Value when resting on side (left side up)
    */
    #define X0 500
    #define X1 500
    #define X2 500
    #define X3 711

    #define Y0 465
    #define Y1 481
    #define Y2 621
    #define Y3 449

    #define Z0 578
    #define Z1 785
    #define Z2 575
    #define Z3 582

    //END OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42
    //------------------------------------------------------

    //--------------------------------------------------------------------------
    // START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE
    #include

    #define LEFTSERVOPIN 10
    #define RIGHTSERVOPIN 9

    #define MAXSPEED 10 //due to the way continuous rotation servos work maximum speed is reached at a much lower value than 90 (this value will change depending on your servos) (for Parallax servos)

    Servo leftServo;
    Servo rightServo;

    int leftSpeed = 100; //sets the speed of the robot (left servos)
    //a percentage between -MAXSPEED and MAXSPEED
    int rightSpeed = 100; //sets the speed of the robot (both servos)
    //a percentage between -MAXSPEED and MAXSPEED
    int speed = 100; //used for simple control (goForward, goBackward, goLeft, and goRight
    //a percentage between 0 and MAXSPEED


    // END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE
    //--------------------------------------------------------------------------

    long lastPrint; //a long variable to store the time the wiimote state was last printed
    #define PRINTINTERVAL 1000 //the number of milliseconds between outputting the nunchuck state over the usb port
    #define DEADBAND 20 //A percentage away from center that is interpretted as still being zero


    void setup(){
    Serial.begin(9600); //Starts the serial port (used for debuging however makes servos jumpy)
    nunchuck_init (); // send the nunchuck initilization handshake
    serbSetup(); // adds the servos and prepares all SERB related variables
    lastPrint = millis();
    }


    void loop(){
    readNunchuck(); //Reads the current state of the nunchucks buttons and accelerometers
    if(!getNunValue(ZBUTTON)){
    moveWiiAcelerometer(); //moves the wii deoending on the nunchucks acceleration values
    }else{
    moveWiiJoystick();
    }
    if((millis() - lastPrint) > PRINTINTERVAL){ //If a second has passed since last printing nunchuck values print them
    printData(); //print nunchuck values
    Serial.println(); //add an enter
    lastPrint = millis(); //store current time as lastPrint
    }

    }

    void moveWiiAcelerometer(){
    moveDifferential(getYGs() * (float)100,getXGs()*(float)100);
    }

    void moveWiiJoystick(){
    moveDifferential(map(getNunValue(YSTICK),30,220,-100,100),map(getNunValue(XSTICK),30,220,-100,100));
    }

    //Takes in a speed and a direction input (like a joystick) and translates it to speed commands
    void moveDifferential(int speed1, int direction1){
    speed1 = deadBandFilter(speed1);
    direction1 = deadBandFilter(direction1);
    setSpeedLeft(speed1 + direction1);
    setSpeedRight(speed1 - direction1);
    }

    int deadBandFilter(int value){
    if(value > -DEADBAND && value < DEADBAND){value = 0;}
    else{
    if(value > 0){value = value - DEADBAND * 100 / (100-DEADBAND);}
    else{value = value + DEADBAND * 100 / (100-DEADBAND);}
    }
    return value;
    }


    //START OF NUNCHUCK ROUTINES
    //-------------------------------------------------------------------------------------------------------


    //Calculates and returns the xAxis acceleration in Gs
    float getXGs(){
    return ((float)getNunValue(XAXIS) - X0) / (X3 - X0);
    }

    //Calculates and returns the yAxis acceleration in Gs
    float getYGs(){
    return ((float)getNunValue(YAXIS) - Y0) / (Y2 - Y0);
    }

    //Calculates and returns the zAxis acceleration in Gs
    float getZGs(){
    return ((float)getNunValue(YAXIS) - Z0) / (Z1 - Z0);
    }

    //START OF NUNCHUCK Reading CODE - For more in depth information please visit the original source
    //of this code http://www.windmeadow.com/node/42
    //---------------------------------------------------------------
    void readNunchuck(){
    Wire.requestFrom (0x52, 6); // request data from nunchuck
    while (Wire.available ()) {
    outbuf[cnt] = nunchuk_decode_byte (Wire.read()); // receive byte as an integer
    digitalWrite (ledPin, HIGH); // sets the LED on
    cnt++;
    }

    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5) {
    nunchuckValues[XSTICK] = outbuf[0];
    nunchuckValues[YSTICK] = outbuf[1];
    int tempNun_xAxis = outbuf[2] * 2 * 2;
    int tempNun_yAxis = outbuf[3] * 2 * 2;
    int tempNun_zAxis = outbuf[4] * 2 * 2;
    nunchuckValues[ZBUTTON] = 0;
    nunchuckValues[CBUTTON] = 0;

    // byte outbuf[5] contains bits for z and c buttons
    // it also contains the least significant bits for the accelerometer data
    // so we have to check each bit of byte outbuf[5]
    if ((outbuf[5] >> 0) & 1) { nunchuckValues[ZBUTTON] = 1; } //checking if Z button is pressed (0=pressed 1=unpressed)
    if ((outbuf[5] >> 1) & 1) { nunchuckValues[CBUTTON] = 1; } //checking if C button is pressed (0=pressed 1=unpressed)
    if ((outbuf[5] >> 2) & 1) { tempNun_xAxis += 2; } //adding second least significant bit to x_axis
    if ((outbuf[5] >> 3) & 1) { tempNun_xAxis += 1; } //adding least significant bit to x_axis
    if ((outbuf[5] >> 4) & 1) { tempNun_yAxis += 2; } //adding second least significant bit to y_axis
    if ((outbuf[5] >> 5) & 1) { tempNun_yAxis += 1; } //adding least significant bit to x_axis
    if ((outbuf[5] >> 6) & 1) { tempNun_zAxis += 2; } //adding second least significant bit to z_axis
    if ((outbuf[5] >> 7) & 1) { tempNun_zAxis += 1; } ////adding least significant bit to x_axis

    nunchuckValues[XAXISDELTA] = tempNun_xAxis - nunchuckValues[XAXIS];
    nunchuckValues[XAXIS] = tempNun_xAxis;
    nunchuckValues[YAXISDELTA] = tempNun_yAxis - nunchuckValues[YAXIS];
    nunchuckValues[YAXIS] = tempNun_yAxis;
    nunchuckValues[ZAXISDELTA] = tempNun_zAxis - nunchuckValues[ZAXIS];
    nunchuckValues[ZAXIS] = tempNun_zAxis;
    }
    cnt = 0;
    send_zero (); // send the request for next bytes
    }

    int getNunValue(int valueIndex){
    return nunchuckValues[valueIndex];
    }

    void nunchuck_init (){
    Wire.begin (); // join i2c bus with address 0x52
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.write (0x40); // sends memory address
    Wire.write (0x00); // sends sent a zero.
    Wire.endTransmission (); // stop transmitting
    }

    void send_zero () {
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.write (0x00); // sends one byte
    Wire.endTransmission (); // stop transmitting
    }

    // Encode data to format that most wiimote drivers except
    // only needed if you use one of the regular wiimote drivers
    char nunchuk_decode_byte (char x) {
    x = (x ^ 0x17) + 0x17;
    return x;
    }

    //END OF NUNCHUCK CODE - For more in depth information please visit the
    //original source of this code http://www.windmeadow.com/node/42
    //---------------------------------------------------------------

    //------------------------------------------------------------------------
    //START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES

    /*
    * sets up your arduino to address your SERB using the included routines
    */
    void serbSetup(){
    setSpeed(speed);
    pinMode(LEFTSERVOPIN, OUTPUT); //sets the left servo signal pin
    //to output
    pinMode(RIGHTSERVOPIN, OUTPUT); //sets the right servo signal pin
    //to output
    leftServo.attach(LEFTSERVOPIN); //attaches left servo
    rightServo.attach(RIGHTSERVOPIN); //attaches right servo
    goStop();
    }


    /*
    * sets the speed of the robot between 0-(stopped) and 100-(full speed)
    * NOTE: speed will not change the current speed you must change speed
    * then call one of the go methods before changes occur.
    */
    void setSpeed(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= 0) {newSpeed = 0;} //if speed is less than 0 make
    //it 0
    speed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between 0 and MAXSPEED
    }

    /*
    * sets the speed of the robots rightServo between -100-(reversed) and 100-(forward)
    * NOTE: calls to this routine will take effect imediatly
    */
    void setSpeedRight(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
    //it -100
    rightSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between -MAXSPEED and MAXSPEED
    rightServo.write(90 - rightSpeed); //sends the new value to the servo
    }

    /*
    * sets the speed of the robots leftServo between -100-(reversed) and 100-(forward)
    * NOTE: calls to this routine will take effect imediatly
    */
    void setSpeedLeft(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
    //it -100
    leftSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between -MAXSPEED and MAXSPEED
    leftServo.write(90 + leftSpeed); //sends the new value to the servo
    }

    /*
    * sends the robot forwards
    */
    void goForward(){
    leftServo.write(90 + speed);
    rightServo.write(90 - speed);
    }

    /*
    * sends the robot backwards
    */
    void goBackward(){
    leftServo.write(90 - speed);
    rightServo.write(90 + speed);
    }

    /*
    * sends the robot right
    */
    void goRight(){
    leftServo.write(90 + speed);
    rightServo.write(90 + speed);
    }

    /*
    * sends the robot left
    */
    void goLeft(){
    leftServo.write(90 - speed);
    rightServo.write(90 - speed);
    }

    /*
    * stops the robot
    */
    void goStop(){
    leftServo.write(90);
    rightServo.write(90);
    }
    //END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES
    //---------------------------------------------------------------------------


    //START OF PRINT ROUTINES (can delete if not using)
    //---------------------------------------------------------------

    //Prints the Nunchucks last read data (must call NUN_readNunchuck(); before calling
    void printData(){
    Serial.print("XJoy= ");Serial.print (getNunValue(XSTICK), DEC); Serial.print ("\t");
    Serial.print("YJoy= ");Serial.print (getNunValue(YSTICK), DEC); Serial.print ("\t");
    Serial.print("XGs= ");Serial.print (getXGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("YGs= ");Serial.print (getYGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("ZGs= ");Serial.print (getZGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("ZBut= ");Serial.print (getNunValue(ZBUTTON), DEC); Serial.print ("\t");
    Serial.print("YBut= ");Serial.print (getNunValue(CBUTTON), DEC); Serial.print ("\t");
    }

    //END OF PRINT ROUTINES
    //--------------------------------------------------------------------

    #include
    #include

    #undef int
    #include

    uint8_t outbuf[6]; // array to store arduino output
    int cnt = 0;
    int ledPin = 13;

    void
    setup ()
    {
    beginSerial (19200);
    Serial.print ("Finished setup\n");
    Wire.begin (); // join i2c bus with address 0x52
    nunchuck_init (); // send the initilization handshake
    }

    void
    nunchuck_init ()
    {
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.send (0x40); // sends memory address
    Wire.send (0x00); // sends sent a zero.
    Wire.endTransmission (); // stop transmitting
    }

    void
    send_zero ()
    {
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.send (0x00); // sends one byte
    Wire.endTransmission (); // stop transmitting
    }

    void
    loop ()
    {
    Wire.requestFrom (0x52, 6); // request data from nunchuck
    while (Wire.available ())
    {
    outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
    digitalWrite (ledPin, HIGH); // sets the LED on
    cnt++;
    }

    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5)
    {
    print ();
    }

    cnt = 0;
    send_zero (); // send the request for next bytes
    delay (100);
    }

    // Print the input data we have recieved
    // accel data is 10 bits long
    // so we read 8 bits, then we have to add
    // on the last 2 bits. That is why I
    // multiply them by 2 * 2
    void
    print ()
    {
    int joy_x_axis = outbuf[0];
    int joy_y_axis = outbuf[1];
    int accel_x_axis = outbuf[2] * 2 * 2;
    int accel_y_axis = outbuf[3] * 2 * 2;
    int accel_z_axis = outbuf[4] * 2 * 2;

    int z_button = 0;
    int c_button = 0;

    // byte outbuf[5] contains bits for z and c buttons
    // it also contains the least significant bits for the accelerometer data
    // so we have to check each bit of byte outbuf[5]
    if ((outbuf[5] >> 0) & 1)
    {
    z_button = 1;
    }
    if ((outbuf[5] >> 1) & 1)
    {
    c_button = 1;
    }

    if ((outbuf[5] >> 2) & 1)
    {
    accel_x_axis += 2;
    }
    if ((outbuf[5] >> 3) & 1)
    {
    accel_x_axis += 1;
    }

    if ((outbuf[5] >> 4) & 1)
    {
    accel_y_axis += 2;
    }
    if ((outbuf[5] >> 5) & 1)
    {
    accel_y_axis += 1;
    }

    if ((outbuf[5] >> 6) & 1)
    {
    accel_z_axis += 2;
    }
    if ((outbuf[5] >> 7) & 1)
    {
    accel_z_axis += 1;
    }

    Serial.print (joy_x_axis, DEC);
    Serial.print ("\t");

    Serial.print (joy_y_axis, DEC);
    Serial.print ("\t");

    Serial.print (accel_x_axis, DEC);
    Serial.print ("\t");

    Serial.print (accel_y_axis, DEC);
    Serial.print ("\t");

    Serial.print (accel_z_axis, DEC);
    Serial.print ("\t");

    Serial.print (z_button, DEC);
    Serial.print ("\t");

    Serial.print (c_button, DEC);
    Serial.print ("\t");

    Serial.print ("\r\n");
    }

    // Encode data to format that most wiimote drivers except
    // only needed if you use one of the regular wiimote drivers
    char
    nunchuk_decode_byte (char x)
    {
    x = (x ^ 0x17) + 0x17;
    return x;
    }

    //START OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42
    //-------------------------------------------------
    /*
    * Wiring Details
    * white - ground
    * red - 3.3+v - 5 volts seems to work
    * green - data - Analog 4
    * yellow - clock - Analog 5
    */

    #include
    #include

    #undef int
    #include

    uint8_t outbuf[6]; // array to store arduino output
    int cnt = 0; // counter used for nunchuck comunication
    int ledPin = 13;

    int nunchuckValues[] = {0,0,0,0,0,0,0,0,0,0}; //An array to store the nuncheck values

    /*
    * The index of each value within the nunchuckValues[] array
    * ie. XSTICK value is stored at nunchuckValues[XSTICK] (0)
    */
    #define XSTICK 0 //The joystick values
    #define YSTICK 1
    #define XAXIS 2 //The three accelerometer values
    #define YAXIS 3
    #define ZAXIS 4
    #define ZBUTTON 5 //Front button values (0 when pressed)
    #define CBUTTON 6
    #define XAXISDELTA 7 //Change in accelerometer data from last read;
    #define YAXISDELTA 8
    #define ZAXISDELTA 9

    //Nunchuck G calculating Constants
    /*
    * For scaling the raw values from the nunchuck into G values
    * Details on callibration and the maths can be found at
    * http://www.wiili.org/index.php/Motion_analysis
    (Copied from http://www.wiili.org/index.php/Motion_analysis)
    Zero Points
    x_0 = (x_1 + x_2) / 2\,
    y_0 = (y_1 + y_3) / 2\,
    z_0 = (z_2 + z_3) / 2\,
    One G points
    x = \frac{x_{raw} - x_0}{x_3 - x_0}
    y = \frac{y_{raw} - y_0}{y_2 - y_0}
    z = \frac{z_{raw} - z_0}{z_1 - z_0}
    */

    /* Not all of these are used and could be deleted (kept to make interpretting math's
    * Easier 0-Zero G Value 1-Value when laying on table 2-Value when resting on nose
    * 3-Value when resting on side (left side up)
    */
    #define X0 500
    #define X1 500
    #define X2 500
    #define X3 711

    #define Y0 465
    #define Y1 481
    #define Y2 621
    #define Y3 449

    #define Z0 578
    #define Z1 785
    #define Z2 575
    #define Z3 582

    //END OF NUNCHUCK PREAMBLE - For more in depth information please visit the original source of this code http://www.windmeadow.com/node/42
    //------------------------------------------------------

    //--------------------------------------------------------------------------
    // START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE
    #include

    #define LEFTSERVOPIN 10
    #define RIGHTSERVOPIN 9

    #define MAXSPEED 10 //due to the way continuous rotation servos work maximum speed is reached at a much lower value than 90 (this value will change depending on your servos) (for Parallax servos)

    Servo leftServo;
    Servo rightServo;

    int leftSpeed = 100; //sets the speed of the robot (left servos)
    //a percentage between -MAXSPEED and MAXSPEED
    int rightSpeed = 100; //sets the speed of the robot (both servos)
    //a percentage between -MAXSPEED and MAXSPEED
    int speed = 100; //used for simple control (goForward, goBackward, goLeft, and goRight
    //a percentage between 0 and MAXSPEED


    // END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE
    //--------------------------------------------------------------------------

    long lastPrint; //a long variable to store the time the wiimote state was last printed
    #define PRINTINTERVAL 1000 //the number of milliseconds between outputting the nunchuck state over the usb port
    #define DEADBAND 20 //A percentage away from center that is interpretted as still being zero


    void setup(){
    Serial.begin(9600); //Starts the serial port (used for debuging however makes servos jumpy)
    nunchuck_init (); // send the nunchuck initilization handshake
    serbSetup(); // adds the servos and prepares all SERB related variables
    lastPrint = millis();
    }


    void loop(){
    readNunchuck(); //Reads the current state of the nunchucks buttons and accelerometers
    if(!getNunValue(ZBUTTON)){
    moveWiiAcelerometer(); //moves the wii deoending on the nunchucks acceleration values
    }else{
    moveWiiJoystick();
    }
    if((millis() - lastPrint) > PRINTINTERVAL){ //If a second has passed since last printing nunchuck values print them
    printData(); //print nunchuck values
    Serial.println(); //add an enter
    lastPrint = millis(); //store current time as lastPrint
    }

    }

    void moveWiiAcelerometer(){
    moveDifferential(getYGs() * (float)100,getXGs()*(float)100);
    }

    void moveWiiJoystick(){
    moveDifferential(map(getNunValue(YSTICK),30,220,-100,100),map(getNunValue(XSTICK),30,220,-100,100));
    }

    //Takes in a speed and a direction input (like a joystick) and translates it to speed commands
    void moveDifferential(int speed1, int direction1){
    speed1 = deadBandFilter(speed1);
    direction1 = deadBandFilter(direction1);
    setSpeedLeft(speed1 + direction1);
    setSpeedRight(speed1 - direction1);
    }

    int deadBandFilter(int value){
    if(value > -DEADBAND && value < DEADBAND){value = 0;}
    else{
    if(value > 0){value = value - DEADBAND * 100 / (100-DEADBAND);}
    else{value = value + DEADBAND * 100 / (100-DEADBAND);}
    }
    return value;
    }


    //START OF NUNCHUCK ROUTINES
    //-------------------------------------------------------------------------------------------------------


    //Calculates and returns the xAxis acceleration in Gs
    float getXGs(){
    return ((float)getNunValue(XAXIS) - X0) / (X3 - X0);
    }

    //Calculates and returns the yAxis acceleration in Gs
    float getYGs(){
    return ((float)getNunValue(YAXIS) - Y0) / (Y2 - Y0);
    }

    //Calculates and returns the zAxis acceleration in Gs
    float getZGs(){
    return ((float)getNunValue(YAXIS) - Z0) / (Z1 - Z0);
    }

    //START OF NUNCHUCK Reading CODE - For more in depth information please visit the original source
    //of this code http://www.windmeadow.com/node/42
    //---------------------------------------------------------------
    void readNunchuck(){
    Wire.requestFrom (0x52, 6); // request data from nunchuck
    while (Wire.available ()) {
    outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
    digitalWrite (ledPin, HIGH); // sets the LED on
    cnt++;
    }

    // If we recieved the 6 bytes, then go print them
    if (cnt >= 5) {
    nunchuckValues[XSTICK] = outbuf[0];
    nunchuckValues[YSTICK] = outbuf[1];
    int tempNun_xAxis = outbuf[2] * 2 * 2;
    int tempNun_yAxis = outbuf[3] * 2 * 2;
    int tempNun_zAxis = outbuf[4] * 2 * 2;
    nunchuckValues[ZBUTTON] = 0;
    nunchuckValues[CBUTTON] = 0;

    // byte outbuf[5] contains bits for z and c buttons
    // it also contains the least significant bits for the accelerometer data
    // so we have to check each bit of byte outbuf[5]
    if ((outbuf[5] >> 0) & 1) { nunchuckValues[ZBUTTON] = 1; } //checking if Z button is pressed (0=pressed 1=unpressed)
    if ((outbuf[5] >> 1) & 1) { nunchuckValues[CBUTTON] = 1; } //checking if C button is pressed (0=pressed 1=unpressed)
    if ((outbuf[5] >> 2) & 1) { tempNun_xAxis += 2; } //adding second least significant bit to x_axis
    if ((outbuf[5] >> 3) & 1) { tempNun_xAxis += 1; } //adding least significant bit to x_axis
    if ((outbuf[5] >> 4) & 1) { tempNun_yAxis += 2; } //adding second least significant bit to y_axis
    if ((outbuf[5] >> 5) & 1) { tempNun_yAxis += 1; } //adding least significant bit to x_axis
    if ((outbuf[5] >> 6) & 1) { tempNun_zAxis += 2; } //adding second least significant bit to z_axis
    if ((outbuf[5] >> 7) & 1) { tempNun_zAxis += 1; } ////adding least significant bit to x_axis

    nunchuckValues[XAXISDELTA] = tempNun_xAxis - nunchuckValues[XAXIS];
    nunchuckValues[XAXIS] = tempNun_xAxis;
    nunchuckValues[YAXISDELTA] = tempNun_yAxis - nunchuckValues[YAXIS];
    nunchuckValues[YAXIS] = tempNun_yAxis;
    nunchuckValues[ZAXISDELTA] = tempNun_zAxis - nunchuckValues[ZAXIS];
    nunchuckValues[ZAXIS] = tempNun_zAxis;
    }
    cnt = 0;
    send_zero (); // send the request for next bytes
    }

    int getNunValue(int valueIndex){
    return nunchuckValues[valueIndex];
    }

    void nunchuck_init (){
    Wire.begin (); // join i2c bus with address 0x52
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.send (0x40); // sends memory address
    Wire.send (0x00); // sends sent a zero.
    Wire.endTransmission (); // stop transmitting
    }

    void send_zero () {
    Wire.beginTransmission (0x52); // transmit to device 0x52
    Wire.send (0x00); // sends one byte
    Wire.endTransmission (); // stop transmitting
    }

    // Encode data to format that most wiimote drivers except
    // only needed if you use one of the regular wiimote drivers
    char nunchuk_decode_byte (char x) {
    x = (x ^ 0x17) + 0x17;
    return x;
    }

    //END OF NUNCHUCK CODE - For more in depth information please visit the
    //original source of this code http://www.windmeadow.com/node/42
    //---------------------------------------------------------------

    //------------------------------------------------------------------------
    //START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES

    /*
    * sets up your arduino to address your SERB using the included routines
    */
    void serbSetup(){
    setSpeed(speed);
    pinMode(LEFTSERVOPIN, OUTPUT); //sets the left servo signal pin
    //to output
    pinMode(RIGHTSERVOPIN, OUTPUT); //sets the right servo signal pin
    //to output
    leftServo.attach(LEFTSERVOPIN); //attaches left servo
    rightServo.attach(RIGHTSERVOPIN); //attaches right servo
    goStop();
    }


    /*
    * sets the speed of the robot between 0-(stopped) and 100-(full speed)
    * NOTE: speed will not change the current speed you must change speed
    * then call one of the go methods before changes occur.
    */
    void setSpeed(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= 0) {newSpeed = 0;} //if speed is less than 0 make
    //it 0
    speed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between 0 and MAXSPEED
    }

    /*
    * sets the speed of the robots rightServo between -100-(reversed) and 100-(forward)
    * NOTE: calls to this routine will take effect imediatly
    */
    void setSpeedRight(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
    //it -100
    rightSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between -MAXSPEED and MAXSPEED
    rightServo.write(90 - rightSpeed); //sends the new value to the servo
    }

    /*
    * sets the speed of the robots leftServo between -100-(reversed) and 100-(forward)
    * NOTE: calls to this routine will take effect imediatly
    */
    void setSpeedLeft(int newSpeed){
    if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100
    //make it 100
    if(newSpeed <= -100) {newSpeed = -100;} //if speed is less than -100 make
    //it -100
    leftSpeed = newSpeed * MAXSPEED / 100; //scales the speed to be
    //between -MAXSPEED and MAXSPEED
    leftServo.write(90 + leftSpeed); //sends the new value to the servo
    }

    /*
    * sends the robot forwards
    */
    void goForward(){
    leftServo.write(90 + speed);
    rightServo.write(90 - speed);
    }

    /*
    * sends the robot backwards
    */
    void goBackward(){
    leftServo.write(90 - speed);
    rightServo.write(90 + speed);
    }

    /*
    * sends the robot right
    */
    void goRight(){
    leftServo.write(90 + speed);
    rightServo.write(90 + speed);
    }

    /*
    * sends the robot left
    */
    void goLeft(){
    leftServo.write(90 - speed);
    rightServo.write(90 - speed);
    }

    /*
    * stops the robot
    */
    void goStop(){
    leftServo.write(90);
    rightServo.write(90);
    }
    //END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES
    //---------------------------------------------------------------------------


    //START OF PRINT ROUTINES (can delete if not using)
    //---------------------------------------------------------------

    //Prints the Nunchucks last read data (must call NUN_readNunchuck(); before calling
    void printData(){
    Serial.print("XJoy= ");Serial.print (getNunValue(XSTICK), DEC); Serial.print ("\t");
    Serial.print("YJoy= ");Serial.print (getNunValue(YSTICK), DEC); Serial.print ("\t");
    Serial.print("XGs= ");Serial.print (getXGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("YGs= ");Serial.print (getYGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("ZGs= ");Serial.print (getZGs() * 1000, DEC); Serial.print ("\t");
    Serial.print("ZBut= ");Serial.print (getNunValue(ZBUTTON), DEC); Serial.print ("\t");
    Serial.print("YBut= ");Serial.print (getNunValue(CBUTTON), DEC); Serial.print ("\t");
    }

    //END OF PRINT ROUTINES
    //--------------------------------------------------------------------

    If you are using Arduino 1.0 IDE you will have to change some commands. The error codes will tell you which ones. Also the code doesn't specify some registers, you'll have to plug those in yourself. Good luck.

    Is the code posted alright? Im thinking of doing this but i dont want to buy the stuff until i know its alright.

    2 replies

    This is an awesome guide!! Thanks oomlout and also thanks to carlosanchez for providing the uncorupted code :P I will definantly link to this in the instructable I make with my nunchuck :D

    i think that the next logical step would be hide an xbee, a rechargeable battery, and charging circuit to make a wireless version

    Is the kit no longer available? when i try to go to the l "purchase a lovely kit" link it does not work.

    why would you want to use the 5v if there's a 3v3 (3.3v) on the arduino beside the reset and 5v?