Thursday, February 2, 2017

Wii Classic Controller over I2C to Raspberry Pi

I wanted to connect my Wii Classic Controller to my Raspberry Pi 3.  Here is how I did it.

The Hardware:

The Wiibrew extension controller page explains how to connect an official Wii Classic Controller via I2C.  (I tried a cheap ZettaGuard one, and I couldn't figure out the appropriate I2C initialization codes to make it work.)

The site Robot Electronics has an I2C tutorial that explains the need for pull up resistors when making I2C connections.  I used two 10 K pull up resistors and connected the four pins (3v3, SDA, SCL, and ground) from the Wii Classic Controller to the Raspberry Pi connector (pins 1, 3, 5, and 6).



The Software:

I am using a stock Raspbian image (as of January 2017).  The goal is to read the Wii Classic data and translate it to virtual keyboard presses thru the linux uinput device.

First, set up the uinput device by adding a line for "uinput" in /etc/modules.  Make it accessible for all users by adding the following line to /etc/udev/rules.d/99-com.rules:
KERNEL=="uinput",MODE="0666"

After a reboot, confirm that is shows up with read/write privileges for all.
pi@raspberrypi:~ $ ls -l /dev/uinput
crw-rw-rw- 1 root root 10, 223 Feb  2 13:36 /dev/uinput


Now, this page has useful lower level info about writing C code to use uinput, but ultimately I installed libsuinput to handle the details.

I installed wiringPi to use the I2C library.  I2C can be enabled on the Raspberry Pi using raspi-config.

Here is my code.

The delay times after I2C transactions and keys to output can be customized.  The delay times provide enough time for I2C transactions to occur.  They probably can be less, but the values I've used seem to work okay.  According to wikipedia, input lag becomes distracting around 200 ms, so keep the delay times much less than that.

The valid key codes to be listed in the keys[] array can be found in /usr/include/linux/input.h.  The key codes should be listed in the same order as the commented list of Wii Classic buttons.

Compile using:  gcc -lwiringPi -lsuinput WiiClassicPi.c -oWiiClassicPi