■
内蔵RCの8MHzで動くArduinoに、Wiiのモーションプラスとヌンチャクをつないで値を取ることができた。
Wiimote/Extension ControllerにWiiの拡張コントローラの資料がある。「Nunchuck pass-through mode」にするとモーションプラスとヌンチャクの両方の値が取れる。
現状のスケッチはこれ。
/** http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus **/ #include <Wire.h> #include <string.h> #undef int #include <stdio.h> uint8_t outbuf[6]; // array to store arduino output int cnt = 0; int ledPin = 13; int yaw, pitch, roll; //three axes int yaw0, pitch0, roll0; //calibration zeroes void setup() { Serial.begin(19200); Wire.begin (); // join i2c bus with address 0x52 nunchuck_init (); // send the initilization handshake delay(100); calibrate_zeroes(); //原点調整 pinMode(ledPin, OUTPUT); // 出力に設定 Serial.print("Finished setup\n"); } void nunchuck_init () { Wire.beginTransmission(0x53); //WM+ starts out deactivated at address 0x53 Wire.send(0xfe); //send 0x04 to address 0xFE to activate WM+ Wire.send(0x05); //Nunchuck pass-through mode Wire.endTransmission(); //WM+ jumps to address 0x52 and is now active } void send_zero () { Wire.beginTransmission (0x52); // transmit to device 0x52 Wire.send (0x00); // sends one byte Wire.endTransmission (); // stop transmitting } /** * 原点調整 */ void calibrate_zeroes() { int i=0; yaw0 = 0; pitch0 = 0; roll0 = 0; while (i<8) { send_zero(); delay (100); Wire.requestFrom(0x52,6); for (int j=0;j<6;j++){ outbuf[j] = Wire.receive(); cnt++; } if (cnt >= 5 && (outbuf[5] & 3) == 2) { //Wii Motion Plus 14bit中の上位8ビットを取得する yaw0 += ((outbuf[3] >> 2) << 2) + (outbuf[0]>>6); //average 8 readings for each zero pitch0 += ((outbuf[4] >> 2) << 2) + (outbuf[1]>>6); roll0 += ((outbuf[5] >> 2) << 2) + (outbuf[2]>>6); i++; } cnt = 0; } yaw0 /= 8; pitch0 /= 8; roll0 /= 8; } void loop() { Wire.requestFrom (0x52, 6); // request data from nunchuck while (Wire.available ()) { outbuf[cnt] = Wire.receive (); // receive byte as an integer digitalWrite (ledPin, HIGH); // sets the LED on cnt++; } if (cnt >= 5 && outbuf[0] > 0 && outbuf[1] > 0 && outbuf[2] > 0) { //頭3バイトが0は無視する if ((outbuf[5] & 3) == 0) { //Nunchuck pass-through mode print_nunchuck(); } else if ((outbuf[5] & 3) == 2) { //Wii Motion Plus print_mplus(); } } cnt = 0; send_zero (); // send the request for next bytes delay (100); } void print_mplus() { yaw = ((outbuf[3] >> 2) << 2) + (outbuf[0]>>6) - yaw0; //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus pitch = ((outbuf[4] >> 2) << 2) + (outbuf[1]>>6) - pitch0; //for info on what each byte represents roll = ((outbuf[5] >> 2) << 2) + (outbuf[2]>>6) - roll0; Serial.print ("[M+]\t"); Serial.print (yaw, DEC); Serial.print ("\t"); Serial.print (pitch, DEC); Serial.print ("\t"); Serial.print (roll, DEC); Serial.print ("\t"); } void print_nunchuck() { int joy_x_axis = outbuf[0]; int joy_y_axis = outbuf[1]; int accel_x_axis = outbuf[2]; int accel_y_axis = outbuf[3]; int accel_z_axis = (outbuf[4] >> 2) << 2; int z_button = 0; int c_button = 0; if ((outbuf[5] >> 2) & 1) { z_button = 1; } if ((outbuf[5] >> 3) & 1) { c_button = 1; } if ((outbuf[5] >> 7) & 1) { accel_z_axis ++; } Serial.print ("[NC]\t"); Serial.print (joy_x_axis, DEC); Serial.print ("\t"); Serial.print (joy_y_axis, DEC); Serial.print ("\t"); Serial.print (accel_x_axis, DEC); Serial.print ("\t"); Serial.print (accel_y_axis, DEC); Serial.print ("\t"); Serial.print (accel_z_axis, DEC); Serial.print ("\t"); Serial.print (z_button, DEC); Serial.print ("\t"); Serial.print (c_button, DEC); Serial.print ("\r\n"); }