HOWTO make your own Wiimote peripheral
With a little wiring a Wiimote can be made into a cheap bluetooth transmitter for your microcontroller project. Wiimote peripherals like the nunchuk, communicate with the wiimote over I2C (aka Two Wire Interface, TWI). A number of microcontrollers support TWI, such as the Arduino,the Make Controller and Atmels ATmega series. I am using an arduino with a ATmega168 for this project.

The nunchuk sends a 6 byte packet to the wiimote. For an in depth discussion of the format go to wiili.org. So you can send whatever data you want across the wiimote, just send it 6 bytes at a time. On the PC side, there are a number of wiimote drivers to choose from. Since am running Linux, I am using libcwiimote. Running the program test1, the Arduino's data shows up as nunchuk data.
The wiimote uses a proprietary connect. I just bought an extra nunchuk and cut the cable off of it. The cable has 4 wires.
white - ground
red - 3.3+v
green - data
yellow - clock
Attach white to the Arduino's ground, red to AREf, green to analog pin 4, yellow to analog pin 5. Since the wiimote provides power you can actually power the Arduino straight from the wiimote. The Arduino's twi.h header needs two changes. Look in lib/targets/libraries/Wire/utility. Then delete twi.o. Open up twi.h. Uncomment line // #define ATMEGA8. Since the wiimote uses "Fast" I2C, we will need to change the speed #define TWI_FREQ 400000L.
Here is a simple program to send data across the wiimote.
#include <Wire.h>
uint8_t outbuf[6];
void
receiveEvent (int howMany)
{
while (Wire.available ())
{
char c = Wire.receive (); // receive byte as a character
}
}
void
requestEvent ()
{
outbuf[0] = nunchuk_encode_byte (125); // joystick X
outbuf[1] = nunchuk_encode_byte (126); // joystick Y
outbuf[2] = nunchuk_encode_byte (227); // Axis X
outbuf[3] = nunchuk_encode_byte (241); // Axis Y
outbuf[4] = nunchuk_encode_byte (140); // Axis Z
outbuf[5] = nunchuk_encode_byte (1); // Press C button, byte[5] is buttons
//C,Z and accelaration data
//outbuf[5] = nunchuk_encode_byte(2); // Press Z button
//outbuf[5] = nunchuk_encode_byte(0); // Press Z and C button
Wire.send (outbuf, 6); // send data packet
}
void
setup ()
{
Wire.begin (0x52); // join i2c bus with address 0x52
// this is the nunchuk address.
// all nunchuks use this address
Wire.onReceive (receiveEvent); // register event
Wire.onRequest (requestEvent); // register event
}
void
loop ()
{
delay (100);
}
// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char
nunchuk_encode_byte (char x)
{
x = x - 0x17;
x = (x ^ 0x17);
return x;
}
The regular nunchuk encodes the data before it is sent. To mimic the nunchuk, my codes performs the same operation. Now byte[0] will come over as nunchuk joystick X, byte[1] as joy Y, byte[2] as axis X, byte[3] as axis Y, byte[4] as axis Z. Byte[5] as buttons and accelaration data. Byte[5] as some more computations (an additional XOR 0xFF) done to it when using the regular wiimote driver. So your driver would need to be modified to accurately read that byte.
No one has quite figured out if it is possible to send data TOO the peripheral. If that can be figured out then the wiimote will make a cheap blue tooth transceiver especially compared to the cost of an Arduino blue tooth board $140.
Credit goes to Zudini at wiire.org. He figured out the wiimotes I2C protocol and posted the sample code that I based mine off of.
Update I just tried running my code under Arduino 10. I had to make a different change to twi.h. Here are the first few lines of twi.h
#define ATMEGA8
#ifndef CPU_FREQ^M
#define CPU_FREQ 16000000L
#endif
#ifndef TWI_FREQ^M
#define TWI_FREQ 100000L
#endif

Interesting sample code.
I think I might order some stepper motors and make an electronic, wiimote guided etch-a-sketch.
ARef
Perhaps I am mistaken here, but will the Arduino be using the 3.3v reference voltage in the situation you've described? See this post which is linked to by the Arduino reference.
Post new comment