Read wii nunchuck on teensy 3.0

Status
Not open for further replies.

Loic

Member
Hi,

I want to make a Wii to USB converter using the teensy 3.0.
I have started with basic code from Tod E. Kurt which works fine on teensy 2.0
But reading the nunchuck on teensy 3.0 does not seem to work probably due to 32Bit which I do not understand (reading i2C seems to work but values read are wrong).

Can anyone help?
Thanks
Loic
Code below:

/*
* NunchuckPrint
*
* 2007 Tod E. Kurt, http://todbot.com/blog/
*
* The Wii Nunchuck reading code is taken from Windmeadow Labs
* http://www.windmeadow.com/node/42
*/

#include <Wire.h>

void setup()
{
Serial.begin(19200);
nunchuck_init(); // send the initilization handshake
Serial.print ("Finished setup\n");
}

void loop()
{
nunchuck_get_data();
nunchuck_print_data();
delay(100);
}


//
// Nunchuck functions
//

static uint8_t nunchuck_buf[6]; // array to store nunchuck data,

// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends sent a zero.
Wire.endTransmission(); // stop transmitting
}

// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}

// Receive data back from the nunchuck,
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}

// 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 nunchuck_print_data()
{
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte nunchuck_buf[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 ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;

if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
if ((nunchuck_buf[5] >> 3) & 1)
accel_x_axis += 1;

if ((nunchuck_buf[5] >> 4) & 1)
accel_y_axis += 2;
if ((nunchuck_buf[5] >> 5) & 1)
accel_y_axis += 1;

if ((nunchuck_buf[5] >> 6) & 1)
accel_z_axis += 2;
if ((nunchuck_buf[5] >> 7) & 1)
accel_z_axis += 1;

Serial.print(i,DEC);
Serial.print("\t");

Serial.print("joy:");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(" \t");

Serial.print("acc:");
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print("\t");

Serial.print("but:");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);

Serial.print("\r\n"); // newline
i++;
}

// 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;
}
 
I added 2k pullups on SDA and SCL and I still get wrong values.
Anyone got Nunchuck to work on a teensy 3.0?
 
I needed delayMicroseconds(10) between requestFrom(...) and reading the returned data. Without the delay, I got data values, they were wrong.

I put this on my TO-DO list to investigate.... It might be Teensy 3.0 is simply faster and the system needs delay, but then again, it might be a timing problem with the Wire library. I'll hook up the hardware and investigate.

I have a Wii nunchuck. But I don't have the cable or connector. Could you post a link to what hardware I should get to connect to the nunchuck?
 
I clipped off the Nunchuk connector from its cable, and connected the four wires directly:
- GREEN is SDA, to A4
- YELLOW is SCK, to A5
- RED power to 3.3v (mine tolerates 5v fine)
- WHITE ground.
Note that some OEM nunchuks need a different initialization sequence from the Wii versions, YMMV.
 
I bought an extension cord and cut it in half in order not to destroy the nunchuck and use a wii fighting stick.
In order to get the fighting stick to work (is like the classic controller) with the teensy 3.0 I needed to change the microsecond delay to 20ms.
 
Nunchuck on teensy 3.1

Spend an hour getting the nunchuck to work with teensy 3.1 :p, here's what i found out:

- no pullups required on 3.1
- set the cpu speed down to 48MHz to get any data related to the gyro
- NUNCHUK_TWI_DELAY_MICROSEC is set to 5

Hope its helpful.
 
Status
Not open for further replies.
Back
Top