Go Down

Topic: Wii Motion Plus Decoded (Read 27505 times) previous topic - next topic

knuckles904

Jun 23, 2009, 04:10 am Last Edit: Jun 23, 2009, 04:56 am by knuckles904 Reason: 1
Ok, Im finished decoding the Wii motion plus peripheral. Ive got it up and running on my arduino nano. All the info as well as the demo code is on my shiny new blogger account. Check it out: http://randomhacksofboredom.blogspot.com/

Ill also post code here as its more tidy and suited for that sort of thing

Code: [Select]
#include <Wire.h>

byte data[6];          //six data bytes
int yaw, pitch, roll;  //three axes
int yaw0, pitch0, roll0;  //calibration zeroes

void wmpOn(){
 Wire.beginTransmission(0x53);    //WM+ starts out deactivated at address 0x53
 Wire.send(0xfe);                 //send 0x04 to address 0xFE to activate WM+
 Wire.send(0x04);
 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
 Wire.endTransmission();
}

void calibrateZeroes(){
 for (int i=0;i<10;i++){
   wmpSendZero();
   Wire.requestFrom(0x52,6);
   for (int i=0;i<6;i++){
     data[i]=Wire.receive();
   }
   yaw0+=(((data[3]>>2)<<8)+data[0])/10;        //average 10 readings for each zero
   pitch0+=(((data[4]>>2)<<8)+data[1])/10;
   roll0+=(((data[5]>>2)<<8)+data[2])/10;
 }
 Serial.print("Yaw0:");
 Serial.print(yaw0);
 Serial.print("  Pitch0:");
 Serial.print(pitch0);
 Serial.print("  Roll0:");
 Serial.println(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++){
   data[i]=Wire.receive();
 }
 yaw=((data[3]>>2)<<8)+data[0]-yaw0;        //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
 pitch=((data[4]>>2)<<8)+data[1]-pitch0;    //for info on what each byte represents
 roll=((data[5]>>2)<<8)+data[2]-roll0;      
}

void setup(){
 Serial.begin(115200);
 Serial.println("WM+ tester");
 Wire.begin();
 wmpOn();                        //turn WM+ on
 calibrateZeroes();              //calibrate zeroes
 delay(1000);
}

void loop(){
 receiveData();                  //receive data and calculate yaw pitch and roll
 Serial.print("yaw:");           //see diagram on randomhacksofboredom.blogspot.com
 Serial.print(yaw);              //for info on which axis is which
 Serial.print("  pitch:");
 Serial.print(pitch);
 Serial.print("  roll:");
 Serial.println(roll);
 delay(100);
}

transfinite

Words cannot express how awesome this is.

When I first heard of the Motion Plus I knew that Arduino IMU would one day arrive.  I didn't know that it would be so soon.

Congratulations knuckles904.

absolutum

which resolution in parts of degree do you get with the WII Motion Plus?

jezuz

kudos :) can't wait to get down and dirty with this

designer2k2

Quote
which resolution in parts of degree do you get with the WII Motion Plus?


2nd that! and how fast is it?

but its shure the cheapest sensor you can get  :D

mem

The MotionPlus uses the IDG600 dual axis gyro which is specified at 2000 degrees per second with a linearity of 0.1%
http://www.invensense.com/products/idg_600.html

blindfish

Great stuff!

I'd just assumed that Motion Plus added sensors to deal with the lack of yaw data on the Wii-remote and you needed to combine Motion Plus with the remote to get complete motion tracking.  It seems this isn't the case :D

mem

Quote
I'd just assumed that Motion Plus added sensors to deal with the lack of yaw data on the Wii-remote and you needed to combine Motion Plus with the remote to get complete motion tracking.  It seems this isn't the case

why? I think the Motion Plus just adds gyros, the accelerometers from the remote are still needed

blindfish

Ah - my misunderstanding: re-reading your blog more carefully  (i.e. being less excited and paying proper attention :-[ ) I see you mention that you need to combine it with the nunchuck/remote to get full motion sensing.  Having said that the arrows on the diagram at the bottom do give the impression that the Motion Plus returns roll, pitch and yaw data.  It might be worth clarifying that so over-excited fools such as myself don't misinterpret it ;)

xandar

:)  Thanks knuckles, you rock!  Have you figured out how to talk to a nunchuck plugged into the m+ after the m+ has been activated?

knuckles904

#10
Jun 23, 2009, 11:51 pm Last Edit: Jun 24, 2009, 12:06 am by knuckles904 Reason: 1
Thanks everyone. Sorry about the misunderstanding. The WM+ only contains gyros (specifically a two axis gyro listed above and then another gyro whose datasheet has yet to be found, plus a 14 bit adc). Gyros only yield data about rotational velocity, not position. Accelerometers (like those found in the nunchuck)yield position data (due to gravitational acceleration) and direct acceleration due to motion. So with these two sensors in the three directions, we have a 6DOF IMU (inertial measurement unit) which fully measures motion in three directions.

And sorry xandar, i havent been able to play with that yet. My nunchuck is about 60 miles away right now. The wiibrew site i referenced makes it seem like you have to deactivate the WM+ and then initialize the nunchuck to read from there, but that just doesnt seem right. Ill ask anyone who has both a WM+, nunchuck, and arduino on hand to try to run the standard nunchuck code and see if it works and post back here. If not, I might have something that could do the trick.

(edit)-nevermind, nunchuck and WM+ are at the same address when the WM+ is active. It doesnt seem like anyone has figured out how to read from the expansion slot yet.

xandar

Ok, that's what I thought, thanks.

Seems like there must be some way.... disabling (and reinitializing) the WM+ every time you want to read the nunchuck seems like it would hurt your sampling rate too much :-/

jds

Very cool, awesome work knuckles!

halley


The Wiimote and the Nunchuck use the same 3d accelerator part.  They get a rate of change of velocity in x, y, z.

Since gravity is a known component, you can use this to estimate current roll and current pitch but not current yaw.  The estimates are not very accurate if there are other strong acceleration components like shaking.

The Wiimote has a camera that can analyze the picture to find the "sensor bar" lights.  It can then estimate current yaw, and fine-tune the current roll and pitch estimates.  The Nunchuck does not have any way of detecting the sensor bar, of course.

With acceleration and a known starting condition, you can also estimate velocity, and with velocity, you can also estimate absolute position.  These sensors are pretty noisy, so don't expect much in the way of position tracking.

The Wii Motion Plus adds a three axis gyro sensor to the above capabilities.  It's not able to determine current yaw, pitch or roll.  It's only able to determine rate of change in yaw, pitch and roll.

Just as with orthogonal velocity, you can also estimate the absolute rotational position (current yaw, current pitch, current roll) given the rotational velocity and a known starting condition.

knuckles904

#14
Jun 28, 2009, 02:50 am Last Edit: Jun 28, 2009, 04:54 am by knuckles904 Reason: 1
can someone with a wii, nunchuck, and motion plus please check this for me, i havent been able to get a good answer with google and i dont own a wii(though now i have an 80$ controller for it). With the motion plus plugged into the wiimote, and the nunchuck plugged into the motion plus, will the wii, recognize the nunchuck in a game that needs the nunchuck? I have heard rumors that it will not recognize the nunchuck when plugged into the expansion port. Can anyone confirm or deny this rumor?

(edit) nevermind, this person took apart their WM+ and caused a loose wire

Go Up