Introduction

I’m working on a project that uses a Wii Nunchuk and an Arduino micro-controller and I needed a way to get the data from the Wii Nunchuk using my Arduino. There are a few libraries that already can do that. However, none of them suited me. Some were too complex, some were outdated and most did not work with Arduino 1.0. Therefore, I decided to create my own library, called ArduinoNunchuk. While writing it, I had two things in mind:

  • The library must be simple and easy to implement in other projects.
  • The library should use the best way to access the information from the Wii Nunchuk.

Most libraries initialize the controller by writing 0×00 to 0×40. When this is done, the data bytes are encrypted and only Nintendo’s controllers will work. However, there is another way to initialize the Wii Nunchuk that will make the data unencrypted and will allow some 3rd party controllers to work too. You should write 0×55 to 0xF0 and then 0×00 to 0xFB instead. This new, improved method was used in my library.

Another change was in the precision of the accelerometer’s data. The Wii Nunchuk sends data in 6 bytes and bytes 2, 3 and 4 contain the values from the accelerometer. However, there are still some digits in bits 2-7 from byte 5. These values are normally ignored in other libraries. Although they do not cause a major change in the data, they increase the precision of the accelerometer’s value. Therefore, I decided to implement this too.

 

Instructions

The library is very simple to be used. You create an instance using:

ArduinoNunchuk nunchuk = ArduinoNunchuk();

In you setup() method, you initialize it:

nunchuk.init();

And in your loop() method, you update the values:

nunchuk.update();

The data from the Wii Nunchuk will be available in the following format:

nunchuk.analogX
nunchuk.analogY
nunchuk.accelX
nunchuk.accelY
nunchuk.accelZ
nunchuk.zButton
nunchuk.cButton

 

Download

You can download the library ArduinoNunchuk on GitHub. Feel free to use it in any project of yours. The only thing I ask is that you credit me if you adapt/reuse/distribute the library. Also, please share any projects that you create or ask any question on the comments section below.

 

FAQ

How do I use this library?

Download all the files from the link above and place the ArduinoNunchuk folder them into your libraries folder, which can be found at:

Windows: My Documents\Arduino\libraries\
OSX: ~/Documents/Arduino/libraries/

If the libraries folder does not exist, you should create one. You must restart the Arduino IDE after moving the folder. You can now import the library to an existing project in Sketch > Import Library... > ArduinoNunchuk. There is also an example file for reference, which can be found at File > Examples > ArduinoNunchuk > ArduinoNunchukDemo. This example file prints all the data from the Wii Nunchuk to the computer’s serial port.

 

References & Further Resources

I based my library on the following projects/websites:

Post comment as twitter logo facebook logo
Sort: Newest | Oldest
EricQuagliozzi 5 pts

Hi Gabriel,

Thanks for that great job!

I'm starting a basic servo project using the Wii Nunchuk and I'm facing a problem:

I use your good library and all works fine if I keep the line "Serial.begin(19200)", but if I remove this line it seems that the received data is not right (that works for buttons but not for values of accelerometer and stick). :(

May be I'm wrong, but the I2C has got it's own baudrate generator and I don't understand why I have to set the Serial if I don't need it (I don't send any data to serial). Is there any relationship between Serial and Wire?

Many thanks for you help.

GabrielBianconi 5 pts moderator

EricQuagliozzi

My library works without "Serial.begin(19200)" if you do not print anything to the serial port. For example, the following sketch works fine:

http://pastebin.com/z7xJJbLX

When the Nunchuk is rotated right, the led turns on. When it is rotated left, it turns off.

You could use this script to debug your sketch. The problem is probably with your sketch.

Please let me know if you need more help.

Best regards,

Gabriel Bianconi.

PS: ccweb1 this may interest you. I'm still working on your problem, I'll answer your comment soon.

EricQuagliozzi 5 pts

Thanks Gabriel,

You were right, it seems I did something wrong with delay() in my sketch, now it runs fine.

Best regards,

Eric

ccweb1 5 pts

I'm trying to come up with a solution to my problem; should I be able to add a simple blink script to your demo and have the led on pin 13 flash as well as have the nunchuk values print out serially? I would think this would be very possable, but when I try to do this nothing happens. When I put "//" in front of

nunchuk.init(); (in the setup), the blink function works just fine. So back to my other post, do you think it has something to do with my nunchuk not inishalizing? Or hanging up the sketch?

GabrielBianconi 5 pts moderator

ccweb1 I'll investigate this and create this blink script this weekend and I'll contact you again.

Did you solder your WiiChuck adapter correctly? These numbers usually appear when the Wii Nunchuk is not connected correctly.

ccweb1 5 pts

GabrielBianconi Thanks, that would be great!

I thought the same thing in regards to those numbers normally coming up with a bad or wrong connection, I did print out and solder my own adapter, but I purchased one pre-made as well and I get the same results with both. :-(

GabrielBianconi 5 pts moderator

ccweb1 I managed to write a sketch that blinks LED13 and prints the data:

http://pastebin.com/3gPV9746

When I run this, the RX and TX LEDs are turned on. You should be seeing them too.

Please post pictures of your Arduino and the connections. It may help us find the solution.

Best regards,

Gabriel Bianconi.

ccweb1 5 pts

Gabriel,

Thank you so much for your help and your time. I hate to monopolize your time and I hope I'm not inconveniencing you, I really want this to work and I am not sure what I’m doing wrong.

Here are a few pics of my Arduino Uno R3, the Adapter, and my connections.

http://s65.photobucket.com/albums/h230/ccweb1/?act...

http://s65.photobucket.com/albums/h230/ccweb1/?act...

http://s65.photobucket.com/albums/h230/ccweb1/?act...

http://s65.photobucket.com/albums/h230/ccweb1/?act...

http://s65.photobucket.com/albums/h230/ccweb1/?act...

I placed your blink sketch into the Arduino software and uploaded it, it uploaded fine.

But after it is uploaded, it doesn’t do anything. If I open up the serial communication it is blank but when I unplug the nunchuk , the Tx led lights up and I get the generic data that you said most of the time means miss-wiring.

It wouldn’t have anything to do with my software would it. I have never done anything with I2c before and I’m at a loss and looking for any pointers. Do I need to try a different Arduino board to troubleshoot and rule things out? (I don’t have one, I’d have to get one, I did put a new IC chip into my board just to troubleshoot, but had the same results.)

I must be doing something wrong, lol so frustrating,

Thanks againd for your much needed input!

GabrielBianconi 5 pts moderator

ccweb1 Hey!

The connections seem correct. You could try different parts, maybe one is defective. See if you can test another: Wii Nunchuk, Arduino Board, Wires, Adapter. Use another computer to upload the sketch. I really don't know what's wrong. =/

See if you can test these parts and let me know how it ends.

Best regards,

Gabriel.

ccweb1 5 pts

Ok, I rounded up all the pieces to the puzzle and my first attempt to make it all come together didn't go as I would have hoped.

I'm using an Arduino Uno Purchased recently,

Arduino 1.0 software,

a wiichuck adapter,

a Nintendo Wii Nunchuck,

When I upload your sketch I see the Tx and Rx leds flash while uploading then they stop.

After uploading I open the serial monitor and it's blank, if I unplug the nunchuck the Tx led flashes continually and I get values similar to Mikael and others;

"20486 -32248 1024 1026 -21466 1 1" that continually repeat, if I plug the nunchuck back in the serial communication stops. Nothing I do to the nunchuck provides any data on the com port.

I referenced Mikael's post and my connections are the same

- to gnd

+ to 3.3

d to A4

c to A5

I have referenced your responce to earlier posts and I am almost positive I am hooked up correctly, But would be willing to post pics.

I made sure the nunchuck was connected when i powered up the Arduino Uno Board...

Are you supposed to see Rx and Tx communication on the leds while the program is running? (I am not.)

Any suggestions would be a big help,

Thanks

SebastianZenobio 5 pts

This library, run with Nunchucks wireless?

GabrielBianconi 5 pts moderator

SebastianZenobio It was designed to work with original Nunchuks. Some 3rd party controllers may also work, but not every model does. I suggest that you buy an original model.

SebastianZenobio 5 pts

ok perfect :D, tnks!!!!!!. One more question, in the library where configure A4 and A5 ??

GabrielBianconi 5 pts moderator

SebastianZenobio You can't change this, because these pins are used for the I2C protocol. (I don't know if this is possible, but it would require a great modification).

SebastianZenobio 5 pts

GabrielBianconiSebastianZenobio tnks a lot for all

SebastianZenobio 5 pts

Tnks for your response, I refer to the ports used by nunchuck in library

GabrielBianconi 5 pts moderator

SebastianZenobio I'm sorry =) Do you mean the pins? If you are using an Arduino Uno, you must use +3.3V (+), GND (-), A4 (d) and A5 (c). If you are using an Arduino Mega, please refer to:

http://www.gabrielbianconi.com/blog/how-to-hook-up...

GabrielBianconi 5 pts moderator

SebastianZenobio In the Arduino IDE, you can select the correct port under Tools > Serial Port.

MikaelPratama 5 pts

Thank you for your library... It seems will help me a lot.

I have a problem like several person below.. It keeps send this value to serial 20486 -32248 1024 1026 -21466 1 1

I am using Original Nintendo Wii Nunchuk.

I newest Arduino... (just bought it October 2011).

I connect '+' to 3.3V,

'-' to GND,

'c' to A5,

'd' to A4.

Would you mind if you help me?

GabrielBianconi 5 pts moderator

MikaelPratama This problem usually happens when you don't wire it correctly. Are you using an Arduino Uno or an Arduino Mega? If you are using an Arduino Mega, you should check:

http://www.gabrielbianconi.com/blog/how-to-hook-up...

If you are using an Arduino Uno, you have connected it correctly. However, you may have made a mistake while connecting to the Wii Nunchuk's connector. Are you using an adapter? Make sure that you have wired it correctly. Look at the following figure. It may help you:

http://wiibrew.org/w/images/thumb/e/eb/Wii_Connect...

The connections to your Arduino seems correct.

If you still don't manage to fix it, please let me know and we'll look more in this. Good luck!

MikaelPratama 5 pts

GabrielBianconi No it is already work thank you...Because I am new in electronics, I did not solder the connector correctly.

It is now works perfectly.And I like your library... thank you.. :D

ccweb1 5 pts

Wow, this library is great. Just what I have been looking for. I have tried other libraries and there examples, but they wont compile. I'm thinking it is because I'm using Arduino 1.0.

I am new to Arduino but feel I'm picking it up very quickly, but know I have lots to learn in the code writing department. I am working on a project and would like to integrate a wii nunchuck. I intend to make my own nunchuck adapter, but for now I don't have the time so I ordered one. Should be here soon. I would like to get started on my code before it gets here.

So my question(s) is/are; what are the input values/ranges for the nunchuck axises? I'm assuming z button and c button are 1 or 0(is this correct?), but what are the accel and joy ranges? I see Adrian (in his post) listed a rang of 400-650, and Gabriel mentions 0-1024.

If using servos, is the best method to use the map function or write a task function similar to that of todbot?

Example : http://todbot.com/blog/bionicarduino/

downloaded nunchuck sketch

float tiltx = nunchuk.accelX(); // x-axis, in this case ranges from ~70 - ~185

tiltx = (tiltx - 70) * 1.57; // convert to angle in degrees, roughly

accelpulseWidthLR = (tiltx * 5.6) + minPulse; // convert angle to microseconds

Also do the ranges change if your using a third party nunchuck vs. a Nintendo nunchuck?

Thanks

ccweb1

GabrielBianconi 5 pts moderator

ccweb1 I'm glad you liked the library :D

Theoretically, the values for the accelerometer would be in the 0-1024 range. However, the values have a smaller range, like Adrian said. I believe that these values change from controller to controller, so I think that the best solution would be to test them using your own controller. Regarding the buttons, 0 and 1 are the only possible values.

I also plan to work with servos and an Arduino Nunchuk. I've ordered some servos, but they haven't arrived yet, so I can't really help you with this right now. When I get them, I'll test some scripts and I'll let you know what works best for me.

When you complete your project, post it here. I'd like to see it! Thank you for visiting!

Adrian Martinez 5 pts

ccweb1 The ranges I used were the ranges that were printed to serial port using the example GabrielBianconi provides. Regarding the map function, I'm still pretty new to Arduino and map() was the only way I know how to use the accel/analog ranges to control the servo. I haven't figured out the twitch issue I'm having, I'm curious to see if you have the same problem. Keep us posted.

darkside40 5 pts

First of all thanks for your work.

But i got a problem with your library. I use an Arduino Uno R3, a Wiichchuck Adapter (wired to PIns A2-3-4-5) and an origina Nintendo Nunchuck.

Yesterday i just tried your demo program, but the funny thing is as long as the Nunchuck is connected the Serial Monitor stays blank. When i disconnect the Nunchuck many rows filled with 20486 -32248 1024 1026 -21466 1 1, when i reconnect the Nunchuck the Serial Monitor stops.

To ensure that my Nunchuck works correct i tried the Demo made by todbot, and there i get Values when the Nunchuck is connected and the change when the Nunchuck is moved.

GabrielBianconi 5 pts moderator

darkside40 The difference between my library and todblog's library is that mine does not use Analog In pins 2/3. You have to wire + to +3.3V and - to GND. Todblog's library uses +5V. Although this works, it will reduce the life span of your Wii Nunchuk, which should only receive 3.3V. This is why I decided to use the other pins. It should work if you change this. Please let me know if that fixes your problem.

darkside40 5 pts

GabrielBianconi Thanks for the Hint, that did the trick. I just wired it up like it was mentioned on the todblog site. Maybe you should mention that tip in your instruction.

Thanks for your work at this library.

GabrielBianconi 5 pts moderator

darkside40 I'm glad that it worked for you. I'm going to improve the instruction, thanks for the tip!

I am using arduino 1.0 and an arduino Duemilanove board.

I just installed your library and tried to compile your example program and got the following error messages:

class TwoWire has no member named 'read'

class TwoWire has no member named 'write'

No modifications have been done to the standard Wire library.

GabrielBianconi 5 pts moderator

This is wierd, since Wire.read and Wire.write were created in Arduino 1.0. Are you sure that you are using this version? Have you configured something to use an older Wire library or something like that? Many people, including I, are using Arduino 1.0 without problems.

GabrielBianconi 5 pts moderator

If you manage to fix this, please comment here so that others with the same problem can see it. Also, if someone knows the answer for this, please let us know.

christiangoff 5 pts

I am having the same issue. all I did was add the libraries and copy the demo code. Here is my error log.

sketch_jan14a.cpp: In function 'void nunchuck_init()':

sketch_jan14a:31: error: call of overloaded 'write(int)' is ambiguous

C:\Documents and Settings\cgoff\Desktop\arduino-1.0\libraries\Wire/Wire.h:55: note: candidates are: virtual size_t TwoWire::write(uint8_t)

C:\Documents and Settings\cgoff\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*) sketch_jan14a.cpp: In function 'void send_zero()':

sketch_jan14a:39: error: call of overloaded 'write(int)' is ambiguous

C:\Documents and Settings\cgoff\Desktop\arduino-1.0\libraries\Wire/Wire.h:55: note: candidates are: virtual size_t TwoWire::write(uint8_t)

C:\Documents and Settings\cgoff\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*) sketch_jan14a.cpp: In function 'void loop()':

sketch_jan14a:49: error: 'class TwoWire' has no member named 'receive'

As of Arduino 1.0, the Wire.receive() function was renamed to Wire.read() for consistency with other libraries.

sketch_jan14a.cpp: In function 'char nunchuk_decode_byte(char)':

any help would be appreciated christian.goff at gmail.com

GabrielBianconi 5 pts moderator

christiangoff It seems that you are using both my library and todbot's library (since you have an error in nunchuck_init() function, which my library doesn't have). You should only use mine (or his). Create a sketch and add only my files to it. I think that this is the problem. Let me know if this fixes it.

christiangoff 5 pts

GabrielBianconi

Turns out you were right. in my haste to make it work, I was using two different libraries. Just now used only your files with success. Through my stumbling, however, I figured out the read/write issue that was bothering me as well. the new wires library requires wire.read instead of wire.receive and instead of wire.send (0x00) it needs wire.send (byte (0x00)).

Thanks for your prompt reply. You have been a huge help in my project.

GabrielBianconi 5 pts moderator

christiangoff Hey Christian! I'm glad that it worked. Regarding the Wire library, I added support to Arduino 1.0 and tried to add to older versions too, but there is one problem which needs to be fixed (I'm working on this). But it should work with the latest version. When you complete your project, please send me a link to it. I'd be interested in knowing what you built.

Adrian Martinez 5 pts

Thank you for this library, I love it. I used the it to make a pan and tilt unit! I only have one problem. The servos(HITEC HS-322HD) twitch like mad. Check out the YouTube video I linked. I'm pretty sure its not the servos because when I upload the sweep example(Arduino1.0 on an ArduinoUno r2) they work smoothly. I'm not using an aftermarket nunchuk and as you can see I am holding it very still. It pans and tilts but very twitchy. What do you think is the problem?

This is my loop

nunchuk.update();

val = nunchuk.accelX;

val = map(val, 400, 650, 0, 170);

myservo.write(val);

Serial.print(nunchuk.accelX);

delay(15);

val2 = nunchuk.accelY;

val2 = map(val2, 400, 650, 0, 179);

myservo2.write(val2);

Serial.print(nunchuk.accelY);

delay(15);

servoTwitch

http://youtu.be/rbvAG0eUT2Y

Thanks again

GabrielBianconi 5 pts moderator

Adrian Martinez I have an idea. The precision of the accelerometer is very high (0-1024), so a very small movement would change the value. So, you could try to divide its value by ten and then round the value. By doing this, the precision would be much smaller (0-124). Try this and let me know if it works!

Adrian Martinez 5 pts

GabrielBianconi Thanks for the suggestion. Unfortunately I am still very new to programming and don't know exactly where to reduce these values. I'm going to keep learning as much as I can(Google Search University). I'll come back and post when I get it to work.

GabrielBianconi 5 pts moderator

Adrian Martinez You can do it like this.

Instead of:

val = nunchuk.accelX;

Write:

val = nunchuk.accelX/10;

And instead of:

val = map(val, 400, 650, 0, 170);

Write:

val = map(val, 40, 65, 0, 170);

Do the same for val2. Let me know if this works for you.

Adrian Martinez 5 pts

GabrielBianconi Still not working smoothly. I have tried many different configurations with the numbers. Now when I program the servos to analogX and Y it works perfectly. I'm still trying to find a solution to the accel issue.

GabrielBianconi 5 pts moderator

Adrian Martinez I bought some servos some days ago, but they haven't arrived yet. I'm going to build something using my Wii Nunchuk and them, so if I manage to find a solution, I'll post it for you. I don't know how long it'll take for them to arrive, since I'm importing them. I hope that they arrive in 1-2 weeks. In the meantime, if you find a solution, please post it here. I'm sorry, but I can't help you more until they arrive.

christiangoff 5 pts

GabrielBianconiAdrian Martinez

Your delay is set really low. it is sending a new position to the servo every 15 milliseconds. Combine that with the extremely sensitive accelerometer and it'll twitch. change delay(15); to delay(100); and see if that helps. that will give 10 positions per second instead of 67.

GabrielBianconi 5 pts moderator

christiangoffAdrian Martinez Thanks Christian! Let's see if this works for Adrian Martinez .

Adrian Martinez 5 pts

Changing the delay helped a little. I still get a random twitch every now and then.

rhbgames 5 pts

Ignore previous comment. Our problem was that we connected to digital pins 4 and 5 rather than analog pins. Once we fixed that, we observed the expected behavior. Thanks again!!!

GabrielBianconi 5 pts moderator

rhbgames I'm glad it's working!

rhbgames 5 pts

Thanks so much for providing this library! It seems pretty easy to use, but we have not yet been successful. We have an Arduino Uno and a standard Wii Nunchuck.

When uploading the program and opening the serial monitor (set to 19.2) we see many rows of:

20486 -32248 1024 1026 -21466 1 1

Since it is scrolling by so quickly, it is hard to tell if anything is changing - but doing something simple like pressing/releasing the C and/or Z buttons never seems to change the final two values to anything other than "1 1". I sense that we might be close, but just missing some key piece.

I was assuming that if I pushed on the Nunchuck joystick I would see the x or y values change in a somewhat smooth manner - but perhaps I was mistaken.

tomydb 5 pts

Hi Gabriel,

I buy a nunchuk on DealExtreme. In the comments of the item, a user claims to have been able to control and explain how ( http://club.dealextreme.com/forums/Forums.dx/threa... ), but I could not set that in your code. I hope you can help!.

Regards

GabrielBianconi 5 pts moderator

tomydb Hey Tomy,

According to that website, the I2C address is different. Instead of using 0x52, you should use 0xA4 to initialize and 0xA5 to get values. I modified the ArduinoNunchuk.cpp file for you. You can find this new version here:

https://gist.github.com/1562252

Replace the file in my library with this one. Note that this version only works with the DealExtreme Wii Nunchuk. Let me know if this worked.

Best regards,

Gabriel.