Arduino and Nunchuck?

Hi,

I have a small 'problem' (well, again).
I now try for almost two days to get my nunchuck running on the Arduino, but so far i had no luck...
I was following this 'tutorial':
http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/

and also bought this adapter, soldered it and connected it with the following Pins:
Analog 5 - 2 (c,d,+,-) and fiddled arround with the library a bit as well as it didnt run out of the box for me (had to add a few includes)...
But each time the Code reaches EndTransmission it 'hangs' - nothing works anymore...
Needless to say that i havent got a single signal from the nunchuck till now ><

Any ideas of what to do? I cant seem to find anything anymore i could try besides ruining the cable of the nunchuck and plugging it directly into the arduino..

Try running the self contained nunchuck sketch here: http://www.windmeadow.com/node/42

If that still doesn' t work you may have a problem with your connections. If it does work then the problem is with your library and we can have a look at fixing that.

I didn't have much trouble with todbot's code, but I noticed some of the data he cracks out is not quite right.

This weekend, I hope to post my full WiiChuck/WiiClassic/ADXL330 libraries. I've grabbed todbot's code and also two other library sources (including the one mem linked), to make my own. I separated out the "hardware" concerns from the "geometry" concerns, so that things are nicely separated and streamlined. Also, some calibration helpers.

Later, I'd like to find and blend in some gyro-correction to account for drift or dead-reckoned yaw. It could help those building 6dof gadgets like bot brains.

sounds great - i think i will wait with my nunchuck then till you release that stuff :0)

mem: There is not much to be done wrong with cables if you use (like i do) the adapter.. its just strange it doesnt work... it might be that the adapter is not right since there are no real 'rings' arround the wholes to solder the pins in it.. yet i guess the way it is soldered is ok...

Alright.. i have been fizzling with that Wiimote a bit again and now are at this point again that EndTransmission 'hangs'

I use the following code:

#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 ()
{
  
  Serial.println("PC3");  
byte pwrpin = PC3;
  Serial.println("PC2");
byte gndpin = PC2;
  Serial.println("DDR");
DDRC |= _BV(pwrpin) | _BV(gndpin);
  Serial.println("RTC1");
PORTC &=~ _BV(gndpin);
  Serial.println("RTC2");
PORTC |= _BV(pwrpin);
  Serial.println("DEL");
delay(100); // wait for things to stabilize  
  
  Serial.println("BTR");
  
  Wire.beginTransmission (0x52);      // transmit to device 0x52
  Serial.println("TR1");
  Wire.send (0x40);            // sends memory address
  Serial.println("TR2") ; 
  Wire.send (0x00);            // sends sent a zero.  
  Serial.println("BET")  ;
  Wire.endTransmission ();      // stop transmitting
  Serial.println("AET")  ;
}

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

It gets executes till 'BET".
My Nunchuck is wired:
c Analog in 5
d Analog in 4

  • Analog in 3
  • Analog in 2

Is there some thing i still miss?

Hi Nachtwind,

Coincidentally I had the exact same problem yesterday and found that the nunchuck wasn't being powered.

Can you make the following changes to your code? This solved the problem for me.

void setup ()
{
  beginSerial (19200);
  Serial.print ("Finished setup\n");
  [glow] // Wire.begin ();[/glow] // REMOVE OR COMMENT THIS
  nunchuck_init (); // send the initilization handshake
}

... and ...

void
nunchuck_init ()
{

  Serial.println("PC3");
  byte pwrpin = PC3;
  Serial.println("PC2");
  byte gndpin = PC2;
  Serial.println("DDR");
  DDRC |= _BV(pwrpin) | _BV(gndpin);
  Serial.println("RTC1");
  PORTC &=~ _BV(gndpin);
  Serial.println("RTC2");
  PORTC |= _BV(pwrpin);
  Serial.println("DEL");
  delay(100); // wait for things to stabilize

  Serial.println("BTR");
  [glow]Wire.begin();[/glow] // And place it here instead..

  Wire.beginTransmission (0x52);      // transmit to device 0x52
  Serial.println("TR1");
  Wire.send (0x40);            // sends memory address
  Serial.println("TR2") ;
  Wire.send (0x00);            // sends sent a zero.
  Serial.println("BET")  ;
  Wire.endTransmission ();      // stop transmitting
  Serial.println("AET")  ;
}

If you follow Todbot's header file http://todbot.com/blinkm/example_code/BlinkMChuck/nunchuck_funcs.h you'll see he is setting the power pins before calling Wire.begin().

BTW, I was using the WiiChuckClass from the playground Arduino Playground - WiiChuckClass and found it doesn't initialise the power pins at all (unless I'm missing something). My code was hanging at endTransmission too. I added the init routines from Todbot's code and it worked like a champ :slight_smile:

Thanks for your idea, but i have solved the problem a slightly different way - i cut off the connector and did it the simple way of connecting the cables directly.. that worked like a charm...