Late last year when I was putting the finishing touches on the McCree Hammershot project, I decided to use a Wii Nunchuk hooked up to an Arduino for the controller’s movement. Although I eventually got it working, I had to try a variety of libraries before I found one that would even read the data properly. Most of them were convoluted, bloated, or poorly documented. Even the library I eventually ended up using was designed for controlling motors with a Nunchuk, not for just reading control inputs.

It’s now many months later, and once again I’m looking to build at least two more projects using extension controllers. So I decided to fix all of these problems and just build my own library.

Introducing NintendoExtensionCtrl

The library is called “NintendoExtensionCtrl”, and I designed it from the ground up to be flexible and lightweight.

At the time of this initial release (0.5.3), the library works with 7 controllers including the Nunchuk, Wii Classic Controller, and Wii Guitar Hero guitar. Out of the box it can do approximately 800 updates a second, supports multiple I²C buses, and works on both the Arduino (AVR) and Teensy platforms.

Simple API

The API is built to be simple to use for novices, while still allowing more complex use by advanced users.

ClassicController classic;

void setup() {
	classic.begin();  // Initialize the bus
	while (!classic.connect()) {}  // Connect to the controller

void loop() {
	if (classic.update();) {  // Update all values



There are only 3 typical communication functions that need to be called in order to talk to the controller, and only one that needs to be called from within the main loop. These functions handle all of the background I²C communication and identity checks, so the user is free to focus on working with the controller data instead.

Each controller uses a straight-forward naming convention for its control data functions. Inputs are named with the control type (joy, button, trigger) followed by the name. The user should never have to struggle to figure-out how the data matches their controller.


To keep things lightweight, all data arrays are kept to minimum sizes and the library itself declares no global variables. Control data functions utilize constant expressions to transform data from the raw array, keeping memory usage low.

For use with 2 or more controller types on a single bus, advanced users can access the controller-specific data classes directly so that there is only ever one instance of the data-heavy communication class.

Thorough Documentation

The library includes a full keyword map for the Arduino IDE and 20 different examples, including a debug and demo example for every supported controller.

Each “DebugPrint” example will connect to the selected controller and print all available control inputs nicely formatted over serial. Each “Demo” example lists all available data functions including ranges, and gives examples for typical usage.

In case your controller isn’t supported, I’ve also written a guide in the ‘extras’ folder for how to add your own extension controllers to the library.

Open Source

Everything in the library is licensed under the GNU Lesser General Public License, which makes it easy to integrate into your own closed or open-source project without affecting your own licensing.


The library is available on GitHub, and I’ve asked the Arduino maintainers to add it to the IDE’s libraries manager as well. Enjoy!

Believe it or not this was my first foray into the nitty-gritty of C++ classes and inheritance. I’ve learned a lot, and I’m really proud of how this library turned out.

That being said, be aware that I built this library for my own projects which are still in progress. Although I’m releasing this publicly the library is still in development and both the public API and underlying behavior of functions are liable to change. If you’re going to integrate it into one of your projects make sure you note the version number you’re using.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Would you like to know more?