A Wii controller library for talking to every Extension Controller made for the wii including Nunchuck and Classic Controller over i2c.

Similar projects worth following

We wrote a library to go with our esp8266 puppetry board. We support many of the controllers listed here.

Use a DJ table, a guitar hero guitar or a drum-kit to control a robot puppet.

Other users could benefit from a library that allows them to encorporate these game peripherals into their projects.

Library currently supports

* Nunchuck

* Classic Controller

* Guitar hero guitar

* Guitar hero Drums

* DJ Hero Turntable

* Drawsome tablet


5 seconds of recorded i2c bus activity between tablet and wiimote when tablet is plugged in.

logicdata - 2.25 MB - 02/17/2017 at 23:21


  • Next Steps

    Alex Camilo02/25/2017 at 14:09 0 comments

    The bulk of the library is done. Now i just need to write a bunch of example sketches.

    Future work:

    • Support uDraw tablet
      • Same deal as the drawsome, load up game, sniff, then stare till your eyes bleed untill it maks sense.
    • Support Wii Motion plus
      • Not hard, its all well documented but it's goofy. It comes up on another i2c address and you enable it then it overwrites the accessory data every other read. Additionally, it takes a bit off of one of the joysticks to use as a flag for framing.
    • Support 3rd party wireless wiichucks and wireless extenders.
      • Might just be as easy as enabling encryption. i dunno.

  • Drums added

    Alex Camilo02/23/2017 at 03:42 0 comments

    Added drums. Also tracked down an annoying bug. Remember kids, Don't assume malloc gives you clean memory. Especially when that memory bieng 0 signifies the end of your linked list.

  • DJ Table and Guitar support added

    Alex Camilo02/22/2017 at 04:29 0 comments

    Just tested and committed classes for the DJ Hero table and the Guitar Hero 3 guitar. I didn't test dual turntables since I only have one.

    Tomorrow i'll be adding the drums.

  • Taking a break from the tablet.

    Alex Camilo02/21/2017 at 21:50 0 comments

    The Ebay fairy and the Amazon Fairy dropped off more peripherals. I now have the DJ Hero, a Wii Motion Plus, and guitar hero drums. All of these have good documentation so i'm going to add them to the library.

    The tablet is an interesting beast. I'm not sure how to decode the LSBs of the X,Y and pressure. They look like they're incrementing and decrementing but they jump and skip. I'll need to gather more data.

    I'm checking in what I have, It brings up the tablet and decodes the data as I understand it now.

  • I think we have good data.

    Alex Camilo02/18/2017 at 03:51 0 comments

    According to the wiibrew wiki the following is true.

    decrypted_byte = (encrypted_byte XOR table1[address%8]) + table2[address%8]
    if the host key is 16 zero bytes, table1[x] and table2[x] are all 0x97.

    So i set the key to zero and simplified my decryption function and started pulling some more data. When I approached the board with the pen I saw byte 5 go from 0x80 to 0x00 and when i applied pressure it counted up from 0 to 7.

    I think this is the first useful bit of structure i've gotten so far. I can detect a pen and sense pressure with 3 bits of sensitivity. There is totally more pressure data in byte 5 but it looks like there might be something else. it's not counting from 00 to FF correctly.

  • Progress! Data from the tablet.

    Alex Camilo02/18/2017 at 01:15 0 comments

    I repeaded the sequence of reads and writes exactly.

    Writing a full 16 bytes of key, reading a few times, and then setting 0xfb to 01 seems to yeald results.

    The tablet is now spitting out 6 bytes that change with the stylus. I need to fix my decryption function or try the 0xfb 01 trick in unencrypted mode before i can begin decoding stuff.

    Accessory Bytes:	FD 5A 4D 51 0E 5E 
    Accessory Bytes:	10 43 75 5E 0E DE 
    Accessory Bytes:	A7 42 AC 53 48 DA 
    Accessory Bytes:	9D 42 A5 52 5A D5 
    Accessory Bytes:	58 42 65 52 BE D5 
    Accessory Bytes:	59 42 7E 52 78 D5 
    Accessory Bytes:	5B 42 40 52 25 DA 
    Accessory Bytes:	44 42 AE 52 01 D5 
    Accessory Bytes:	7A 42 15 53 AA D5 
    Accessory Bytes:	9B 42 EE 53 3E D5 
    Accessory Bytes:	AE 42 ED 53 78 D4 
    This is the startup procedure so far. I'm not sure how much of these extra delays or reads i need. I was tryig to match what the wii does.
            Serial.println("enc start");
            // to start, init in unenc mode
            _writeRegister(0xF0, 0x55);
            _writeRegister(0xFB, 0x00);
            _writeRegister(0xF0, 0xAA); // enable enc mode?

  • Tablet Init

    Alex Camilo02/17/2017 at 23:19 0 comments

    We have some bytes from the tablet. It's all pretty standard stuff with one exception.

    // unenc init
    a4 w f0 55
    a4 w fb 00
    Read ID Bytes
    a4 w fa
    a5 r ff 00 a4 20 00 13
    // Enter enc mode
    a4 w f0 aa
    // write 16 byte key
    a4 w 40 e0 7d e0 7d e0 7d
    a4 w 46 e0 7d e0 7d 38 54
    a4 w 4c bb 79 01 43
    // Read Cal Data
    a4 w 20
    a5 r a2 b2 89 40 0f 1f 39 f0
    a5 r a2 b2 89 40 0f 1f 39 f0
    a4 w 30 
    a5 r a2 b2 89 40 0f 1f 39 f0
    a5 r a2 b2 89 40 0f 1f 39 f0
    // Read inputs
    a4 w 00
    a5 r a3 b1 8a 41 0e 5e 38 f3
    a5 r a3 b1 8a 41 0e 1e 38 f3
    many more  00 reads
    a4 w fb 01
    many more  00 reads

    Whats with the write of 01 to fb? i'll have to try doing that.

  • Protocol Analyser!

    Alex Camilo02/17/2017 at 22:14 0 comments

    The ali-express fairy left me a gift today.

  • Encryption Encryption Encryption

    Alex Camilo02/17/2017 at 20:09 0 comments

    Looking at the registers I noticed something. the first 24 bytes look like they have data and the last 6 bytes look like they have data. This looks like what a WII peripheral in encrypted mode would look like. The fixed 8 byte pattern repeating every bit is due to the "scrambling protocoll" only using the lower 3 bits of the address. A repeating 8 byte pattern is what you would get if you encrypted a constant (like 0 or FF).

    0x00A40000: 32 68 0F 15 47 2C 34 3E  89 6D D7 1A 46 65 34 3E 
    0x00A40010: 89 6D D7 1A 46 64 3B 3F  88 6E C8 1B 47 64 3B 3F 
    0x00A400F0: 88 6E C8 1B 47 64 3B 3F  88 6E C8 19 E2 45 34 CB

    I'm assuming that the Wii brought up the tablet in encrypted mode. In that case, there is no point in trying to figure out data structure beyond what bits might hold what.

    I did some experiments. Maybe the tablet needs to be brought up in encrypted mode.

    I tried the old init mehtod of writing 0x00 to address 0x40. This didn't work. got FFs.

    I then found this blog post in which bill writes an i2c sniffer and uses it to spy on a nunchuck. He posts a log of what his WII did.

    Init in unencrypted mode. write 55 to f0 and 00 to fb
    (3):A4+ F0+ 55+
    (3):A4+ FB+ 00+
    Read ID bits. Write address FA. read 6 bytes from FA-FF
    (2):A4+ FA+
    (7):A5+ 00+ 00+ A4+ 20+ 00+ 00-
    Write AA to F0. (Enable encryption?)
    (3):A4+ F0+ AA+
    Write 16 bytes of encryption tables.
    (8):A4+ 40+ AC+ B9+ 8B+ 35+ 1F+ C8+
    (8):A4+ 46+ 28+ BE+ B2+ 89+ 07+ 18+
    (6):A4+ 4C+ 19+ FF+ 01+ C6+
    ... normal reads and writes after this point.

    I modified my code to bring up the tablet the same way only with an encryption table of 0.

    I'm probably not decryption it right because the data was almost identical to what i was getting using the F0 55 FB 00 procedure. Everything was in the same place but the byte was different.

    I'm concluding that somehting needs to be done to kick the tablet into a mode where it reports it's position. I'll give bill's i2c decode code a shot after i port it to a teensy 3.2.

  • Library refactor done.

    Alex Camilo02/16/2017 at 21:17 0 comments

    Library refactor is done. I think the interface is pretty clean and it's done under the hood using classes for each axis and virtual functions so I can get rid of the mapping struct my old version used.

    This is what the old map looked like.

        UNUSED,0,0,        // MSB (Unused)
        UNUSED,0,0,        // CSB (Unused)
        BYTE1,BIT0,BIT7,   // LSB (7:0 bits of data in byte 1 of controller data)
        0,127,255,          // min, middle, max
        0,255,127,         // servo min, max, zero PWM values
        D6);                // Channel

    Here is the new map.

    myChuck.addMap(new Nunchuck::joyX(D5,200,125,50)); // chan smax szero smin

    you can also statically declare the maps and pass em in that way.

View all 14 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates