I have just discovered the Wii Nunchuck code and am trying to figure out why the data is not updating. I am not using the Wiichuck adapter, I opted wire directly to the Arduino. I am able to receive some kind of data from the nunchuck, but it does not adjust when I tinker with the nunchuck. It remains unchanged (255 255...1 1). I have searched everywhere and there seems to be no one who has addressed this problem.
I am starting to think that the problem lies within the adjustments to with twi.h file suggested on the windmeadow website. I have not found any other references to what should be done with that file. This is just a thought. Can someone please help?
/*==========================================================
Arduino Wii Nunchuck Hack
orginal code provided by windmeadow.com
===========================================================*/
#include <Wire.h> //includes outside library Wire for this sketch
static uint8_t outbuf[6]; //array to store arduino output
int cnt = 0;
int ledPin = 13;
void setup() {
Serial.begin(115200);
Wire.begin(); //join i2c bus with address 0x52
nunchuck_init(); //runs the nunchuck_init function defined below
Serial.print( "Finished setup\n");
}// end of setup function
void nunchuck_init() {
//This function sends the initialization handshake
Wire.beginTransmission (0x52); //transmit to device 0x52
Wire.send (0x40); //sends memory address
Wire.send (0x00); //sends a zero
Wire.endTransmission (); //stop transmitting
}// end of nunchuck_init function
void send_zero(){
Wire.beginTransmission (0x52); //transmit to device 0x52
Wire.send (0x00); //sends a zero
Wire.endTransmission (); //stop transmitting
}//end send_zero function
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++;
}//end while loop
//If we received the 6 bytes, then print them
if (cnt >=5) {
printNunchukData(); //runs print function below
}//end if
cnt = 0;
send_zero(); //send the request for the next bytes
send_zero(); //send the request for the next bytes
send_zero(); //send the request for the next bytes
delay(100); //delay 100 milliseconds
}//end loop function
void printNunchukData(){
/*This function prints the received input data. Accelerometer 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 2*2 */
int joy_x_axis = outbuf[0];
int joy_y_axis = outbuf[1];
int acel_x_axis = outbuf[2] * 2 * 2;
int acel_y_axis = outbuf[3] * 2 * 2;
int acel_z_axis = outbuf[4] * 2 * 2;
int z_button = 0;
int c_button = 0;
/*outbuf[5] contains bits for z and c buttons. It also contains
the least significant bits for the accelerometer data. So each
bit of the outbuf[5] byte has to be checked. */
if ((outbuf[5] >> 0) & 1) {
z_button = 1;
}
if ((outbuf[5] >> 1) & 1) {
c_button = 1;
}
if ((outbuf[5] >> 2) & 1) {
acel_x_axis += 2;
}
if ((outbuf[5] >> 3) & 1) {
acel_x_axis += 1;
}
if ((outbuf[5] >> 4) & 1) {
acel_y_axis += 2;
}
if ((outbuf[5] >> 5) & 1) {
acel_y_axis += 1;
}
if ((outbuf[5] >> 6) & 1) {
acel_z_axis += 2;
}
if ((outbuf[5] >> 7) & 1) {
acel_z_axis += 1;
}
Serial.print (joy_x_axis, DEC);
Serial.print ("\t");
Serial.print (joy_y_axis, DEC);
Serial.print ("\t");
Serial.print (acel_x_axis, DEC);
Serial.print ("\t");
Serial.print (acel_y_axis, DEC);
Serial.print ("\t");
Serial.print (acel_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");
}//end printNunchukData function
char nunchuk_decode_byte (char y) {
//Encode data to a format that most wiimote drivers accept
//only needed if you use one of the regular wiimote drivers
y = (y ^ 0x17) + 0x17;
return y;
}//end nunchuk decode
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++;
}//end while loop
//If we received the 6 bytes, then print them
if (cnt >=5) {
printNunchukData(); //runs print function below
}//end if
cnt = 0;
You request 6 bytes
suppose there are 3 available (less than 6)
the while loop will capture those 3
we dont have more than 4 so we print nothing
and make the counter zero again.
So the thext three readings will overwrite the three reading you allready have
so your code is a bit too optimistic
here some rewrite to make it more robust
void loop()
{
Wire.requestFrom(0x52,6); //request data from nunchuck
unsigned long timer = millis();
cnt = 0;
while (cnt < 6 && millis() - timer < 10000) // wait max 10 seconds to receive those bytes
{
if (Wire.available())
{
outbuf[cnt] = nunchuk_decode_byte (Wire.receive()); // receive byte as an integer
digitalWrite (ledPin, HIGH); // sets the LED on
cnt++;
}
}
//If we received the 6 bytes, then print them
if (cnt == 6)
{
printNunchukData(); //runs print function below
}
else
{
Serial.println(cnt); // debugging purpose
}
//... rest of code
}
Hey guys... I've been reading the forum for quite some time but never registered as i never had the need to ask something. Many people in here are very helpful and up to this day, i've always found what i was looking for. BUT today i have the same problem listed above... I tried with and without pull up resistors but the results are the same. It keeps on sending 255,255 for the joystick and 258,258,258 for the accelerometer. I tried many different codes (including those from the playground,todbot,windmeadow) but no luck.I also tried tweaking the twi.h as suggested but no change whatsoever. The i2c scanner works and recognises the nunchuck but as i said, no change of values when i plug it in... Anyone who has resolved a similar problem? Many thanks in advance to any kind soul who will reply. peace!
P.S. I am using an arduino duemilanove with atmega328 and a nunchuck purchased from gamestop (so it's not original).
But, I have a trick: the problems is print data!
First: Use this library http://arduino.emsley.ca/wiki/Nunchuck
Second: Try to use analogWrite(), like that:
Guys
I have been using both a normal wired genuine Nunchuk and a wireless version from DealExtreme, and my initialisation and read code values are different to yours.
Maybe these might help.
MarkB, that fixed the problem. I am now able to see a change in data. Thanks so much!!! Thanks to everyone who has offered suggestions and advice. Mark, May I ask how did you come across this initialization code?
@SAIcon
I was following the thread for a Balancing Robot, which used the Nunchuk (NC) and Motion Plus (MP).
The codes are modified because the MP receives the data, manipulates it and the controller (Arduino or Wii) then gets it from the MP.
I recall that in amongst all the thread there was a reference to the Wiki Wiimote/Extension Controllers - WiiBrew about Wii, and its in there tied up with the eprom address to read. (Looking at the codes .. it seems its the same as if a MP is plugged in, so maybe its intelligent enough)
Anyway glad it's resolved.
I've got some code for a Nunchuk controlled BOT using the joystick if you want.