Go Down

Topic: Cheap ebay nunchuck NOT working (Read 15899 times) previous topic - next topic

ntgr

Hi.
I bought cheap nunchuck from China and it would not work whatever i do. :-[
Firstly i tested it with an original wii system and the nunchuck was working fine.
But when i try to connect it in my arduino...i get nothing.
Any one got an idea why ??
Thnx in advance.

digimike

Do you have it wired right? What code are you using?

We need more information here before we can speculate on the problem.

ntgr

Thnx digimike for your reply.
Quote
Do you have it wired right? What code are you using?

Yes i m sure that is wired right. I also open it and take some readings with the multimeter in the accelerometer exit.
The code im using is http://todbot.com/arduino/sketches/NunchuckPrint/. I v also tested almost every code i v found in the internet .

ntgr

#3
Jan 30, 2010, 12:46 am Last Edit: Jan 30, 2010, 12:47 am by ntgr Reason: 1
Here is an image of the board.
http://img96.imageshack.us/i/p1142482.jpg/

crimony

#4
Jan 30, 2010, 11:02 pm Last Edit: Jan 30, 2010, 11:08 pm by crimony Reason: 1
Wii "Extension Controllers" other than the original Nunchuck have an initialisation sequence which differs from the one found in the nunchuck library originally designed by Tim Hirzel. I found this out when I tried to use a Wii "Classic Controller".

To initialise anything other than an OEM Nunchuck, you need to replace this in the init call:

Code: [Select]
   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


With this:

Code: [Select]
byte cnt;

Wire.begin();
           
// init controller
delay(1);
Wire.beginTransmission(0x52);      // device address
Wire.send(0xF0);                    // 1st initialisation register
Wire.send(0x55);                    // 1st initialisation value
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0xFB);                    // 2nd initialisation register
Wire.send(0x00);                    // 2nd initialisation value
Wire.endTransmission();
delay(1);
           
// read the extension type from the register block        
Wire.beginTransmission(0x52);
Wire.send(0xFA);                    // extension type register
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.requestFrom(0x52, 6);               // request data from controller
for (cnt = 0; cnt < 6; cnt++) {
   if (Wire.available()) {
       ctrlr_type[cnt] = Wire.receive(); // Should be 0x0000 A420 0101 for Classic Controller, 0x0000 A420 0000 for nunchuck
   }
}
Wire.endTransmission();
delay(1);
           
// send the crypto key (zeros), in 3 blocks of 6, 6 & 4.
Wire.beginTransmission(0x52);
Wire.send(0xF0);                    // crypto key command register
Wire.send(0xAA);                    // sends crypto enable notice
Wire.endTransmission();
delay(1);
Wire.beginTransmission(0x52);
Wire.send(0x40);                    // crypto key data address
for (cnt = 0; cnt < 6; cnt++) {
   Wire.send(0x00);                    // sends 1st key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);                    // sends memory address
for (cnt = 6; cnt < 12; cnt++) {
   Wire.send(0x00);                    // sends 2nd key block (zeros)
}
Wire.endTransmission();
Wire.beginTransmission(0x52);
Wire.send(0x40);                    // sends memory address
for (cnt = 12; cnt < 16; cnt++) {
   Wire.send(0x00);                    // sends 3rd key block (zeros)
}
Wire.endTransmission();
delay(1);
// end device init


Also somewhere you'll need to store the ctrlr_type that you collected in the routine, its type is (make it global or whatever you like):

Code: [Select]
uint8_t ctrlr_type[6];

This works for my Classic Controller and my nunchuck, even though the old code also worked for my nunchuck.

The inspiration for this code came from the wiibrew site, http://wiibrew.org/wiki/Wiimote#Extension_Controllers

ntgr

crimony ..
YES !!! YES !!! YES !!!  :)
Working !!!!
Many many thnx ....
You r THE BEST ...
THNX..

turbosharp

#6
Feb 17, 2010, 12:24 pm Last Edit: Feb 17, 2010, 01:31 pm by turbosharp Reason: 1
I have a Dealextreme nunchuck and with this modification of the code it now works great! thanks crimony!

however i didnt get it to work with the complimentary filter implimentation done by ardvark http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253202298

please help out

PaulS

Quote
however i didnt get it to work...please help out


It would be oh so much easier if you gave us the tiniest little hint what didn't work.

Did the cheap ebay nunchuck not work? Did the code not work? Did the code not compile correctly? What does YOUR code look like?

turbosharp

Of course Paul.

problem

My nunchuck dont work with the complimentary filter code

I cant get readings => problems with the Ic2 Communications

Suggestion
as mention by crimony, "Wii "Extension Controllers" other than the original Nunchuck have an initialisation sequence which differs from the one found in the nunchuck library originally designed by Tim Hirzel"

I succesfully manage to change the nunchuck_funcs.h library done by todbot. So the nunchuck works fine.. just different  :)

So I think my problem is in the initialisation sequence
. I've tryed the same approach but cant get it to work on the complimentary filter code.


Summary
Change the initialisation sequence in this thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253202298/0 to crimonys solution above


Tobes

Just registered to post in here. I bought a cheap nunchuck solely to use it for my arduino. I spent 3 hours trying to get it to work and thought I'd wasted my money, but the code here made it work! Thanks crimony. You're a lifesaver.

dcahveind

i love you crimony

i had the same headache and now it works beautifully

manut

hello,
I also bought the cheap wii nunchuck from china, and I'd like to know how to connect it because there is 5 wires(white, black, red, yellow, green), I think the original one has 4..
thanx

kuusmam

Hi,

I have the same problem , though maine came ftom amzone uk.  The remote is working , but nunchuk not.

I went through this site , but as not any expert , hard to understand what can possibly be done ?

Can anyone please describe the steps.

Tnx

jdc

Hi all,

I have an issue with the low costs nunchucks from China...

I have tried the workaround from crimony and updated the init block

Here the code I'm using:
Code: [Select]

#include <Wire.h>

void setup()
{
 Serial.begin(19200);
 Serial.print ("Begin of setup\n");
 nunchuck_setpowerpins(); // use analog pins 2&3 as fake gnd & pwr
 nunchuck_init(); // send the initilization handshake
 Serial.print ("End of 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,
uint8_t ctrlr_type[6];


// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
   DDRC |= _BV(pwrpin) | _BV(gndpin);
   PORTC &=~ _BV(gndpin);
   PORTC |=  _BV(pwrpin);
   delay(100);  // wait for things to stabilize        
}

// 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*/
 
 Serial.print ("Begin nunchuck init\n");
 byte cnt;
 Wire.begin();

 Serial.print ("Step 1\n");
 // init controller
 delay(1);
 Wire.beginTransmission(0x52);      // device address
 Wire.send(0xF0);                    // 1st initialisation register
 Wire.send(0x55);                    // 1st initialisation value
 Wire.endTransmission();
 delay(1);
 Wire.beginTransmission(0x52);
 Wire.send(0xFB);                    // 2nd initialisation register
 Wire.send(0x00);                    // 2nd initialisation value
 Wire.endTransmission();
 delay(1);
           
 Serial.print ("Step 2\n");
 // read the extension type from the register block        
 Wire.beginTransmission(0x52);
 Wire.send(0xFA);                    // extension type register
 Wire.endTransmission();
 Wire.beginTransmission(0x52);
 Wire.requestFrom(0x52, 6);               // request data from controller
 for (cnt = 0; cnt < 6; cnt++) {
   if (Wire.available()) {
     ctrlr_type[cnt] = Wire.receive(); // Should be 0x0000 A420 0101 for Classic Controller, 0x0000 A420 0000 for nunchuck
   }
 }
 Wire.endTransmission();
 delay(1);
           
 Serial.print ("Step 3\n");
 // send the crypto key (zeros), in 3 blocks of 6, 6 & 4.
 Wire.beginTransmission(0x52);
 Wire.send(0xF0);                    // crypto key command register
 Wire.send(0xAA);                    // sends crypto enable notice
 Wire.endTransmission();
 delay(1);
 Wire.beginTransmission(0x52);
 Wire.send(0x40);                    // crypto key data address
 for (cnt = 0; cnt < 6; cnt++) {
     Wire.send(0x00);                    // sends 1st key block (zeros)
 }
 Wire.endTransmission();
 Wire.beginTransmission(0x52);
 Wire.send(0x40);                    // sends memory address
 for (cnt = 6; cnt < 12; cnt++) {
     Wire.send(0x00);                    // sends 2nd key block (zeros)
 }
 Wire.endTransmission();
 Wire.beginTransmission(0x52);
 Wire.send(0x40);                    // sends memory address
 for (cnt = 12; cnt < 16; cnt++) {
   Wire.send(0x00);                    // sends 3rd key block (zeros)
 }
 Wire.endTransmission();
 delay(1);
 // end device init
}

// 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;
}


When I upload the code to the board, no error is showned, but on the serial monitor I see only:

Begin of setup
Begin nunchuck init
Step 1

after that the sketch seems to be stopped.

If I unplug the data wire from the nunchuck then the sketch start again running

Can anyone help?

Thanks a lot
jdc

jdc

HEllo

Some more information regarding my issue mentionned in my previous post.

It seems the
Quote
Wire.endTransmission();
has something to do with my issue.
When I comment the line, the sketch continue to the next steps but at the end it is still not working properly.

If anyone can help ...  :)

Thanks a lot

jdc

Go Up