Wii Nunchuck update

In February of 2013 I was attempting to wire a Wii Nunchuck to my Arduino (which I did).  The problem was that I thought it wasn’t good enough.  I liked that I could run the throttle on a train with this Arduino and code (here’s the original post: http://holoprinter.blogspot.com/search/label/Wii%20Remote).  What I didn’t like was that it didn’t seem like it was smooth and pinout for the servo was ok, but I wanted to streamline it some.  Intro the Servo library.

I do not know if I modified this code.  I started this blog to streamline the processes with the Servo library, however, I did copy this and am pretty sure I did not modify it much.  I did change some pins around.

When you rotate the Wii Nunchuck up and down one servo will rotate.  When you roll the Wii Nunchuck the other servo will rotate.  If you press the ‘c’ button then use the top hat you will get one servo to move along the x-axis and one servo when you move the top hat along the y-axis.

I’m working on another version of this that streamlines it into more of a library.

http://forum.arduino.cc/index.php?topic=147238.0;wap2

 //   
// 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.
//http://forum.arduino.cc/index.php/topic,147238.0.html
#include
#include
#include
uint8_t outbuf[6];
int cnt = 0;
int ledPin1 = 13;//9; // assign the LED pin
int laserPin = 11; // assign the laser pointer pin
int servoPin = 7;//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;
}
Serial.println("laser flash");
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:
Serial.println("ray");
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;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.