Re: Use a Wii Motion Plus, using I2C interface ?
Posted: 04 Feb 2011, 10:08
oh good lord, i first have to find my magnifying glass for this...
Give a child a robot, he'll play for an hour. Teach him to build, and he'll play forever.
https://mindboards.org:443/
That is possible, some u-controllers do integrate them, but usually the designer can turn them off. I think the PICAXE 20X2's have an option to have pullups internally on their I2C lines, but I have never looked into it.hergipotter wrote:...Perhaps the pull-ups are integrated in the µC?
Code: Select all
#define PORT S4
#define LOOPS 1
byte WMplusActivate[] = {0xA6, 0xFE, 0x04};
byte WMplusWrite[] = {0xA4, 0x00};
byte WMplusRead[] = {0xA4};
byte nbytes;
byte data[];
void initWMplus()
{
LowspeedWrite(PORT, 0, WMplusActivate);
while(LowspeedStatus(PORT, nbytes)>0);
}
void readWMplus()
{
LowspeedWrite(PORT, 0, WMplusWrite);
while(LowspeedStatus(PORT, nbytes)>0);
LowspeedWrite(PORT, 6, WMplusRead); //ask for 6 bytes
while(LowspeedStatus(PORT, nbytes)>0);
NumOut(15, LCD_LINE6, nbytes); // Print number of bytes read
if(nbytes == 6){
LowspeedRead(PORT, 6, data) //read data from buffer
for(int i=0; i<6; i++ ){
data[i]=(data[i]^0x17) + 0x17; // decode data
}
}
else {
ArrayInit(data,0,0); //error
}
}
task main()
{
SetSensorLowspeed(PORT);
initWMplus();
for (int j = 0; j < LOOPS; j++)
{
ClearScreen();
readWMplus();
/*if (ArrayLen(data)==6) {
for(int i=0; i<ArrayLen(data); i++ ) {
TextOut(15*i, LCD_LINE5, FormatNum("%02X", data[i])); //hex: enhanced firmware
//NumOut(15*i, LCD_LINE5, data[i]); //dez: lego firmware
}
} */
Wait(100);
}
Wait(3000);
}
Code: Select all
#define PORT S4
#define SHOW_CALIB_VALUES
byte WMplusActivate[] = {0xA6, 0xFE, 0x04};
byte WMplusWrite[] = {0xA4, 0x00};
byte WMplusRead[] = {0xA4};
byte nbytes;
byte data[];
int yaw, pitch, roll; // variables holding sensor values
int yaw0, pitch0, roll0; // variables for offset values
/* Initialises the Wii Motion Plus.
After this, the i2c address changes to 0xA4
*/
void initWMplus()
{
LowspeedWrite(PORT, 0, WMplusActivate);
while(LowspeedStatus(PORT, nbytes)>0);
}
/* Calibrates the offset values by
computing the average of ten readings
*/
void calibrateOffset()
{
int i = 0;
while (i < 10) // read sensors 10 times
{
LowspeedWrite(PORT, 0, WMplusWrite);
while(LowspeedStatus(PORT, nbytes)>0);
LowspeedWrite(PORT, 6, WMplusRead); //ask for 6 bytes
while(LowspeedStatus(PORT, nbytes)>0);
if(nbytes == 6)
{
LowspeedRead(PORT, 6, data); //read data from buffer
yaw0 += (((data[3]>>2)<<8) | data[0]) / 10;
pitch0 += (((data[4]>>2)<<8) | data[1]) / 10;
roll0 += (((data[5]>>2)<<8) | data[2]) / 10;
i++;
}
Wait(50);
}
#ifdef SHOW_CALIB_VALUES
{
NumOut(55, LCD_LINE3, yaw0);
NumOut(55, LCD_LINE4, pitch0);
NumOut(55, LCD_LINE5, roll0);
TextOut(5, LCD_LINE3, "yaw0: ");
TextOut(5, LCD_LINE4, "pitch0: ");
TextOut(5, LCD_LINE5, "roll0: ");
Wait(3000);
}
#endif
}
/* Reads the sensor values.
After this, the raw values are stored in the data array
and the computed values can be read from yaw, pitch and roll variables
*/
void readWMplus()
{
LowspeedWrite(PORT, 0, WMplusWrite);
while(LowspeedStatus(PORT, nbytes)>0);
LowspeedWrite(PORT, 6, WMplusRead); //ask for 6 bytes
while(LowspeedStatus(PORT, nbytes)>0);
if(nbytes == 6){
LowspeedRead(PORT, 6, data); //read data from buffer
yaw = (((data[3]>>2)<<8) | data[0]) - yaw0;
pitch = (((data[4]>>2)<<8) | data[1]) - pitch0;
roll = (((data[5]>>2)<<8) | data[2]) - roll0;
}
else {
ArrayInit(data,0,0); //error
}
}
task main()
{
SetSensorLowspeed(PORT);
initWMplus();
Wait(300); // Wait some time after init
calibrateOffset();
while (true)
{
ClearScreen();
readWMplus();
if (ArrayLen(data)==6) {
for(int i=0; i<ArrayLen(data); i++ ) {
TextOut(15*i, LCD_LINE1, FormatNum("%02X", data[i])); //hex: enhanced firmware
//NumOut(15*i, LCD_LINE5, outbuf[i]); //dez: lego firmware
}
NumOut(55, LCD_LINE3, yaw);
NumOut(55, LCD_LINE4, pitch);
NumOut(55, LCD_LINE5, roll);
TextOut(5, LCD_LINE3, "yaw: ");
TextOut(5, LCD_LINE4, "pitch: ");
TextOut(5, LCD_LINE5, "roll: ");
}
Wait(200);
}
}