Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

This is an arduino library for talking to the Wii Classic Controller over i2c. The hardware is the same as the Wii Nunchuck.

/*
WiiClassic Test Code

This code prints the current controller status to the serial port.
Button pressed calls poll whether the button was pressed since the last update call.
as a result, it will just briefly print the last button pressed once.

Tim Hirzel May 2008

*/


#include "Wire.h"

#include "WiiClassic.h"

WiiClassic wiiClassy = WiiClassic();

void setup() {
Wire.begin();
Serial.begin(9600);
wiiClassy.begin();
wiiClassy.update();
}

void loop() {
delay(100); // 1ms is enough to not overload the wii Classic, 100ms seems to ease the serial terminal a little
wiiClassy.update();

//
/*
// PRINT RAW BYTES FOR DEBUG
// STATUS IS FIRST FOUR BYTES
for (int i = 0; i < 4; i ++) {
for (int j = 7; j >= 0; j--) {
if ((wiiClassy.getRawStatus()[i] & (1 << j)) == 0) {
Serial.print("0");
}
else{
Serial.print("1");
}
}
Serial.println();
}
// BUTTONS IS NEXT TWO BYTES
for (int i = 0; i < 2; i ++) {
for (int j = 7; j >= 0; j--) {
if ((wiiClassy.getRawButtons()[i] & (1 << j)) == 0) {
Serial.print("0");
}
else{
Serial.print("1");
}
}
Serial.println();
}
Serial.println("---");
*/

Serial.print("Buttons:");


if (wiiClassy.leftShoulderPressed()) {
Serial.print("LS.");
}
if (wiiClassy.rightShoulderPressed()) {
Serial.print("RS.");
}
if (wiiClassy.lzPressed()) {
Serial.print("lz.");
}
if (wiiClassy.rzPressed()) {
Serial.print("rz.");
}
if (wiiClassy.leftDPressed()) {
Serial.print("LD.");
}

if (wiiClassy.rightDPressed()) {
Serial.print("RD.");
}

if (wiiClassy.upDPressed()) {
Serial.print("UD.");
}
if (wiiClassy.downDPressed()) {
Serial.print("DD.");
}

if (wiiClassy.selectPressed()) {
Serial.print("select.");
}

if (wiiClassy.homePressed()) {
Serial.print("home.");
}
if (wiiClassy.startPressed()) {
Serial.print("start.");
}

if (wiiClassy.xPressed()) {
Serial.print("x.");
}

if (wiiClassy.yPressed()) {
Serial.print("y.");
}

if (wiiClassy.aPressed()) {
Serial.print("a.");
}

if (wiiClassy.bPressed()) {
Serial.print("b.");
}

Serial.println();
Serial.print("right shoulder: ");
Serial.println(wiiClassy.rightShouldPressure());
Serial.print(" left shoulder: ");

Serial.println(wiiClassy.leftShouldPressure());
Serial.print(" left stick x: ");

Serial.println(wiiClassy.leftStickX());
Serial.print(" left stick y: ");

Serial.println(wiiClassy.leftStickY());
Serial.print(" right stick x: ");

Serial.println(wiiClassy.rightStickX());
Serial.print(" right stick y: ");

Serial.println(wiiClassy.rightStickY());
Serial.println("---");

//pulse = (int)500+8*wiiClassy.leftStickX();
//updateServo();
}

  • WiiClassic.h library

/*
 * Wii Classic -- Use a Wii Classic Controller
 * by Tim Hirzel https://www.growdown.com
 *
 *
 * This code owes thanks to the code by these authors:
 * Tod E. Kurt, https://todbot.com/blog/
 *
 * The Wii Nunchuck reading code is taken from Windmeadow Labs
 * https://www.windmeadow.com/node/42
 *
 * and the reference document on the wii linux site:
 * https://www.wiili.org/index.php/Wiimote/Extension_Controllers/Classic_Controller
 */


#include <Wire.h>


#ifndef WiiClassic_h
#define WiiClassic_h


class WiiClassic {    
    private:
        byte cnt;
        uint8_t status[4];              // array to store wiichuck output
        byte averageCounter;
        //int accelArray[3][AVERAGE_N];  // X,Y,Z

        uint8_t buttons[2];
        uint8_t lastButtons[2];


    public:

        void begin()
        {
            Wire.begin();
            cnt = 0;
            averageCounter = 0;
            Wire.beginTransmission (0x52);      // transmit to device 0x52
            Wire.send (0x40);           // sends memory address
            Wire.send (0x00);           // sends memory address
            Wire.endTransmission ();    // stop transmitting
            lastButtons[0] = 0xff;
            lastButtons[1] = 0xff;
            buttons[0] = 0xff;
            buttons[1] = 0xff;

            update();        

        }


        void update() {

            Wire.requestFrom (0x52, 6); // request data from nunchuck
            while (Wire.available ()) {
                // receive byte as an integer
                if (cnt < 4) {
                    status[cnt] = _nunchuk_decode_byte (Wire.receive()); //_nunchuk_decode_byte ()
                } else {
                    lastButtons[cnt-4] = buttons[cnt-4];
                    buttons[cnt-4] =_nunchuk_decode_byte (Wire.receive());
                }
                cnt++;
            }
            if (cnt > 5) {
                _send_zero(); // send the request for next bytes
                cnt = 0;                  
            }
        }

        byte * getRawStatus() {
            return status;
        }

        byte * getRawButtons() {
            return buttons;
        }

        boolean leftShoulderPressed() {
            return _PressedRowBit(0,5);
        }

        boolean rightShoulderPressed() {
            return _PressedRowBit(0,1);
        }

        boolean lzPressed() {
            return _PressedRowBit(1,7);
        }

        boolean rzPressed() {
            return _PressedRowBit(1,2);
        }

        boolean leftDPressed() {
            return _PressedRowBit(1,1);
        }

        boolean rightDPressed() {
            return _PressedRowBit(0,7);
        }

        boolean upDPressed() {
            return _PressedRowBit(1,0);
        }

        boolean downDPressed() {
            return _PressedRowBit(0,6);
        }

        boolean selectPressed() {
            return _PressedRowBit(0,4);
        }

        boolean homePressed() {
            return _PressedRowBit(0,3);
        }

        boolean startPressed() {
            return _PressedRowBit(0,2);
        }

        boolean xPressed() {
            return _PressedRowBit(1,3);
        }

        boolean yPressed() {
            return _PressedRowBit(1,5);
        }

        boolean aPressed() {
            return _PressedRowBit(1,4);
        }

        boolean bPressed() {
            return _PressedRowBit(1,6);
        }

        int rightShouldPressure() {
            return status[3] & 0x1f; //rightmost 5 bits
        }

        int leftShouldPressure() {
            return ((status[2] & 0x60) >> 2) + ((status[3] & 0xe0) >> 5); //rightmost 5 bits
        }

        int leftStickX() {
            return  ( (status[0] & 0x3f) );
        }

        int leftStickY() {
            return  ((status[1] & 0x3f));      
        }

        int rightStickX() {
            return ((status[0] & 0xc0) >> 3) + ((status[1] & 0xc0) >> 5) +  ((status[2] & 0x80) >> 7);

        }

        int rightStickY() {
            return status[2] & 0x1f;   
        }


    private:
        boolean _PressedRowBit(byte row, byte bit) {
            byte mask = (1 << bit);
            return (!(buttons[row] & mask )) && (lastButtons[row] & mask);
        }


        byte _nunchuk_decode_byte (byte x)
        {
            x = (x ^ 0x17) + 0x17;
            return x;
        }

        void _send_zero()
        {
            Wire.beginTransmission (0x52);      // transmit to device 0x52
            Wire.send (0x00);           // sends one byte
            Wire.endTransmission ();    // stop transmitting
        }

};



#endif