Thank you for the links, however I have already peered through those.
It seems as though I'm having a problem with the address to receive the data: if I change the address in the code below from 0x52 to 0x4a (or any other) it gives me the same result (displays 0's), does anyone have a hunch that this is the problem? Also, how would I find the right address?
I ordered my WMP from ebay and it looks a little different from the WMP's posted online, would this be a factor? Or does it not matter because all Wii's read at the same addresses?
#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([glow]0xa4[/glow]); //now at address [glow]0x52[/glow]
Wire.send(0x00); //send zero to signal we want info
Wire.endTransmission();
}
void calibrateZeroes(){
for (int i=0;i<10;i++){
wmpSendZero();
Wire.requestFrom([glow]0xa4[/glow],6);
for (int i=0;i<6;i++){
data[i]=Wire.receive();
}
yaw0+=(((data[3]>>2)<<8)+data[0])/10; //average 10 readings
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([glow]0xa4[/glow],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;
pitch=((data[4]>>2)<<8)+data[1]-pitch0;
roll=((data[5]>>2)<<8)+data[2]-roll0;
}
//see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
//for info on what each byte represents
void setup(){
Serial.begin(115200);
Serial.println("WM+ tester3");
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);
}
The Wii Motion Plus starts off at register 0xA60000 instead of register 0xA40000, because it has its own extension port on the back allowing a Nunchuk for example to be plugged in along with the Wii Motion Plus. BUT it changes to 0xA40000 once it is activated by writing 04 to 0xa600fe.
The Wii Motion Plus is first identified by the 6 bytes: 00 00 A6 20 00 05 at register address 0x(4)a600fa (instead of 0x(4)a400fa like a regular extension). Games attempt to detect the Wii Motion Plus by trying to read the two-byte expansion identifier at 0xA600FE (they try up to 3 times, then wait 8 seconds, then check again). If a Wii Motion Plus is not present, or it has already been activated, then the attempt to read those bytes will fail with error 7.
The extension is initialised by writing 0x55 to 0x(4)a600f0. But there is no need to write 00 to 0x(4)a500fb, since Wii games don't do that. While the Motion Plus is initialising, the value at 0x(4)a600f7 changes from 0x02 to 0x04 to 0x08 to 0x0C to 0x0E then stays at 0x0E. There is no need to read this byte, since games don't. While initialising, the 128 bytes from 0x(4)a60050 - 0x(4)a600cf also change briefly, but randomly, after the extension is initialized. More examples of this data block changing over time can be found here: Three Data Samples from Wii Motion Plus (Google Doc)
It appears that the 32 bytes from 0x(4)a60020 are, as usual, calibration information, but it is unknown how they work.
Writing 0x04 to 0x(4)A600FE activates the MotionPlus as the "active" extension. This does 3 things (with no additional initialization):