Sunday, May 04, 2008

Improvements to Arduino Wii Nunchuck connection

I'm working on an Arduino based controller for an electric canoe. In the process of doing that, I've been looking more closely at the data coming off the wii Nunchuck. Using the avr math libraries, and the atan2 function, you can combine the data from the X and Z accelerometers on the nunchuck to get a nice smooth 360 degrees of roll information. Because this is using an inverse tangent function, it also makes for more accurate angular data than the raw data coming off the device.

ps. For this same canoe project I wrote up a library for the Wii Classic Controller as well. For anyone interested, that's available here.

UPDATE:George's asks a good question in the comments. If you try and run the code posted on the arduino playground. It's important to note that the third chunk of code needs to be run from the processing application, available here at processing.org.

14 comments:

Miles
said...

Hey Tim,

I stumbled on your old sailing blog the other day and couldn't stop reading it. I've been planning to build a boat myself with crusing the ICW as the final goal, and the story of your trip captured exactly how I image my trip will be when it becomes a reality. I wondered here trying to find a way to send you a quick note.

Interestingly enough, I see that you lived a while in Bozeman, where I lived for 4 years too (I left in the summer of 2004). It is unfortunate that our paths didn't cross.

I would love to send you some questions for cruising advice sometime if my plans materialize. Would that be ok? Also, just so you know, I gave the Slow Times a link on my blog.

I am an old physicist now practically retired. I am very interested on your project. As I have an arduino board and an wiinunchuck, I downloaded your 3 codes and tried to reproduce the results. The first two seam to work OK. After creating a directory WiiChuck in the hardware/libraries, I copied in the code_1. Then I started the arduino and copied the code_2 as the main program. It works well. The last one gives a syntaxe error (void serialEvent) in the arduino 010 environment. Please help me with some guidance as I am new in this field and a lot of my knowledge was forgotten. send me mail on: const_g20 at yahoo dot fr.

On the Arduino site you listed a ".h" file an arduino sketch and a processing sketch.I can't get the library(.h) file to work with the arduino sketch. Doesn't there need to be a (.cpp) (.o) and (keywords.txt) file included with each code library in order for the arduino to reference it?

It looks like maybe your WiiChuck.h file doesn't compile properly in Arduino 0012 Alpha though? I'm pretty new to Arduino so I'm not sure about which syntax changes broke it or if I'm just doing something wrong? I get dozens of errors compiling it, the first few errors are:

hardware\libraries\WiiChuck/WiiChuck.h:51: error: 'byte' does not name a type

hardware\libraries\WiiChuck/WiiChuck.h:53: error: 'byte' does not name a type

hardware\libraries\WiiChuck/WiiChuck.h:63: error: 'boolean' does not name a type

hardware\libraries\WiiChuck/WiiChuck.h:68: error: 'byte' does not name a type

I'm trying to connect my Wii controller to my arduino. I used the source from http://www.windmeadow.com/node/42.

i wasn't able to get any data because when i connect the nunchuck to the arduino, my arduino just stop. I connect directly on pins 2 to 5 with the WiiChuck Adaptor. The TX and TR pins stop blinking when i connect the controller.

I have no idea where is the problem and i can't continue to go ahead because I just can't read data.

Do I need to use resistor or something else ?

I use an Arduino diecimila, an original Nintento Nunchuck and the Wii Nunchuck Adaptor. I also use the lastest arduino software (012).

I am trying to use your code with an Arduino Diecimila using an ATmega328. I'm not using the Processing code, and I'm using a modified version of Arduino 12. The wii nunchuck is connected with one of the adapters.

Why do none of the variables get printed in the Serial Monitor?

The code seems to stall when it gets to chuck.begin();

I just tried it on an ATmega168 and an Arduino 12 IDE, it still didn't work.

hrmmm... that's a tough one. Can you get hold of an Arduino 10 and try it with the 168 version? If that works, that will confirm that somehow this library has gotten stale since I set it up. With some other code, I've noticed v12 has been less happy with some of my libraries, and I've yet to sort it out yet.

If that doesn't help, I've definitely had i2c stuff freeze up my apps when there were hardware issues, like a slightly lose connection to the nunchuck. I since have started adding little solder blobs to the wiichuck adapter to widen the adapter just slightly and make a tighter fit to the nunchuck.

Lastly, try Todbot's library as an alternative. http://todbot.com/blinkm/example_code/BlinkMChuck/nunchuck_funcs.hNote his special init function for when the nunchuck is connected directly to the arduino. That *might* illuminate something.

Please do post back with any clues or results. Thanks for your comment.

Seems that if the power pins are not set up, the ThingM wiichuck adapter can't power the i2c conversation, and the Wire library freezes whenever trying to converse with an unpowered nunchuck.

Interestingly, the board would unfreeze and start printing ~512~512~540 results if I pulled the nunchuck OFF the adapter entirely.

Once I powered the i2c pins (outputs 2 and 3), it would work. It would require the whole Arduino to be reset if it was unplugged and replugged, however.

You and todbot did a great job, but I'm thinking of merging both of your codes into one, which will handle the buttons, tilts and also try to auto-reset the i2c conversation if it thinks the nunchuck has not been initialized. I will also try to separate the Wire calls from the Wii-related features, so it's easier to extend. Any objections?

I think some of you are having the same problem I did: you need to init the nunchuck with power. Todbot's code has a function to do that. I've copied that in to the WiiChuck class and added two constructors - one that defaults to no power, and one that lets you supply a boolean indicating whether or not you want power. I can send this around if it's not clear what I mean.