Aujourd'hui j'ai regardé comment interfacer un nunchuck wii avec ma teensy ++ 2.
Sur la vidéo l'axe x et y du stick contrôle 2 servos, et les boutons c et z 2 leds.
Voici un bout de code qui ma bien aidé: (pour les nunchuck non officiel ex:ebay ne fonctionne pas avec un original)
/*
** This code works with a Nyko Kama Wireless nunchuk and
** a black wired nunchuk. This code has not been tested
** with any other nunchuk.
**
** To use a Wired Nunchuk just comment out the #define for WIRELESS_KAMA_NUNCHUK.
** To use a Wireless Nyko Kama Nunchuk uncomment the #define for WIRELESS_KAMA_NUNCHUK.
**
*/
#include <Wire.h>
/* Debug definitions */
#define PRINT_NUNCHUK_DATA
#define WIRELESS_KAMA_NUNCHUK /* Comment out this line if using a Wired Nunchuk */
#define READ_DELAY 5 /* (milliseconds) - Increase this number to not read the nunchuk data so fast */
#define SERIAL_BAUD_RATE 115200
unsigned int joy_x = 0;
unsigned int joy_y = 0;
unsigned int acc_x = 0;
unsigned int acc_y = 0;
unsigned int acc_z = 0;
unsigned int btn_c = 0;
unsigned int btn_z = 0;
unsigned long previous_read_time = 0;
void setup()
{
Serial.begin(SERIAL_BAUD_RATE);
Wire.begin();
initialize_nunchuk();
previous_read_time = millis();
}
void loop()
{
if (millis() - previous_read_time > READ_DELAY)
{
read_nunchuk_data();
previous_read_time = millis();
}
}
void read_nunchuk_data()
{
unsigned int buffer[6];
byte buffer_index = 0;
Wire.beginTransmission(0x52);
Wire.send(0x00);
Wire.endTransmission();
#ifndef WIRELESS_KAMA_NUNCHUK
delay(1); /* This delay is required for a wired nunchuk otherwise the data will appear maxed out */
#endif
Wire.requestFrom(0x52, 6);
while(Wire.available())
{
buffer[buffer_index] = Wire.receive();
buffer_index++;
}
joy_x = buffer[0];
joy_y = buffer[1];
acc_x = ((buffer[2] << 2) | ((buffer[5] & 0x0C) >> 2) & 0x03FF);
acc_y = ((buffer[3] << 2) | ((buffer[5] & 0x30) >> 4) & 0x03FF);
acc_z = ((buffer[4] << 2) | ((buffer[5] & 0xC0) >> 6) & 0x03FF);
btn_c = !((buffer[5] & 0x02) >> 1);
btn_z = !(buffer[5] & 0x01);
#ifdef PRINT_NUNCHUK_DATA
Serial.print(" "); Serial.print(joy_x);
Serial.print(" "); Serial.print(joy_y);
Serial.print(" "); Serial.print(acc_x);
Serial.print(" "); Serial.print(acc_y);
Serial.print(" "); Serial.print(acc_z);
Serial.print(" "); Serial.print(btn_c);
Serial.print(" "); Serial.print(btn_z);
Serial.println("");
#endif
}
void initialize_nunchuk()
{
#ifdef WIRELESS_KAMA_NUNCHUK
Wire.beginTransmission(0x52);
Wire.send (0xF0);
Wire.send (0x55);
Wire.endTransmission();
delay(30);
Wire.beginTransmission (0x52);
Wire.send (0xFB);
Wire.send (0x00);
Wire.endTransmission();
delay(30);
Wire.beginTransmission(0x52);
Wire.send (0xFA);
Wire.endTransmission();
delay(30);
Wire.requestFrom(0x52, 6);
Serial.print("Device ID is: ");
while(Wire.available())
{
byte c = Wire.receive();
Serial.print(c, HEX);
Serial.print(" ");
}
delay(30);
#else
Wire.beginTransmission(0x52);
Wire.send (0x40);
Wire.send (0x00);
Wire.endTransmission();
delay(30);
#endif
#ifdef PRINT_NUNCHUK_DATA
Serial.println("");
Serial.println(" X-axis Y-axis X-accel Y-accel Z-accel C-button Z-button");#endif
}
Fonctionne sur les copies ainsi que pour les nunchuck sans fils.
Voici un code qui devrai marcher avec les nunchuck officiel (non testé):
#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; void setup () { beginSerial (19200); Serial.print ("Finished setup\n"); Wire.begin (); // join i2c bus with address 0x52 nunchuck_init (); // send the initilization handshake } void nunchuck_init () { Wire.beginTransmission (0x52); // transmit to device 0x52 Wire.send (0x40); // sends memory address Wire.send (0x00); // sends sent a zero. Wire.endTransmission (); // stop transmitting } void send_zero () { Wire.beginTransmission (0x52); // transmit to device 0x52 Wire.send (0x00); // sends one byte Wire.endTransmission (); // stop transmitting } void loop () { Wire.requestFrom (0x52, 6); // request data from nunchuck while (Wire.available ()) { outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer digitalWrite (ledPin, HIGH); // sets the LED on cnt++; } // If we recieved the 6 bytes, then go print them if (cnt >= 5) { print (); } cnt = 0; send_zero (); // send the request for next bytes delay (100); } // Print the input data we have recieved // accel data is 10 bits long // so we read 8 bits, then we have to add // on the last 2 bits. That is why I // multiply them by 2 * 2 void print () { int joy_x_axis = outbuf[0]; int joy_y_axis = outbuf[1]; int accel_x_axis = outbuf[2] * 2 * 2; int accel_y_axis = outbuf[3] * 2 * 2; int accel_z_axis = outbuf[4] * 2 * 2; int z_button = 0; int c_button = 0; // byte outbuf[5] contains bits for z and c buttons // it also contains the least significant bits for the accelerometer data // so we have to check each bit of byte outbuf[5] if ((outbuf[5] >> 0) & 1) { z_button = 1; } if ((outbuf[5] >> 1) & 1) { c_button = 1; } if ((outbuf[5] >> 2) & 1) { accel_x_axis += 2; } if ((outbuf[5] >> 3) & 1) { accel_x_axis += 1; } if ((outbuf[5] >> 4) & 1) { accel_y_axis += 2; } if ((outbuf[5] >> 5) & 1) { accel_y_axis += 1; } if ((outbuf[5] >> 6) & 1) { accel_z_axis += 2; } if ((outbuf[5] >> 7) & 1) { accel_z_axis += 1; } 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 ("\t"); Serial.print ("\r\n"); } // Encode data to format that most wiimote drivers except // only needed if you use one of the regular wiimote drivers char nunchuk_decode_byte (char x) { x = (x ^ 0x17) + 0x17; return x; }