I have posted a project on using the accelerometer chip in the broken Wii Nunchuck. It was broken: the joystick did’t work. However, the accelerometer chip in the Nunchuck was intact and it also has the I2C interface which can be easily communicate with Arduino (or compatible board) with the Wire.h library.
I have seen those applications on iPod touch or Android tablets that can be used as a level using their built-in accelerometer sensor chip with a nice graphic showing bubble level. I thought I could make one like that with the Wii Nunchuck and started building one. I had bought a Wii Nunchuck from ebay to replace my kids’ broken Nunchuck for less than $10 (I don’t remember exactly) and I thought it was much cheaper to buy them than to buy the accelerometer with I2C interface or breakout boards so I bought a couple more at that time.
The joystick and the PCB look like this.

I don’t need the (broken) joystick part, so I cut off that part.

The accelerometer chip (A7260) is shown.
The I2C converter is at the bottom of the PCB.

Now I need a case for this project and found perfect size clear acrylic case from my junk box. I don’t even remember where I got it.



The width inside of the case was almost perfect for the JeonLab mini v1.3. I had to file off about half mm of the PCB. I also thought to use a 3.0V CR123A battery for this project.

But later I changed the power supply to a 3.3V regulated with a 12V A23 battery for better stability.
The cut PCB from the Nunchuck was glued on top of the ATmega328P chip on the JeonLab mini v1.3.

The I2C wires, clock and data, are connected to the analog pin 5 and 4 on the JeonLab mini v1.3, respectively.

I also connected the power for the Nunchuck board to the JeonLab mini v1.3 board as shown below, but this was my mistake.

The power supply I thought was 3.0V battery, so I thought sharing the power should be fine. BUT I forgot the program upload through the FTDI. The accelerometer chip and the I2C interface need 3.3V (3.0-3.6V) and the ATmega328 on the JeonLab mini v1.3 (and other Arduino compatible boards as well) can work 3-5V. The Nunchuck data reading header, nunchuck_funcs.h (from WiiChuckDemo by Tod E. Kurt) provides the settings for utilizing the analog pins 3 and 2 as power source for the Nunchuck board but this provides 5V, not 3.3V. The problem is that 5V supply to the Nunchuck board could damage the chip(s) either the accelerometer or the I2C chip or both. Actually, the first one I used had been unstable and noisy, so it had to be replaced with a new one. That’s when I decided to change the power source from the 3V battery to 12V battery with a 3.3V regulator and added a Schottky diode (1N5819) to protect the Nunchuck board from FTDI 5V supply.
Now, let me explain the design. Using the accelerometer sensor on the Nunchuck board, it detects which side is tilted and send the 3 axis data to the Arduino program loaded JeonLab mini board through the I2C protocol. The program compares the current data to the stored (in EEPROM of the ATmega328P) calibration data. There are three stages of displaying: 1) If the value is within certain range, it will turn on the central red LED connected to the digital pin 7; 2) If the value is greater than the range (sens in the program) and less than 2 times of the range (sens), it will turn on the red LED and one green LED at the opposite (in order to simulate the bubble direction) side of the tilt; 3) If the value is greater than 2 times of the range (sens), then only the green LED is turned on.
The calibration values are the neutral value of each axis reading when it is leveled on that axis. For example, the Nunchuck data reading is between 60-70 (these values are different from sensor to sensor) at -g (upside down) on that axis and is over 170 at g (up right). So the neutral (leveled) value of each axis is about 120-130. The calibration begins when the pin 10 goes HIGH by connected to V+ with a small push button switch pressed. One the calibration process begins, in order to give the user some time to put the device down on a flat surface, it waits until the central red LED blinks a few times. The actual calibration is done really quickly and followed by a few quicker blinks.
Here is the whole program.
/*
* Wii_Nunchuck_Level
* Feb-Mar 2012, Jinseok Jeon
* http://jeonlab.wordpress.com
*
* Wii Nunchuck data read:
* nunchuck_funcs.h from WiiChuckDemo by Tod E. Kurt,
* http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/
*/
#include
#include
#include "nunchuck_funcs.h"
byte accl[3]; //accelerometer readings for x, y, z axis
int calPin = 10; //calibration pin
int sens = 1; //sensitivity
int orient;
void setup()
{
nunchuck_init();
for (int i=5;i<10;i++) {
pinMode(i, OUTPUT);
} //9 left, 8 up, 7 center, 6 down, 5 right
pinMode(calPin, INPUT);
delay(100);
}
void loop()
{
//if the calibration pin is pressed, jump to funcion calibrate()
if (digitalRead(calPin) == HIGH) calibrate();
getData();
if (orient == 1 || orient == 2) {
if (abs(accl[0]-EEPROM.read(0 + orient*10)) sens) digitalWrite(5, HIGH);
if (EEPROM.read(0 + orient*10)-accl[0] > sens) digitalWrite(9, HIGH);
}
if (orient == 3 || orient == 4) {
if (abs(accl[1]-EEPROM.read(1 + orient*10)) sens) digitalWrite(8, HIGH);
if (EEPROM.read(1 + orient*10)-accl[1] > sens) digitalWrite(6, HIGH);
}
if (orient == 5 || orient == 6) {
if (abs(accl[0]-EEPROM.read(0 + orient*10)) <= 2*sens && abs(accl[1]-EEPROM.read(1 + orient*10)) sens) digitalWrite(5, HIGH);
if (EEPROM.read(0 + orient*10)-accl[0] > sens) digitalWrite(9, HIGH);
if (accl[1]-EEPROM.read(1 + orient*10) > sens) digitalWrite(8, HIGH);
if (EEPROM.read(1 + orient*10)-accl[1] > sens) digitalWrite(6, HIGH);
}
delay(50);
for (int i=5;i<10;i++) { //turn off all LEDs
digitalWrite(i, LOW);
}
}
void getData()
{
nunchuck_get_data();
accl[0] = nunchuck_accelx();
accl[1] = nunchuck_accely();
accl[2] = nunchuck_accelz();
orient = orientation(); //get orientation
}
void calibrate()
{
for (int i=0;i<3;i++) {
digitalWrite(7, HIGH);
delay(500);
digitalWrite(7, LOW);
delay(500);
}
getData();
for (int i=0;i<3;i++) {
EEPROM.write(i + orient*10, accl[i]);
}
for (int i=0;i 125 && accl[0] 110 && accl[2] 170) orient = 1; //bottom on floor
else if (accl[1] 110 && accl[1] 110 && accl[2] 180) orient = 3; //left on floor
else if (accl[0] 110 && accl[1] 125 && accl[0] 170) orient = 5; //back on floor
else if (accl[2] < 80) orient = 6; //front on floor
}
return orient;
}
Some pictures below show the assembling procedure of the LEDs and the tiny switch from a broken camera. Here I want to give all of you a note: don’t throw away any broken electronics. Because they don’t work doesn’t mean they are garbage. There are a lot of good parts you can use for other projects.
The tiny switch found from a broken camera.

A 10k resistor is used to pull down the pin 10 and this tiny switch is connected to the pin 10 and V+ to trigger the calibration.

Now these are the parts for the power supply. There are a piece of prototype board, a Schottky diode (from a broken power adapter), 0.1uF ceramic capacitor, a 10uF electrolyte capacitor, 12V A23 battery, 3.3V regulator LD33V, and battery contacts also found from the broken camera.


The battery contacts were modified a little bit and soldered on the board. The regulator doesn’t need the big heat sink so the metal part was cut on top and soldered on the board and it also form a perfect battery holder.

This is assembled power supply in the case.

Fully assembled Wii Nunchuck Level:

And here is the Youtube video showing how it works.






Pingback: Wii Nunchuck hack: making an electronic level with Arduino ... | Arduino Focus | Scoop.it