Go Down

Topic: Wii Motion Plus Servo Controller (Read 4004 times) previous topic - next topic


Hi guys,
Im new to arduino, and I want to control my servos/motors using the wii motion plus gyroscope.

Unfortunately the servo is not moving at all.
Any ideas how I can get that fixed?



setup looks like this:

and that's the code I'm using:
Code: [Select]
//Trapezoid or Runge-kutta 4th order integration program of wm+

#include <Streaming.h>
#include <Wire.h>
#include <Servo.h>

Servo yawServo;
Servo pitchServo;

int yawServoVal;
int pitchServoVal;

#define steps_per_deg_slow 20
#define steps_per_deg_fast 4

byte data[6];          //six data bytes
int yaw, pitch, roll;  //three axes
int yaw0, pitch0, roll0;  //calibration zeroes
int time, last_time;
float delta_t;
int last_yaw[3], last_pitch[3], last_roll[3];
float yaw_deg, pitch_deg, roll_deg;
int yaw_deg2, pitch_deg2, roll_deg2;
int startTag=0xDEAD;
int accel_x_axis, accel_y_axis, accel_z_axis;

void wmpOn(){
 Wire.beginTransmission(0x53);    //WM+ starts out deactivated at address 0x53
 Wire.send(0xfe);                 //send 0x04 to address 0xFE to activate WM+
 Wire.endTransmission();          //WM+ jumps to address 0x52 and is now active

void wmpSendZero(){
 Wire.beginTransmission(0x52);    //now at address 0x52
 Wire.send(0x00);                 //send zero to signal we want info

void calibrateZeroes(){
 for (int i=0;i<10;i++){
   for (int i=0;i<6;i++){
   yaw0+=(((data[3]>>2)<<8)+data[0])/10;        //average 10 readings for each zero
 Serial.print("  Pitch0:");
 Serial.print("  Roll0:");

void receiveData(){
 wmpSendZero();                   //send zero before each request (same as nunchuck)
 Wire.requestFrom(0x52,6);        //request the six bytes from the WM+
 for (int i=0;i<6;i++){
 if(bitRead(data[3], 1)==1) yaw=(((data[3]>>2)<<8)+data[0]-yaw0)/steps_per_deg_slow;        //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
 else yaw=(((data[3]>>2)<<8)+data[0]-yaw0)/steps_per_deg_fast;
 if(bitRead(data[3], 0)==1) pitch=(((data[4]>>2)<<8)+data[1]-pitch0)/steps_per_deg_slow;    //for info on what each byte represents
 else pitch=(((data[4]>>2)<<8)+data[1]-pitch0)/steps_per_deg_fast;
 if(bitRead(data[4], 1)==1) roll=(((data[5]>>2)<<8)+data[2]-roll0)/steps_per_deg_slow;
 else roll=(((data[5]>>2)<<8)+data[2]-roll0)/steps_per_deg_fast;

float trapIntegrate(int y2, int y1, float deltax){
 float area=0;
 return area;

float rk4Integrate(int y4, int y3, int y2, int y1, float deltax){
 float area=0;
 return area;

void setup()
 Serial.println("WM+ Tuning People Bot Control");
 wmpOn();                        //turn WM+ on
 calibrateZeroes();              //calibrate zeroes
 pinMode(4, INPUT);

void loop(){
 receiveData();                  //receive data and calculate yaw pitch and roll
 /* Runge-kutta 4th Order Integration */
 yaw_deg+=rk4Integrate(yaw, last_yaw[0], last_yaw[1], last_yaw[2], delta_t);
 pitch_deg+=rk4Integrate(pitch, last_pitch[0], last_pitch[1], last_pitch[2], delta_t);
 roll_deg+=rk4Integrate(roll, last_roll[0], last_roll[1], last_roll[2], delta_t);
 /* Runge-kutta 4th Order Integration */
 if (digitalRead(4) == 1)
   yaw = 0;
   pitch = 0;
   roll = 0;
   yaw_deg = 0;
   pitch_deg = 0;
   roll_deg = 0;

 yawServoVal = map(yaw_deg, -90, 90, 0, 179);
 if (yawServoVal < 0){yawServoVal = 0;};
 if (yawServoVal > 179){yawServoVal = 179;};
 pitchServoVal = map(pitch_deg, -90, 90, 0, 179);
 if (pitchServoVal < 60){pitchServoVal = 60;};
 if (pitchServoVal > 179){pitchServoVal = 179;};


Where's your test sketch to prove the servo works?
What does your debug output look like?
Does it look like you're passing the right sort of values to the servos?
Per Arduino ad Astra


How about the external power supply, are you running it with the USB-power only?

The only law for me; Ohms Law: U=R*I       P=U*I
Note to self: "Damn! Why don't you just fix it!!!"


the servo is working. I now tested it on an 12V battery, still not working :(


Aug 23, 2010, 07:13 pm Last Edit: Aug 23, 2010, 07:15 pm by AWOL Reason: 1
. I now tested it on an 12V battery

What sort of servo is it?
Most R/C servos are 6V.

Do the debug prints look sensible?
i.e. do they gives servo angles in the right sort of range?

I've got to say, R-K wouldn't be my first attempt at an Arduino programming project
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.


Thanks guys, it's a 4.8V servo.
I still get no output at all:(
Any ideas? The wii m+ is working!


What does your debug output look like?
Per Arduino ad Astra


Maybe you need external power for the servo. It's most likely not working because it is drawing more mA's than Arduino can provide.


I'm no longer using a servo.
I just want the values for each axis to appear in the serial monitor.

Anybody wants to do that for me (incl. servo-out)? Will pay you!  ;)


Nobody? :'(
Would be REALLY helpful!


Would be really helpful TO POST YOUR DEBUG PRINT OUTPUT
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.


Sep 12, 2010, 07:34 pm Last Edit: Sep 12, 2010, 07:35 pm by jds Reason: 1
In your code I found this line:
Code: [Select]

In your serial window I see 19200 baud.

Make these equal to each other and tell us what happens.


Go Up