Monday, January 6, 2014

Wii Remote Plus and Linux

I've had this happen to me several times:

  • Find some cool project on the internet involving some piece of hardware
  • Run out and buy the hardware
  • Can't get hardware to work as advertised
  • Discover that the hardware I bought is revision "d" and I needed revision "c or lower"
Welp, if you're trying to get a Wiimote to work, you're might be here because you can't get it working or you don't know what to do next.

The first thing I learned is that there are several types of Wiimote controllers.  The basic one looks like this:

Wiimote, image from http://metroid.wikia.com/wiki/Wii_Remote

Now, I ran down to Best Buy to get one of these, and I found about FIFTY of these (at least) hanging on a rack, in all different colors.  Except they were slightly different.  What I got was the Wii Remote Plus:

Wii Remote Plus, image from Amazon.com
This is all confusing since my Wii Remote Plus says "MotionPlus Inside".  Turns out the MotionPlus was a little plugin/add-on for the first Wiimote that gave it higher resolution and more sensing capabilities.  This device is built-in to the Wii Remote Plus, so almost certainly for marketing reasons they had to give this device a new name and a rubber case.  Behind the rubber case the device looks basically identical to the original Wiimote above but it INCLUDES the higher-resolution sensing.  It cost me $31 at Best Buy.

There are add-ons, like nunchucks, drums, guitars, etc.

Now, there is lots of information available about hacking these devices.

Maybe the most well-known is wmgui, part of Donnie Smith's cwiid project:



wmgui, part of the cwiid project

The wmgui program (shown above) runs in Linux and displays the Wiimote sensor outputs.  I didn't get it to work, apparently because I have a Wii Remote Plus.  From what I gather support for the Wii Remote Plus wasn't added.  

Further, this program  requires that you pair to the device directly from the app in userspace, something that seemed to annoy David Hermann:

The XWiimote software stack is a very recent approach to write Linux drivers for the Nintendo Wii Remote. Long time cwiid and wiiuse were the only choices to use Wii Remotes under Linux. However, both tools very badly designed. They require the application that uses the device to perform a Bluetooth inquiry, connect to the device and run a user-space driver instead of adding the device to the Linux input devices and let applications use them with well-defined APIs like linux-input / evdev. An application does not need to connect to keyboards by itself so why should it need to connect to Wii Remotes? Also the libraries provided by both projects either required threads or global objects which is horrible to use in most applications. This is why the XWiimote project was created.

While calling cwiid and wiiuse "very badly designed", David seems to have picked up the torch and created a proper driver (hid-wiimote.ko) for the Wiimote that has been in the Linux kernel since verson 3.1.  

There's also a BlueZ plugin since version 4.96.  This is perhaps why my installed version of bluez was able to pair with the Wii Remote Plus immediately, and for that I give David (and the other project authors) thanks:

wskellenger@marquette ~ $ dpkg --list | grep bluez
ii  bluez                                    4.98-2ubuntu7

I also found that once paired, the arrow keys on the Wii Remote Plus are also used immediately by X.Org (for example to position a cursor), just as described here, although I haven't installed xwiimote-tools yet...  So because I'm suing a kernel 3.12 the support is already there.  This is cool.  I assume I'm already using xwiimote, so I didn't even get to look at wiiuse.  The rest of the article will thus talk about xwiimote and accompanying tools.



Now, I want to see more about the data that is coming from this controller and David describes the xwiimote-tools package that goes with the kernel driver.  This is easy enough to acquire and build from source:

wskellenger@marquette ~/Projects $ git clone https://github.com/dvdhrm/xwiimote.git
Cloning into 'xwiimote'...
remote: Reusing existing pack: 1249, done.
remote: Total 1249 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1249/1249), 705.21 KiB | 952 KiB/s, done.
Resolving deltas: 100% (604/604), done.
wskellenger@marquette ~/Projects $ cd xwiimote/
wskellenger@marquette ~/Projects/xwiimote $ ./autogen.sh 

...bunch of output skipped...

wskellenger@marquette ~/Projects/xwiimote $ make

At this point the code is compiled and you could run "make install", but I wasn't ready to do that yet, I just wanted to see xwiishow.

wskellenger@marquette ~/Projects/xwiimote $ find | grep xwiishow
./doc/xwiishow.1
./tools/xwiishow-xwiishow.o
./tools/.deps/xwiishow-xwiishow.Po
./tools/xwiishow.c
./xwiishow
./.libs/xwiishow

There she is (bold above).  I tried to run it:

wskellenger@marquette ~/Projects/xwiimote $ ./xwiishow
Usage:
xwiishow [-h]: Show help
xwiishow list: List connected devices
xwiishow <num>: Show device with number #num
xwiishow /sys/path/to/device: Show given device
UI commands:
q: Quit application
f: Freeze/Unfreeze screen
s: Refresh static values (like battery or calibration)
k: Toggle key events
r: Toggle rumble motor
a: Toggle accelerometer
i: Toggle IR camera
m: Toggle motion plus
n: Toggle normalization for motion plus
b: Toggle balance board
p: Toggle pro controller
g: Toggle guitar controller
d: Toggle drums controller
1: Toggle LED 1
2: Toggle LED 2
3: Toggle LED 3
4: Toggle LED 4

Cool, there's a ton of stuff you can play with.  First I'll try 'list':

wskellenger@marquette ~/Projects/xwiimote $ ./xwiishow list
Listing connected Wii Remote devices:
  Found device #1: /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.4/1-1.4:1.0/bluetooth/hci0/hci0:12/0005:057E:0330.000B
End of device list

That being accomplished with success, it sees a device #1 which looks like it works with the xwiishow <1> command above:

wskellenger@marquette ~/Projects/xwiimote $ ./xwiishow 1

What I got was a warning that I wasn't running as root, something that looked like this:

Running xwiishow as a normal user.  Press 'q' to exit.
Just press 'q' to exit and try again as root.  Note the warning above "screen smaller than 80x24; no view" -- if you see this you should enlarge your terminal window before you try this:

wskellenger@marquette ~/Projects/xwiimote $ sudo ./xwiishow 1

Now I got a warning that the window still wasn't large enough, so make it at least 160x48 and you'll get this:


Cool! As you move the device around you can see all of the data that it spits out.  You can also see some awesome ASCII art, the likes and caliber of which I haven't seen since my Telix days in the early 90s.  

Now you can play with the other features, like using the keyboard buttons 1-4 to enable/disable the LEDs on the device, or the 'R' key to enable/disable the feedback motor (vibrator) inside.

Thanks to David Hermann (xwiimote), Donnie Smith (cwiid), and Michael LaForest (wiiuse) for their hours of hacking to bring us these cool tools!

Depending on what you want to do, you may need to figure out which package you need.  For the project I've got in mind I'm hoping I can just use xwiimote, since it is already there in the kernel, there isn't any need to install anything else.


No comments:

Post a Comment