Arduino Mega & nunchuck Interfacing.

I’m an Arduino user, and just bought an Arduino Mega board. I’d like to interface it with a Wii Nunchuck. However, so far, i’m facing problems.

The script uploads to the mega, but when Serial Monitor is opened, there is no data sent from the Nunchuck.

The Serial Monitor reads:
“Nunchuck Ready”
0 joy:0,0 acc:0,0,0 but:0,0
…and so on.

I’ve learned that I2c connections with the mega, are different. That it uses the communications input pins - SDA 20 & SCL 21, instead of pins 4 & 5 on the Arduino Deci.

I’ve rigged up the mega just fine:
-jump leads going from the wiichuck adapter (mounted on a breadboard) to mega:

  • 5v on mega to +ive on the wiichuck
  • GND on the mega to -ive on the wiichuck
  • SCL 21 on the mega to c on the wiichuck
  • SDA 20 on the mega to d on the wiichuck

the script I used is:

#include <Wire.h>;
 
 
void setup(){
 
Serial.begin(19200);
 
nunchuck_setpowerpins();
 
nunchuck_init();
 
Serial.print("Nunchuck ready\n");
 
}
 
 
 
void loop(){
 
nunchuck_get_data();
 
nunchuck_print_data();
 
delay(1000);
 
}
 
//======================================================================================================================================================================================================//
 
//Do not modify!!!!!!!!
 
//======================================================================================================================================================================================================//
 
 
 
//
 
// Nunchuck functions
 
//
 
 
static uint8_t nunchuck_buf[6]; // array to store nunchuck data,
 
 
// Uses port C (analog in) pins as power & ground for Nunchuck
 
static void nunchuck_setpowerpins()
 
{
 
#define pwrpin PC3
 
#define gndpin PC2
 
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
 
}
 
 
// 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,
 
// returns 1 on successful read. returns 0 on failure
 
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;
 
}
 
 
// returns zbutton state: 1=pressed, 0=notpressed
 
int nunchuck_zbutton()
 
{
 
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo
 
}
 
 
// returns zbutton state: 1=pressed, 0=notpressed
 
int nunchuck_cbutton()
 
{
 
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo
 
}
 
 
// returns value of x-axis joystick
 
int nunchuck_joyx()
 
{
 
return nunchuck_buf[0];
 
}
 
 
// returns value of y-axis joystick
 
int nunchuck_joyy()
 
{
 
return nunchuck_buf[1];
 
}
 
 
// returns value of x-axis accelerometer
 
int nunchuck_accelx()
 
{
 
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data
 
}
 
 
// returns value of y-axis accelerometer
 
int nunchuck_accely()
 
{
 
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data
 
}
 
 
// returns value of z-axis accelerometer
 
int nunchuck_accelz()
 
{
 
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data
 
}

Is the ‘wire’ sketch compatible with the mega?
Am I missing something?
Do I need to set the script to read communication pins 20 & 21?
I’m confuzzled. :-/

First thing you need to do is in the upper right hand corner of your first post to click Modify. Then you need to highlight your code then click on the # button in the top of the message field.

Try replacing the 5v with 3.3v

tried both 3.3v & 5v. Nunchuck not frazzled :stuck_out_tongue:

The code I used creates voltage in analogue pins 2&3. But I guess the Mega doesn’t need that bit of code, so it’s superfluous.

The only other bit of code is the ‘wire’ sketch that initiates i2c. Not sure about this bit… :-/

Anyway, I appreciate your kindness in helping me with advice. Hope you can help.

So, it appears that the Arduino Mega has problems using i2c with pins 20 & 21:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1254797394/0

Has anyone had any experience using arduino mega with i2c?

So when I pull out the jumper leads from the SDA & SCL pins during Serial Monitor, it stops the data loop. I think SDA & SCL function, but the nunchuck isn't being read.

Any suggestions? kthnxbai

Anybody know the command for SDA 20 & SCL 21 on the Arduino Mega?

I looked at the datasheet: http://www.atmel.com/dyn/resources/prod_documents/doc2549.pdf But it doesn't make any sense to me as i've not been taught to read a datasheet.

Thnx

I have the same problem. Someone has solved?

Same Problem here :frowning: With the code above my output is still the same!

1 joy:255,255 acc:258,258,258 but:1,1

any advice?

No Solution yet :(

I need to spend a lot of time figuring out I2C communication with the mega. But it's Valentine's weekend, and my wife might get pissy ;)

some one help, i had a deci. as well and my wired nunchuck worked and now it doesnt work on the mega

Hey all, Just got the Nunchuck controller working on the Arduino Mega:

Make sure you have (-) wired to ground (i.e. don't use the standard 4 pins in a line on the header) and then (+) to 3.3v Then have pin3 "d" to SDA20 and pin4 "c" to SCL 21.

i have it wired the same way as u said and i still cant get it to work, can u post ur code, maybe its the code im using

@StevenH Is the resistor for that LED hiding, or do you have something against that pin?

pin 13 has a built in 1k resister (i think its 1k, that or its 10k)

I can confirm that I have wired up the mega exactly as in the above picture by StevenH. It does not work with the code in this post.

Anyone have any success? And can provide a picture/video, and code they used? Otherwise it's still just a red herring.

i rule of thumb has been pic or i didnt happen. but im going to have to say video or it didnt happen.......

Guys, am really sorry to only just get back to this now... I wasn't being notified of replies...

The code and blogpost is here.

I got the nunchuck_funcs.h header file from here.

Let me confirm that I didn't modify that header when I get home tonight.

And as for LED driving... I've been powering them directly from the digital pins? I take it that's a bad thing?

Excuse my double-post, here’s the code I use that works perfectly.
Please ensure you have your nunchuck connected properly. I’ll record a video if you still are unable to get it to work.

#include <Wire.h>
#include <WProgram.h>

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
static 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()"
static void nunchuck_send_request()
{
    Wire.beginTransmission(0x52);// transmit to device 0x52
    Wire.send(0x00);// sends one byte
    Wire.endTransmission();// stop transmitting
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
static char nunchuk_decode_byte (char x)
{
    x = (x ^ 0x17) + 0x17;
    return x;
}

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

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

int loop_cnt=0;

void setup()
{
    Serial.begin(19200);
    nunchuck_init();
}

void loop()
{
    if( loop_cnt > 1000 ) { // every 100 msecs get new data
        loop_cnt = 0;           
        nunchuck_get_data();
        nunchuck_print_data();
    }
    loop_cnt++;
}

Hey,

I uploaded the code & nunchuck_funcs.h code, wired up the Mega as in the pic.

Still not working. Just streaming zeros in serial monitor. I'm using Aduino software 0017.

Getting frustrated. Just shouted at the dog. lol.

Anyone else have any luck? I thought Arduino 0017 had nunchuck_funcs.h already built in?