lesto
I haven't played with mine for a while (I only just received the motor controller board).
I don't recall ever having read issues.
I have 2k7 pullups on the data and clock and use a 328.
Here is my code, it has a few corrections that were discovered on the way along the journey.
// .......................................................................
// Code for reading data from a Wii Motion plus device connected to a Nunchuck
// Links to other sites
// http://www.windmeadow.com/node/42 .... first time i saw arduino nunchuk interface
// http://www.kako.com/neta/2009-017/2009-017.html# .....Japanese site with lots of Wii info
// http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus .... the one and only
// http://randomhacksofboredom.blogspot.com/2009/06/wii-motion-plus-arduino-love.html
// ....original motion plus but not passthrough
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1248889032/35 .... great Kalman filter code
// thanks to duckhead and knuckles904. I will be using that code for sure.
// http://obex.parallax.com/objects/471/ .... ideas for passthrough
// by Krulkip
// Here is the bitmapping which is changed from the standard nunchuk mapping
// In Nunchuk mode:
// Bit
// Byte 7 6 5 4 3 2 1 0
// 0 SX<7-----------------------------------------------------0>
// 1 SY<7-----------------------------------------------------0>
// 2 AX<9-----------------------------------------------------2>
// 3 AY<9-----------------------------------------------------2>
// 4 AZ<9---------------------------------------------3> 1
// 5 AZ<2-----1> AY<1> AX<1> BC BZ 0/1 0
// Please note also the loss of the bit0 resolution.
// Byte 5 Bit 1 is used to signify what data (0) = nunchuk, (1) is motion plus.
// Byte 4 Bit 0 is the extention controller detection bit. (1 = extension present)
// Hardware Arduino with ATMega 328
// Connections SCA to AD4 (Analog4) and SCL to AD5 (Analog5) with pullup of 2k7 to 3.3 volts
//........................................................................
// The Arduino I2C uses 7 bits, therefore the MP address (0xA6) becomes 0x53, and the (0xA4) becomes 0x52
// Modified by Mark Beckett
// May 2010
#include <Wire.h>
#include <string.h>
#include <stdio.h>
#include <LiquidCrystal.h>
//setup the variables, etc
int ledPin = 13;
int xID;
//Nunchuck
uint8_t outbuf[6]; //nunchuck buffer for data
int cnt = 0; //nunchuck buffer counter
int joy_x_axis; //Joystick x (8 bits)
int joy_y_axis; //Joystick y (8 bits)
int accel_x_axis; //Nunchuck x (10 bits - bit0)
int accel_y_axis; //Nunchuck y (10 bits - bit0)
int accel_z_axis; //Nunchuck z (10 bits - bit0)
//Wii Motion Plus
byte data[6]; //buffer for WM+ data
int yaw, pitch, roll; //three gyroscope axes (14 bits)
int yaw0, pitch0, roll0; //calibration zeroes
bool yaw_v, pitch_v, roll_v; //calibration zeroes
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup (){
Serial.begin (19200);
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
//lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Initialising");
Wire.begin();
Serial.print ("Finished setup\n");
Serial.print ("Now detecting WM+\n");
delay(100);
// innitiate Wii Motion plus
Serial.print ("Initialising Wii Motion plus ........");
Wire.beginTransmission(0x52); //0xA6
Wire.send(0xF0);
Wire.send(0x55);
Wire.endTransmission();
Serial.print (" OK done");
Serial.print ("\r\n");
delay (100);
// nunchuk mode = 05, wm+ only = 04, classic controller = 07
Serial.print ("Initialising Wii Motion Plus for Nunchuk in passthru mode = 05 ........");
Wire.beginTransmission(0x53); //0xA6
Wire.send(0xFE);
Wire.send(0x05);// nunchuk in pass thru mode
Wire.endTransmission();
Serial.print (" OK done");
Serial.print ("\r\n");
delay (100);
Serial.print ("Set reading address at 0xFA .......");
Wire.beginTransmission(0x52); //0xA4
Wire.send(0xFA);
Wire.endTransmission();
Serial.print(" OK done");
Serial.print ("\r\n");
delay (100);
Wire.requestFrom (0x52,6); //0xA4
outbuf[0] = Wire.receive();Serial.print(outbuf[0],HEX);Serial.print(" ");
outbuf[1] = Wire.receive();Serial.print(outbuf[1],HEX);Serial.print(" ");
outbuf[2] = Wire.receive();Serial.print(outbuf[2],HEX);Serial.print(" ");
outbuf[3] = Wire.receive();Serial.print(outbuf[3],HEX);Serial.print(" ");
outbuf[4] = Wire.receive();Serial.print(outbuf[4],HEX);Serial.print(" ");
outbuf[5] = Wire.receive();Serial.print(outbuf[5],HEX);Serial.print(" ");
Serial.print ("\r\n");
xID= outbuf[0] + outbuf[1] + outbuf[2] + outbuf[3] + outbuf[4] + outbuf[5];
//Serial.print("Extension controller xID = 0x");
//Serial.print(xID,HEX);
//delay (200);
if (xID == 0xCB) { Serial.print (" Wii Motion plus connected but not activated"); } // 00 00 A6 20 00 05
if (xID == 0xCE) { Serial.print (" Wii Motion plus connected and NC activated"); } // 00 00 A4 20 00 05
if (xID == 0x00) { Serial.print (" Wii Motion plus not connected"); } // 00 00 00 00 00 00
Serial.print ("\r\n");
lcd.setCursor (0,0);
lcd.print("Motion Plus OK");
lcd.setCursor (0,1);
lcd.print (" Nunchuck OK");
delay (500);
// Now we want to point the read adress to 0xa40008 where the 6 byte data is stored
Serial.print ("Set reading address at 0x08 .........");
Wire.beginTransmission(0x52);
Wire.send(0x08);
Wire.endTransmission();
Serial.print(" OK done");
Serial.print ("\r\n");
lcd.clear();
}
void send_zero (){
Wire.beginTransmission(0x52);
Wire.send(0x00);
Wire.endTransmission();
}
void loop (){
// now follows conversion command instructing extension controller to get
// all sensor data and put them into 6 byte register within the extension controller
send_zero (); // send the request for next bytes
delay (100);
Wire.requestFrom (0x52,6);
outbuf[0] = Wire.receive();
outbuf[1] = Wire.receive();
outbuf[2] = Wire.receive();
outbuf[3] = Wire.receive();
outbuf[4] = Wire.receive();
outbuf[5] = Wire.receive();
print ();
cnt = 0;
delay (100); //slow down the printing
}
void print (){
// check if nunchuk is really connected
// Byte(4) bit 0 is 1 if the extension is connected
if ((outbuf[4]&0x01)==0x01) {
Serial.print("Ext con: ");
}
if ((outbuf[5]&0x03)==0x00) { //Nunchuck Data
int joy_x_axis = outbuf[0];
int joy_y_axis = outbuf[1];
int accel_x_axis = (outbuf[2] << 2) + ((outbuf[5] >> 3) & 2);
int accel_y_axis = (outbuf[3] << 2) + ((outbuf[5] >> 4) & 2);
int accel_z_axis = (outbuf[4] << 2) + ((outbuf[5] >> 5) & 6);
int z_button = (outbuf[5]>>2) & 1;
int c_button = (outbuf[5]>>3) & 1;
Serial.print ("joyx= ");
Serial.print (joy_x_axis, DEC);
Serial.print (" joyy=");
Serial.print (joy_y_axis, DEC);
Serial.print (" accx= ");
Serial.print (accel_x_axis, DEC);
Serial.print (" accy= ");
Serial.print (accel_y_axis, DEC);
Serial.print (" accz= ");
Serial.print (accel_z_axis, DEC);
Serial.print (" ");
if (z_button == 0) { Serial.print ("z_button "); }
if (c_button == 0) { Serial.print ("c_button "); }
Serial.print ("\r\n");
//Send the Accelerometer data to the first line
lcd.setCursor (0,0);
lcd.print ("x"); lcd.print (accel_x_axis,DEC);
lcd.setCursor (5,0);
lcd.print ("y"); lcd.print (accel_y_axis,DEC);
lcd.setCursor (10,0);
lcd.print ("z"); lcd.print (accel_z_axis,DEC);
}
else if ((outbuf[5]&0x03)==0x02) { //MP data
int yaw = (((outbuf[5]&0xFC)<<6) + outbuf[2]);
int pitch = (((outbuf[4]&0xFC)<<6) + outbuf[1]);
int roll = (((outbuf[3]&0xFC)<<6) + outbuf[0]);
Serial.print ("yaw= ");
Serial.print (yaw, DEC);
Serial.print (" pitch= ");
Serial.print (pitch, DEC);
Serial.print (" roll= ");
Serial.print (roll, DEC);
Serial.print ("\r\n");
//Send the Gyro data to the second line
lcd.setCursor (0,1);
lcd.print ("w"); lcd.print (yaw,DEC);
lcd.setCursor (5,1);
lcd.print ("r"); lcd.print (roll,DEC);
lcd.setCursor (10,1);
lcd.print ("p"); lcd.print (pitch,DEC);
Serial.print ("yaw= ");
Serial.print (yaw, DEC);
Serial.print (" pitch= ");
Serial.print (pitch, DEC);
Serial.print (" roll= ");
Serial.print (roll, DEC);
Serial.print ("\r\n");
}
}
Mark