Skip to content

Commit

Permalink
updates to the nunchuck code, to support the arduino mega, and to sup…
Browse files Browse the repository at this point in the history
…port the new initialization sequence for the cheap knock-off nunchucks from ebay
  • Loading branch information
matthewbeckler committed Aug 18, 2012
1 parent 254a3c7 commit 6988cad
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 27 deletions.
5 changes: 5 additions & 0 deletions Nunchuck/README
Expand Up @@ -3,6 +3,11 @@ This is an arduino library for using the Wii Nunchuck.
It uses Peter Fleury's excellent i2c library instead of Wire.h,
slightly modified to include a timeout feature on initialization.

Recent updates:
August 18, 2012 - Added support for the Arduino Mega, which has a different RBx pin for the nunchuck select.
August 11, 2012 - Changed initialization bytes to support knock-off nunchucks
January 18, 2012 - Arduino 1.0 compatability fix

Adam Wolf and Matthew Beckler
Wayne and Layne, LLC
http://wayneandlayne.com/projects/video-game-shield/
Expand Down
@@ -1,8 +1,9 @@
/*
Arduino sketch to demonstrate interfacing with a Nintendo Wii Nunchuck.
Arduino sketch to demonstrate interfacing with a Nintendo Wii Nunchuck. It will print the nunchuck information from P1 every second, to the serial terminal at 9600 baud.
Created by Adam Wolf and Matthew Beckler
Wayne and Layne, LLC - http://wayneandlayne.com/projects/video-game-shield/
Last updated: January 16, 2010
Recent updates:
August 18, 2012 - Changed file extension to .ino for Arduino 1.0
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
34 changes: 19 additions & 15 deletions Nunchuck/nunchuck.cpp
@@ -1,7 +1,10 @@
/*
Nunchuck.cpp - Library for Nintendo Wii Nunchuck
Created by Adam Wolf and Matthew Beckler (Wayne and Layne, LLC)
Last updated: January 18, 2012 - Arduino 1.0 compatability fix
Recent updates:
August 18, 2012 - Added support for the Arduino Mega, which has a different RBx pin for the nunchuck select.
August 11, 2012 - Changed initialization bytes to support knock-off nunchucks
January 18, 2012 - Arduino 1.0 compatability fix
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -17,8 +20,6 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
http://www.arduino.cc/playground/Main/WiiClassicController
*/

#if defined(ARDUINO) && ARDUINO >= 100
Expand Down Expand Up @@ -53,7 +54,7 @@ unsigned char Nunchuck::begin(unsigned char which_nunchuck)
joy_y_scaled_min = NUNCHUCK_JOY_Y_SCALED_MIN;
joy_y_scaled_max = NUNCHUCK_JOY_Y_SCALED_MAX;

DDRB |= 0x10; // set DDRB4 bit = make it an output (used for nunchuck select)
NUNCHUCK_SELECT_SET_OUTPUT_DIR;
this_nunchuck = which_nunchuck;

if (this_nunchuck == NUNCHUCK_PLAYER_2)
Expand All @@ -62,14 +63,25 @@ unsigned char Nunchuck::begin(unsigned char which_nunchuck)
NUNCHUCK_SELECT_P1;

i2cmaster::i2c_init(); // this is non-blocking, it just sets up the baud rate generator and internal pullups

if (i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 10) == 1)
{
// could not access device
return 1;
}
i2cmaster::i2c_write(0x40);

// this new init bytes come from this arduino.cc forum post:
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264805255/4#4
i2cmaster::i2c_write(0xF0);
i2cmaster::i2c_write(0x55);
i2cmaster::i2c_stop();
delay(1);

i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 10);
i2cmaster::i2c_write(0xFB);
i2cmaster::i2c_write(0x00);
i2cmaster::i2c_stop();
delay(1);

return 0;
}
Expand All @@ -90,9 +102,9 @@ void Nunchuck::update()
i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_READ, 0xFFFF);
for (unsigned char i = 0; i < 5; i++)
{
nunchuck_buf[i] = decode_byte(i2cmaster::i2c_readAck());
nunchuck_buf[i] = i2cmaster::i2c_readAck();
}
nunchuck_buf[5] = decode_byte(i2cmaster::i2c_readNak());
nunchuck_buf[5] = i2cmaster::i2c_readNak();
i2cmaster::i2c_stop();
}

Expand Down Expand Up @@ -194,11 +206,3 @@ unsigned char Nunchuck::joy_y_scaled()
return map(constrain(nunchuck_buf[1], joy_y_min, joy_y_max), joy_y_min, joy_y_max, joy_y_scaled_min, joy_y_scaled_max);
}


// Internal function to decode data from nunchuck
unsigned char decode_byte (unsigned char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}

34 changes: 24 additions & 10 deletions Nunchuck/nunchuck.h
@@ -1,7 +1,10 @@
/*
Nunchuck.h - Library for the Nintendo Wii Nunchuck
Created by: Adam Wolf and Matthew Beckler, Wayne and Layne, LLC
Last updated: January 18, 2012 - Arduino 1.0 compatability fixes
Recent updates:
August 18, 2012 - Added support for the Arduino Mega, which has a different RBx pin for the nunchuck select.
August 11, 2012 - Changed initialization bytes to support knock-off nunchucks
January 18, 2012 - Arduino 1.0 compatability fix
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -46,23 +49,36 @@
#define NUNCHUCK_JOY_Y_SCALED_MIN 0
#define NUNCHUCK_JOY_Y_SCALED_MAX 100

#define NUNCHUCK_SELECT_P1 PORTB &= 0xEF // set PB4 = low
#define NUNCHUCK_SELECT_P2 PORTB |= 0x10 // set PB4 = high
#define NUNCHUCK_PLAYER_1 0
#define NUNCHUCK_PLAYER_2 1

// The VGS board has the nunchuck-select signal line connected to Arduino pin D12.
// On the UNO and compatible (atmega328p et al) D12 is PB4.
// On the MEGA 2560 and compatible (atmega2560 et al) D12 is PB6.
// We use an ifdef here to make our NUNCHUCK_SELECT_P{1,2} macros be correct
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
#define NUNCHUCK_SELECT_SET_OUTPUT_DIR DDRB |= 0x40 // set DDRB4 bit = make it an output (used for nunchuck select)
#define NUNCHUCK_SELECT_P1 PORTB &= 0xBF // set PB6 = low
#define NUNCHUCK_SELECT_P2 PORTB |= 0x40 // set PB6 = high
#else
#define NUNCHUCK_SELECT_SET_OUTPUT_DIR DDRB |= 0x10 // set DDRB4 bit = make it an output (used for nunchuck select)
#define NUNCHUCK_SELECT_P1 PORTB &= 0xEF // set PB4 = low
#define NUNCHUCK_SELECT_P2 PORTB |= 0x10 // set PB4 = high
#endif


class Nunchuck
{
public:
// returns 0=success, 1=could not access device
// Provide a 0 or 1 to which_nunchuck to specify which player this is
// 0 means "Player 1", 1 means "Player 2"
// Returns 0=success, 1=could not access device
// Argument specifies which nunchuck to initialize
// pass in either NUNCHUCK_PLAYER_1 or NUNCHUCK_PLAYER_2
unsigned char begin(unsigned char which_nunchuck);

// Call this function to query the Nunchuck and update the data
void update();

// low level functions
// Low level functions
unsigned char joy_x();
unsigned char joy_y();
unsigned char acc_x();
Expand Down Expand Up @@ -91,7 +107,7 @@ class Nunchuck
unsigned char joy_y_scaled();

private:
// This stores the raw data from the nunchuck, properly translated
// This stores the raw data from the nunchuck
unsigned char nunchuck_buf[6];

// Stores a 0 = player 1, 1 = player 2
Expand All @@ -116,6 +132,4 @@ class Nunchuck
unsigned char joy_y_scaled_max;
};

unsigned char decode_byte(unsigned char);

#endif

0 comments on commit 6988cad

Please sign in to comment.