Wanderer v2, with Wireless Wii Nunchuck

After building my little autonomous wanderer robot, I saw this iPad-controlled blimp and went ahead and added iPad control to my robot too. I had a Python script on my iMac which took commands from the iPad over Wifi and relayed them to the Arduino using XBee. I demo’ed this at BitNorth 2010, but I’m not sure if the video is up yet. That said, the fact that all the commands were relayed through a ‘base station’ bothered me, and I saw a cheap wireless Wii Nunchuk which I immediately bought, thinking I could make it into a really ergonomic remote control for my little robot. I probably could have gotten a Wifi shield instead, but I was up for a different kind of challenge.

The Wii Nunchuck (wired or wireless) communicates using the I2C protocol, which the Arduino supports quite nicely. There exists a cheap little hardware Arduino/Nunchuck interface but I had no use for the little white casing around the receiver that’s supposed to plug into the WiiMote so I cracked it open and interfaced the little circuit board inside directly to my Arduino. After a lot of experimentation and reading of forum posts and wikis, I found a magic incantation of bytes to send to my particular Nunchuck that would enable me to pull data from it reliably, and I packaged it up into a little object-oriented Nunchuck library here. While I was at it, I also packaged up my Pololu motor controller interface code. The robot code sketch itself is on GitHub as well.

So after all this hardware and software work, I have remote-controllable wanderer robot! In the video above you can see that it’s capable of autonomous and controlled modes. I used the joystick to control motion, the C button to stop and the Z button to turn on autonomous mode. It’s pretty convenient to have a remote for a bot like this, so I can bring it back if it wanders underneath the bed, or turn it around if it gets stuck in a corner or something.






For reference, and because I want to try out my syntax highlighter plugin, here is the  initialization code that works for my ‘Intec’ wireless Wii Nunchuck (look in GitHub at how I handle retrying after failing initialization):


void WiiChuck::init()
{
	Wire.beginTransmission(0x52);
	Wire.send (0xF0);
	Wire.send (0x55);
	Wire.endTransmission();
	delay(30);

	Wire.beginTransmission (0x52);
	Wire.send (0xFB);
	Wire.send (0x00);
	Wire.endTransmission();
	delay(30);

	Wire.beginTransmission(0x52);
	Wire.send (0xFA);
	Wire.endTransmission();
	delay(30);

	Wire.requestFrom(0x52, 6);
	boolean allFF = true;
	int bytesReceived = 0;
	while(Wire.available())
	{
		byte c = Wire.receive();
		bytesReceived++;
		if(c != 0xFF) {
			allFF = false;
		}
	}

	if(bytesReceived == 0)
	{
		return;
	}
	delay(30);

	if(allFF)
	{
		delay(1000);
	}
	else
	{

		Wire.beginTransmission(0x52);
		Wire.send (0xF0);
		Wire.send (0xAA);
		Wire.endTransmission();
		delay(30);

		Wire.beginTransmission(0x52);
		Wire.send (0x40);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.endTransmission();
		delay(30);

		Wire.beginTransmission(0x52);
		Wire.send (0x46);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.endTransmission();
		delay(30);

		Wire.beginTransmission(0x52);
		Wire.send (0x4C);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.send (0x00);
		Wire.endTransmission();
		delay(30);

		inSync = true;
	}
}