Wii Nunchuck hack: making an electronic level with Arduino compatible JeonLab mini v1.3

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.
Wii Nunchuck PCB-Joystick

I don’t need the (broken) joystick part, so I cut off that part.
Accelerometer part of the Wii Nunchuck PCB top
The accelerometer chip (A7260) is shown.

The I2C converter is at the bottom of the PCB.
Accelerometer part of the Wii Nunchuck PCB bottom

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.
Clear case
Clear case width
Clear case height

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.
JeonLab mini v1.3 in clear case with CR123A

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.
Wii Nunchuck PCB on JeonLab mini v1.3 in case

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

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

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
 * https://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.

Bubble LEDs
assembled bubble LEDs and resistors
assembled JeonLabmini v1.3 - Wii Nunchuck - bubble LEDs

The tiny switch found from a broken camera.
micro switch for calibration

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.
Calibration switch connection

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.
Power supply parts
Battery contacts from 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.
battery holder with 3.3V regulator

This is assembled power supply in the case.
power supply with rearragned caps

Fully assembled Wii Nunchuck Level:
Completed Wii Nunchuck Level top

When it is leveled:
Wii Nunchuck Level leveled

When it is tiled to left:
Wii Nunchuck Level tilted left

When it is tilted to right:
Wii Nunchuck Level tilted right

And here is the Youtube video showing how it works.

Advertisements
About

Opto-mechatronic Engineering scientist.

Posted in Arduino, JeonLab mini, Modification
6 comments on “Wii Nunchuck hack: making an electronic level with Arduino compatible JeonLab mini v1.3
  1. […] background-position: 50% 0px; background-color:#222222; background-repeat : no-repeat; } jeonlab.wordpress.com – Today, 10:04 […]

  2. […] [Jeon] has a nice write up on his blog about how he used the accelerometerchip from a Wii nun-chuck & Arduino. This is very well documented and has the source code available, I think this would be another great beginners project for Arduino beginners! […]

  3. Robert says:

    Ok, this or will home he sense to make some levelling devise fir my other hobbie: astronomy.
    Your level will serve well when setting up tripod in the dark and it light up to let me know when my tripod is levelled!?, great!! Thanks again!! Robert Calgary, AB

    • jeonlab says:

      I also have a telescope and enjoy to watch stars from time to time. Since last December, I have had a few good times to watch Venus. Yes, you can use the accelerometer as a level, but there are things that might discourage you. First of all, the quality of the accelerometer in Wii Nunchuck is not very good. It’s not very accurate and not very stable. And it’s quite sensitive to the environment temperature and you don’t want to calibrate every night you go out with your telescope. Personally, I use a bubble level for the telescope.

      • Robert says:

        Glad to have your quick reply!!
        Okay then, I’ll keep this one as a side dish, when all other projects that I want to complete ARE completed, then I will ate a close look at it!!
        I have a little 2 years old boy… And it s draining a lot of my energy… By the time I put him on bed, AND the skies is good, AND it is a Friday or Saturday….. So guess how many nights I could go out and have my viewing session……

        I have a 8″ SCT, an o,d Celestron N8i that I bought used in Dec 2012….

        So quite new for me as well…..
        A lot of my project are involving with or to be used for astronomy….

        Glad to find your blog!!

        Emmanuel.

        Robert Ni

      • jeonlab says:

        Your telescope is much better than mine which is only 5.1″ without any fancy accessories. But still good enough to watch sky with my two teenage boys. I hope I could spend more time to watch sky this year.
        I’m glad you found my blog, too. I have been too busy with my work to do my personal hobbies. I will try to post more exciting projects here.
        Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

March 2012
S M T W T F S
« Feb   Apr »
 123
45678910
11121314151617
18192021222324
25262728293031
Archives

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 11 other followers

%d bloggers like this: