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:
- http://www.windmeadow.com/node/42
- http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/
- http://wiibrew.org/wiki/Wiimote/Extension_Controllers
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:
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.
Thanks Gabriel,
You were right, it seems I did something wrong with delay() in my sketch, now it runs fine.
Best regards,
Eric
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?
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.
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. :-(
ccweb1 I managed to write a sketch that blinks LED13 and prints the data:
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.
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!
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.
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
This library, run with Nunchucks wireless?
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.
ok perfect :D, tnks!!!!!!. One more question, in the library where configure A4 and A5 ??
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).
GabrielBianconiSebastianZenobio tnks a lot for all
Tnks for your response, I refer to the ports used by nunchuck in library
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:
Where Sets the ports to be used??
SebastianZenobio In the Arduino IDE, you can select the correct port under Tools > Serial Port.
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?
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!
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
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
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!
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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
Thanks again
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!
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.
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.
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.
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.
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.
christiangoffAdrian Martinez Thanks Christian! Let's see if this works for Adrian Martinez .
Changing the delay helped a little. I still get a random twitch every now and then.
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!!!
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.
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
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.
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.
- spam
- offensive
- disagree
- off topic
Like