WiiNunchuck controlling two servos (X,Y axis).

All, It has been some time since I have posted on a similar subject. But today I had a breakthrough. I'm currently working on a Predator Costume and wanted to use a WiiNunchuck to control a shoulder mounted Cannon for automatic tracking and manual modes. I basically updated and reworked older code (cited to proper creators) for using 4 servos. I plan to remove the accelerometer and mount it in the Predator BioMask and have the joystick on my arm armor. When I can, I will post progress.

Here's what you get. The WiiNunchuck Accelerometers control the movement of two servos connected; one for X Axis and one for Y Axis. When the Z Button is pressed an held, the WiiNunchuck Joystick takes control of the servos for movement (using and if/else statement) until it is released. When the C Button is held, an LED attached to pin 8 will be HIGH (Simulate a laser pulse from front of cannon). It still needs some tweaking (pulse width and movement) but it works. If I find tweaks that improve it, I will share. I also noted I need to reverse the X and Y axis values because they are wrong; Example: Tilting the Y NunChuck (or Joystick) forward makes the Y Axis servo turn back....but that's an easy fix. Feel free to post any possible solutions to make improvement or solutions to better the stability. See attached code below. Enjoy.

// Honus 2007
// This allows the use of a Wii nunchuck as an input device and is modified/extended from the original code
// by Tod E. Kurt and Windmeadow Labs
// 2007 Tod E. Kurt, http://todbot.com/blog/
// The Wii Nunchuck reading code is taken from Windmeadow Labs, http://www.windmeadow.com/node/42

// Further updated and coded for Manual Mode of 2 servos when WiiNunchuck ZButton is pushed.
// By: Raymond Willis Jr., 2013, email at willisjr24@yahoo.com


#include "Wire.h" 

int ledPin1 = 8; // Control pin for LED 1
int servoPin1 = 5; // Control pin for servo motor
int servoPin2 = 6; // Control pin for servo motor


int pulseWidth1 = 2; // Amount to pulse the servo 1
int pulseWidth2 = 2; // Amount to pulse the servo 2


int refreshTime = 30; // the time in millisecs needed in between pulses

long lastPulse1;
long lastPulse2;


int minPulse = 700; // minimum pulse width
int loop_cnt=0;

void setup()
{
Serial.begin(19200);
pinMode(servoPin1, OUTPUT); // Set servo pin as an output pin
pinMode(servoPin2, OUTPUT); // Set servo pin as an output pin

pulseWidth1 = minPulse; // Set the motor position to the minimum
pulseWidth2 = minPulse; // Set the motor position to the minimum


nunchuck_init(); // send the initilization handshake
Serial.print("NunchuckServo ready\n");
}

void loop()
{
checkNunchuck1();
updateServo1(); // update servo 1 position
checkNunchuck2();
updateServo2(); // update servo 2 position


if( nunchuck_cbutton() ) // light the LED if c button is pressed
digitalWrite(ledPin1, HIGH);
else
digitalWrite(ledPin1,LOW);

delay(2.5); // this is here to give a known time per loop
}


void checkNunchuck1()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

if( nunchuck_zbutton() ) // Manual Control if z button is pressed
  {
  float tilt = nunchuck_joyx(); // x-axis, in this case ranges from ~70 - ~185
  tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly 
  pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds
  }
else
  {
  float tilt = nunchuck_accelx(); // x-axis, in this case ranges from ~70 - ~185
  tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly 
  pulseWidth1 = (tilt * 9) + minPulse; // convert angle to microseconds
  }
loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo1()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse1 >= refreshTime) {
digitalWrite(servoPin1, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth1); // Length of the pulse sets the motor position
digitalWrite(servoPin1, LOW); // Turn the motor off
lastPulse1 = millis(); // save the time of the last pulse
}
}

void checkNunchuck2()
{
if( loop_cnt > 100 ) { // loop()s is every 1msec, this is every 100msec

nunchuck_get_data();
nunchuck_print_data();

if( nunchuck_zbutton() ) // Manual Control if z button is pressed
  {
  float tilt = nunchuck_joyy(); // y-axis, in this case ranges from ~70 - ~185
  tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly 
  pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds
  }
else
  {
  float tilt = nunchuck_accely(); // y-axis, in this case ranges from ~70 - ~185
  tilt = (tilt - 70) * 1.5; // convert to angle in degrees, roughly 
  pulseWidth2 = (tilt * 9) + minPulse; // convert angle to microseconds
}
loop_cnt = 0; // reset for
}
loop_cnt++;

}

// called every loop().
// uses global variables servoPin, pulsewidth, lastPulse, & refreshTime
void updateServo2()
{
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse2 >= refreshTime) {
digitalWrite(servoPin2, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth2); // Length of the pulse sets the motor position
digitalWrite(servoPin2, LOW); // Turn the motor off
lastPulse2 = millis(); // save the time of the last pulse
}
}


//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6]; // array to store nunchuck data,


// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.write(0x40); // sends memory address
Wire.write(0x00); // sends sent a zero. 
Wire.endTransmission(); // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.write(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}

// Receive data back from the nunchuck,
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.read());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}

// 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 nunchuck_print_data()
{
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[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 ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
if ((nunchuck_buf[5] >> 3) & 1)
accel_x_axis += 1;

if ((nunchuck_buf[5] >> 4) & 1)
accel_y_axis += 2;
if ((nunchuck_buf[5] >> 5) & 1)
accel_y_axis += 1;

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

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

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

Serial.print("acc:");
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print("\t");

Serial.print("but:");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);

Serial.print("\r\n"); // newline
i++;
}

// 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;
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_zbutton()
{
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo
}

// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_cbutton()
{
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo
}

// returns value of x-axis joystick
int nunchuck_joyx()
{
return nunchuck_buf[0];
}

// returns value of y-axis joystick
int nunchuck_joyy()
{
return nunchuck_buf[1];
}

// returns value of x-axis accelerometer
int nunchuck_accelx()
{
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data
}

// returns value of y-axis accelerometer
int nunchuck_accely()
{
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data
}

// returns value of z-axis accelerometer
int nunchuck_accelz()
{
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data
}

Also need to add, I'm using the Arduino Uno V3 Board for this project.

Update:
I found better code (better servo stability) I had and changed it as needed. With this code: using a Wii_Nunchuck you can control two servos (Y,X) using the accelerometers, holding the C Button puts it in manual mode and then servo controls will come from the Wii_Nunchucks and holding Z Button will light up an LED attached to pin 9 (and pause all movement until released).
Note: I’m using Hitec HS-322HD servos for this set up and it responses very well with very little jitter when controlling the servos.
The only issues I noted is with the Joystick Controls. When you go extreme forward on the Joy the Y servo will reverse direction quickly and the same is for extreme left on the X servo. I believe that is because the servos can not move 360 and the extreme postions make it go over 360 degrees, so it goes the other direction to get there. I’m going to try and work them out but I’m really happy with the current results.
The code is attached.

// 
// Not sure exactly where I got the original code from but if you know you worked
// on it, please cite yourself to the code below in comments.
// I added comments as needed and using the pre-existing switch case, I created a 
// manual mode so when the c_button is held the controls come from the nunchuck's 
// Joystick. Also, when the z_button is held a LED is turned on to simulate a laser flash (pin9).
//
// Raymond Willis Jr. 2/6/2013 email: willisjr24@yahoo.com
// Title: Servo Turret Controls (Auto / Manual) with Laser fire using Wii_Nunchuck.

#include <Wire.h>
#include <string.h>
#include <stdio.h>
 
uint8_t outbuf[6];
 
int cnt = 0;
int ledPin = 13;
int ledPin2 = 9; 
int servoPin = 10;
int servoPin2 = 8;
 
int pulseWidth = 0;
int pulseWidth2 = 0;
 
long lastPulse = 0;
long lastPulse2 = 0;
 
int z_button = 0;
int c_button = 0;
 
int refreshTime = 20;
 
int minPulse = 1000;
int minPulse2 = 500;
 
int dtime=10;

  
#define pwbuffsize 10
long pwbuff[pwbuffsize];
long pwbuffpos = 0;
long pwbuff2[pwbuffsize];
long pwbuffpos2 = 0;
 
void setup()
{
    Serial.begin (9600);
    Wire.begin ();
    nunchuck_init ();
    pinMode(servoPin, OUTPUT);
    pinMode(servoPin2, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pulseWidth = minPulse;
    pulseWidth2 = minPulse2;
    Serial.print ("Finished setupn");
}
 
void nunchuck_init()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x40);
    Wire.write (0x00); 
    Wire.endTransmission ();
}
 
void send_zero()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x00);
    Wire.endTransmission ();
}
 
int t = 0;
 
void loop()
{
    t++;
    long last = millis();
 
    if( t == 1) {
 
        t = 0;
 
        Wire.requestFrom (0x52, 6);
 
        while (Wire.available ()) {
            outbuf[cnt] = nunchuk_decode_byte (Wire.read ());
            digitalWrite (ledPin, HIGH);
            cnt++;
        }
 
        if (cnt >= 5) {
 
                     // printNunchuckData(); // Uncomment to print data to display- RW
 
            int z_button = 0;
            int c_button = 0;
 
            if ((outbuf[5] >> 0) & 1)
                z_button = 1;
            if ((outbuf[5] >> 1) & 1)
                c_button = 1;
 
            switch (c_button) {
            case 1:
                switch (z_button) {
                case 0:
                                    digitalWrite(ledPin2, HIGH);
                                    delay (10);
                                    
                    break;
                case 1:
                                    digitalWrite(ledPin2, LOW);

                    muovi();
                    break;
                }
                break;
            case 0:
                switch (z_button) {
                case 0:

                    
                    break;
                case 1:
                    ray1();
                    break;
                }
                break;
            }
        }
 
        cnt = 0;
        send_zero();
 
    } // if(t==)
 
    updateServo();
 
    delay(dtime);
}
 
 
void updateServo() {
 
    if (millis() - lastPulse >= refreshTime) {
 
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulseWidth);
        digitalWrite(servoPin, LOW);
 
        digitalWrite(servoPin2, HIGH);
        delayMicroseconds(pulseWidth2);
        digitalWrite(servoPin2, LOW);
 
        lastPulse = millis();
    }
}
 
int i=0;
void printNunchuckData()
{
    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;
 
    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 (i,DEC);
    Serial.print ("t");
 
    Serial.print ("X: ");
    Serial.print (joy_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("Y: ");
    Serial.print (joy_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccX: ");
    Serial.print (accel_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccY: ");
    Serial.print (accel_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccZ: ");
    Serial.print (accel_z_axis, DEC);
    Serial.print ("t");
 
    Serial.print (z_button, DEC);
    Serial.print (" ");
    Serial.print (c_button, DEC);
    Serial.print ("rn");
    i++;
}
 
char nunchuk_decode_byte (char x)
{
    x = (x ^ 0x17) + 0x17;
    return x;
}
 
void muovi (){  // This is the pre-existing auto mode that uses the x, y accelerometers to move servos
    float tilt = (700 - outbuf[3]*2*2);
    float tilt2 = outbuf[2]*2*2;
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse;
 
    tilt2 = (tilt2-285);
    pulseWidth2 = (tilt2 * 5) + minPulse2;
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

void ray1 (){  // This is my set up for manual mode control using the wii nunchuck's joysticks - RW
    float tilt = (650 - outbuf[1]*2*2);  // change 650 as needed to center the servo when c_button is pressed and Joystick is centered- RW
    float tilt2 = outbuf[0]*2*2;
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse; // was (tilt * 5)
 
    tilt2 = (tilt2-285);  // change the 285 number as needed to center the servo when c_button is pressed and Joystick is centered- RW
    pulseWidth2 = (tilt2 * 5) + minPulse2; // was (tilt * 5)
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

Update #2:
I’m tweaking things a little further. I added an additional feature and made some changes. See attached code.

// 
// Not sure exactly where I got the original code from but if you know you worked
// on it , please cite yourself to the code below in comments.
//
// I added comments as needed and using the pre-existing switch case, I created a 
// manual mode so when the c_button is held the controls come from the nunchuck's 
// Joystick. Also when the z_button is held a LED (pin9 / GND) is pulsed to simulate 
// a laser pulsing in both modes.
//
// Version 2
// In this version I changed the auto mode around so the the Y servo tracks the front
// of the Wii_NunChuck like the buttons are a face looking left or right. Also added
// the LED pulse.
//
// Raymond Willis Jr. 2/7/2013 email: willisjr24@yahoo.com
// Title: Servo Turret Controls (Auto / Manual) with Laser fire using Wii_Nunchuck: v2. 

#include <Wire.h>
#include <string.h>
#include <stdio.h>
 
uint8_t outbuf[6];
 
int cnt = 0;
int ledPin = 13;
int ledPin2 = 9; 
int servoPin = 10;
int servoPin2 = 8;
 
int pulseWidth = 0;
int pulseWidth2 = 0;
 
long lastPulse = 0;
long lastPulse2 = 0;
 
int z_button = 0;
int c_button = 0;
 
int refreshTime = 20;
 
int minPulse = 1000;
int minPulse2 = 500;
 
int dtime=10;

  
#define pwbuffsize 10
long pwbuff[pwbuffsize];
long pwbuffpos = 0;
long pwbuff2[pwbuffsize];
long pwbuffpos2 = 0;
 
void setup()
{
    Serial.begin (9600);
    Wire.begin ();
    nunchuck_init ();
    pinMode(servoPin, OUTPUT);
    pinMode(servoPin2, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pulseWidth = minPulse;
    pulseWidth2 = minPulse2;
    Serial.print ("Finished setupn");
}
 
void nunchuck_init()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x40);
    Wire.write (0x00); 
    Wire.endTransmission ();
}
 
void send_zero()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x00);
    Wire.endTransmission ();
}
 
int t = 0;
 
void loop()
{
    t++;
    long last = millis();
 
    if( t == 1) {
 
        t = 0;
 
        Wire.requestFrom (0x52, 6);
 
        while (Wire.available ()) {
            outbuf[cnt] = nunchuk_decode_byte (Wire.read ());
            digitalWrite (ledPin, HIGH);
            cnt++;
        }
 
        if (cnt >= 5) {
 
                     // printNunchuckData(); // Uncomment to print data to display- RW
 
            int z_button = 0;
            int c_button = 0;
 
            if ((outbuf[5] >> 0) & 1)
                z_button = 1;
            if ((outbuf[5] >> 1) & 1)
                c_button = 1;
 
            switch (c_button) {
            case 1:
                switch (z_button) {
                case 0:
                                    digitalWrite(ledPin2, HIGH);
                                    delay (20); // LED on time in millisecs
                                    digitalWrite(ledPin2, LOW);
                                    delay (70); // LED off time in millisecs
                    break;
                case 1:
                                    digitalWrite(ledPin2, LOW);

                    muovi();
                    break;
                }
                break;
            case 0:
                switch (z_button) {
                case 0:
                                    digitalWrite(ledPin2, HIGH);
                                    delay (20); // LED on time in millisecs
                                    digitalWrite(ledPin2, LOW);
                                    delay (70); // LED off time in millisecs
                    break;
                case 1:
                    ray1();
                    break;
                }
                break;
            }
        }
 
        cnt = 0;
        send_zero();
 
    } // if(t==)
 
    updateServo();
 
    delay(dtime);
}
 
 
void updateServo() {
 
    if (millis() - lastPulse >= refreshTime) {
 
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulseWidth);
        digitalWrite(servoPin, LOW);
 
        digitalWrite(servoPin2, HIGH);
        delayMicroseconds(pulseWidth2);
        digitalWrite(servoPin2, LOW);
 
        lastPulse = millis();
    }
}
 
int i=0;
void printNunchuckData()
{
    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;
 
    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 (i,DEC);
    Serial.print ("t");
 
    Serial.print ("X: ");
    Serial.print (joy_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("Y: ");
    Serial.print (joy_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccX: ");
    Serial.print (accel_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccY: ");
    Serial.print (accel_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccZ: ");
    Serial.print (accel_z_axis, DEC);
    Serial.print ("t");
 
    Serial.print (z_button, DEC);
    Serial.print (" ");
    Serial.print (c_button, DEC);
    Serial.print ("rn");
    i++;
}
 
char nunchuk_decode_byte (char x)
{
    x = (x ^ 0x17) + 0x17;
    return x;
}
 
void muovi (){  // This is the pre-existing auto mode that uses the x, y accelerometers to move servos
    float tilt = (700 - outbuf[3]*2*2);
    float tilt2 = (700 - outbuf[2]*2*2);
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse;
 
    tilt2 = (tilt2);
    pulseWidth2 = (tilt2 * 5) + minPulse2;
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

void ray1 (){  // This is my set up for manual mode control using the wii nunchuck's joysticks
    float tilt = (650 - outbuf[1]*2*2);  // change 650 as needed to center the servo when c_button is pressed and Joystick is centered
    float tilt2 = outbuf[0]*2*2;
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse; // was (tilt * 5)
 
    tilt2 = (tilt2-295);  // change the 285 number as needed to center the servo when c_button is pressed and Joystick is centered
    pulseWidth2 = (tilt2 * 5) + minPulse2; // was (tilt * 5)
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

Update…now Version 5 of the code I’ve been working. What’s new?
I added code for a neat laser powering up and firing effect by using a LED on pin 9 and a keychain laser pointer on pin 11. Enjoy. Hope to have a video soon.

// 
// Not sure exactly where I got the original code from but if you know you worked
// on it , please cite yourself to the code below in comments.
// I added comments as needed and using the pre-existing switch case, I created a 
// manual mode so when the c_button is held the controls come from the nunchuck's 
// Joystick. Also when the z_button is pressed a LED (pin-9 / GND) is faded up to simulate 
// a laser powering up and then a simple keychain LASER POINTER assigned to pin-11 / GND goes 
// HIGH for a short duration to simulate a laser firing.
//
// In this version I changed the auto mode around so the the Y servo tracks the front
// of the wii_NunChuck like the buttons are a face looking left or right.
//
// Raymond Willis Jr. 2/20/2013 email: willisjr24@yahoo.com
// Title: Servo Turret Controls (Auto / Manual) with Laser fire using Wii_Nunchuck: v5. 

#include <Wire.h>
#include <string.h>
#include <stdio.h>
 
uint8_t outbuf[6];
 
int cnt = 0;
int ledPin1 = 9; // assign the LED pin
int laserPin = 11; // assign the laser pointer pin
int servoPin = 10;
int servoPin2 = 8;
 
int pulseWidth = 0;
int pulseWidth2 = 0;
 
long lastPulse = 0;
long lastPulse2 = 0;
 
int z_button = 0;
int c_button = 0;
 
int refreshTime = 20;
 
int minPulse = 1000;
int minPulse2 = 500;
 
int dtime=10;

int oneFlash = 1; // test only
  
#define pwbuffsize 10
long pwbuff[pwbuffsize];
long pwbuffpos = 0;
long pwbuff2[pwbuffsize];
long pwbuffpos2 = 0;
 
void setup()
{
    Serial.begin (9600);
    Wire.begin ();
    nunchuck_init ();
    pinMode(servoPin, OUTPUT);
    pinMode(servoPin2, OUTPUT);
    pinMode(ledPin1, OUTPUT);
    pinMode(laserPin, OUTPUT);
    pulseWidth = minPulse;
    pulseWidth2 = minPulse2;
    Serial.print ("Finished setupn");
}
 
void nunchuck_init()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x40);
    Wire.write (0x00); 
    Wire.endTransmission ();
}
 
void send_zero()
{
    Wire.beginTransmission (0x52);
    Wire.write (0x00);
    Wire.endTransmission ();
}
 
int t = 0;
 
void loop()
{
    t++;
    long last = millis();
 
    if( t == 1) {
 
        t = 0;
 
        Wire.requestFrom (0x52, 6);
 
        while (Wire.available ()) {
            outbuf[cnt] = nunchuk_decode_byte (Wire.read ());
            cnt++;
        }
 
        if (cnt >= 5) {
 
                     // printNunchuckData(); // Uncomment to print data to display- RW
 
            int z_button = 0;
            int c_button = 0;
 
            if ((outbuf[5] >> 0) & 1)
                z_button = 1;
            if ((outbuf[5] >> 1) & 1)
                c_button = 1;
 
            switch (c_button) {
            case 1:
                switch (z_button)  {
                case 0:
                                   if (oneFlash > 0) {
                                    for(int fadeValue = 0 ; fadeValue <= 100; fadeValue +=1) { //sets the value (range from 0 to 100):
                                    analogWrite(ledPin1, fadeValue); 
                                    delay (15); // change this value to increase/decrease the LED ramp up time.
                                    oneFlash = 0;
                                   }
                                  }
                                   analogWrite(ledPin1, LOW);
                                   digitalWrite(laserPin, HIGH);
                                   delay (700); // Laser Pointer on time in millisecs after LED ramp up is done.
                                   analogWrite(laserPin, LOW);                                                      
           
                    break;
                                  
                case 1:
                                    digitalWrite(ledPin1, LOW);
                                    muovi();
                                    if (oneFlash < 1){
                                      oneFlash = 1;
                                    }
                                      
                    break;
                }
                break;
                
            case 0:
                switch (z_button) {
                case 0:
                                     if (oneFlash > 0) {
                                    for(int fadeValue = 0 ; fadeValue <= 100; fadeValue +=1) { //sets the value (range from 0 to 100):
                                    analogWrite(ledPin1, fadeValue); 
                                    delay (15); // change this value to increase/decrease the LED ramp up time.
                                    oneFlash = 0;
                                   }
                                  }
                                   analogWrite(ledPin1, LOW);
                                   digitalWrite(laserPin, HIGH);
                                   delay (700); // Laser Pointer on time in millisecs after LED ramp up is done.
                                   digitalWrite(laserPin, LOW);  
                    break;
                case 1:
                    ray1();
                    break;
                }
                break;
            }
        }
 
        cnt = 0;
        send_zero();
 
    } // if(t==)
 
    updateServo();
 
    delay(dtime);
}
 
 
void updateServo() {
 
    if (millis() - lastPulse >= refreshTime) {
 
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulseWidth);
        digitalWrite(servoPin, LOW);
 
        digitalWrite(servoPin2, HIGH);
        delayMicroseconds(pulseWidth2);
        digitalWrite(servoPin2, LOW);
 
        lastPulse = millis();
    }
}
 
int i=0;
void printNunchuckData()
{
    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;
 
    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 (i,DEC);
    Serial.print ("t");
 
    Serial.print ("X: ");
    Serial.print (joy_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("Y: ");
    Serial.print (joy_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccX: ");
    Serial.print (accel_x_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccY: ");
    Serial.print (accel_y_axis, DEC);
    Serial.print ("t");
 
    Serial.print ("AccZ: ");
    Serial.print (accel_z_axis, DEC);
    Serial.print ("t");
 
    Serial.print (z_button, DEC);
    Serial.print (" ");
    Serial.print (c_button, DEC);
    Serial.print ("rn");
    i++;
}
 
char nunchuk_decode_byte (char x)
{
    x = (x ^ 0x17) + 0x17;
    return x;
}
 
void muovi (){  // This is the pre-existing auto mode that uses the x, y accelerometers to move servos
    float tilt = (700 - outbuf[3]*2*2);
    float tilt2 = (700 - outbuf[2]*2*2);
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse;
 
    tilt2 = (tilt2);
    pulseWidth2 = (tilt2 * 5) + minPulse2;
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

void ray1 (){  // This is my set up for manual mode control using the wii nunchuck's joysticks
    float tilt = (650 - outbuf[1]*2*2);  // change 650 as needed to center the servo when c_button is pressed and Joystick is centered
    float tilt2 = outbuf[0]*2*2;
 
    tilt = (tilt);
    pulseWidth = (tilt * 5) + minPulse; // was (tilt * 5)
 
    tilt2 = (tilt2-295);  // change the 285 number as needed to center the servo when c_button is pressed and Joystick is centered
    pulseWidth2 = (tilt2 * 5) + minPulse2; // was (tilt * 5)
 
    pwbuff[pwbuffpos] = pulseWidth;
    pwbuff2[pwbuffpos2] = pulseWidth2;
 
    if( ++pwbuffpos == pwbuffsize ) pwbuffpos = 0;
    if( ++pwbuffpos2 == pwbuffsize ) pwbuffpos2 = 0;
 
 
    pulseWidth=0;
    pulseWidth2=0;
 
    for( int p=0; p<pwbuffsize; p++ ){
        pulseWidth += pwbuff[p];
        pulseWidth2 += pwbuff2[p];
    }
 
    pulseWidth /= pwbuffsize;
    pulseWidth2 /= pwbuffsize;
 
}

Please keep posting :) I was just thinking of getting a WiiNunchuck. I don't have one yet so I can't give you any feedback, but I'll be glad to try your code.

making me want to order a Wii Nunchuck now!!!

Here’s a quick video. You can see the servo jitter when waiting but is pretty reactive when you tilt. You can’t see the powering up effect of the LED (only in the dark) but you do see the laser pointer. I’m still working the code trying to clean things up so I’ll update when I get newer stuff working.
Enjoy:

The response to the accelerometer is impressive, pretty reactive indeed.