Wii NunChuck controller, Arduino and servos
The Wii nunchuck controller contains a 3 axis accelerometer, one joystick and 2 buttons for only 20 euro and you can easly use it to manage your Arduino applications.
In this article we’ll see how to move two servo motors using this controller (providing two videos, prototype images and complete source code)
I have read a lot about Arduino and Wii Nunchuck, so I have decided to buy a wiichuck adapter from Sparkfun, a Wii controller and I was very excited to do my first tests.
I was surprised because I only spent 30 minutes to put it in place and create this demo.
REQUIRED HARDWARE:
- 1 Nintendo Wii Nunchuck Controller (20 euro and you can buy it everywhere)
- 1 WiiChuck Adapter - 3 dollars on Sparkfun.com
NOTE: you can also cut the cable and directly connect the controller wires (search on Google and you’ll find a lot of articles)
- 2 Servo motors HS-422 (or similar, about 15/20 euro each one) and a Lynx Tilt kit (about 15/20 euro) - from robot-italy.com
- 1 Arduino (i have used Duemilanove version)
- 1 BreadBoard
CONNECTIONS
The Wii Controller requires only 4 pins: ground, 5 volt and 2 Arduino analog pins.
Each servo motor require 3 connections: ground, 5V and a Arduino PWM pin.
Check following images to get inspiration. It’s very simple
![]()
CODE (wiring/Arduino):
I have found a lot of source code samples inside books and looking around the web but this is the best one and the more accurate I have found for my purpose (check following video to understand what I mean with ‘accurate’).
I don’t remember where I got it so I’m sorry if I didn’t post the author’s website.
#include <Wire.h> #include <string.h> #include <stdio.h> uint8_t outbuf[6]; int cnt = 0; int ledPin = 13; int servoPin = 9; int servoPin2 = 10; 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); pulseWidth = minPulse; pulseWidth2 = minPulse2; Serial.print ("Finished setupn"); } void nunchuck_init() { Wire.beginTransmission (0x52); Wire.send (0x40); Wire.send (0x00); Wire.endTransmission (); } void send_zero() { Wire.beginTransmission (0x52); Wire.send (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.receive ()); digitalWrite (ledPin, HIGH); cnt++; } if (cnt >= 5) { // printNunchuckData(); 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: break; case 1: muovi(); break; } break; case 0: switch (z_button) { case 0: delay(10000); break; case 1: delay(3000); 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 (){ float tilt = (700 - outbuf[3]*2*2); float tilt2 = outbuf[2]*2*2; tilt = (tilt); pulseWidth = (tilt * 5) + minPulse; tilt2 = (tilt2-288); 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; }









Great work, great use of the wii-chuck. Also I like the little guy strapped to the front of it.
Thanx Chris, i only got and merged some info from more resources but I love it too… it seems work very well.
If you are interested the puppet collection name is VOODOO dools : P
I F’ing love you!! i’ve been searching for days for this code that didn’t have errors after compiling. if you could give me some pointers though ( cause im still a noob), i’m not sure how to assign the other buttons on the nunchuck. Like two more servos for the joystick! Thanks Fabio! You made my day
Leave your response!
Archives
Categories
Blogs
3D ActionScript Adobe AIR AIR for Android android Arduino Binding burrito hero 4.5 TabbedMobileApplication Chat Chrome Cocomo code optimization components custom/generic components custom components DataList developer central Emitter FLARToolkit Flash Flash Builder Flex HTTPService illustrator Infrared Interactions itemRenderer Joystick Loader mobile Papervision PHP Rss Servo singleton Skin Skinning Transitions Tween URLLoader URLRequest Vertical Scrollbar VScrollbar youtube
WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.
Recent Posts
Develop Mobile apps with Catalyst?
Code optimization
TextInput Component
Interactions and Transitions
Most Commented
Recent Comments
how to call methods between swf files