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 http://www.growdown.com
 *
 *
 * This code owes thanks to the code by these authors:
 * Tod E. Kurt, http://todbot.com/blog/
 *
 * The Wii Nunchuck reading code is taken from Windmeadow Labs
 * http://www.windmeadow.com/node/42
 *
 * and the reference document on the wii linux site:
 * http://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
 

Share