Tuesday, January 25, 2011

Color Wheel with Wii Nunchuck and Arduino

Today I want to show you how to use a Wii nunchuck to control your Arduino projects. In my example I used the nunchuck to simulate a color wheel with a full rgb LED. I connected a WiiChuck board directly to the Arduino using the analog ports. You can use them for the I2C communication and to power the board. There is a blog which already provides a library and some demo code to get you started.

I modified the demo code and had to adjust some coordinate bounds of my nunchuck. There are some formulars for calculating color wheels, but I took an easier approach and just mapped coordinate bounds of the color spectrums to the color wheel.
Note that my mapping is only a rough approximation. You also might need to adjust the bounds because your nunchuck readings could differ just a little bit.

The setup is easy. You just need to connect the WiiChuck board to the analog ports 5-2 and setup a circuit for your rgb LED. I have a rgb LED with 6 pins. Two for GND, two for blue, one for red and one for green. That's why my setup seems a little bit crowded.



The code isn't the prettiest one but it gets the job done for now.
#include <Wire.h>
#include "nunchuck_funcs.h"

//PWM Digital Pin layout for RGB LED
#define greenLED 6
#define blue1LED 9
#define blue2LED 10
#define redLED 11

byte joyx,joyy;
byte redVal,greenVal,blueVal;

void setup()
{
  nunchuck_setpowerpins();
  nunchuck_init(); // send the initilization handshake
}

void loop()
{
  nunchuck_get_data();

  joyx = nunchuck_joyx(); // idle position at approx 133, ranges from approx 31 - 232
  joyy = nunchuck_joyy(); // idle position at approx 130, ranges from approx 33 - 228

  //Red has its full intensity at y = 228 (approx upper bound).
  //When moving in x direction, y will decrease.
  //Red has its lowest intensity when it reaches the full intensity position of green or blue.
  //In my case approx y = 95.
  redVal = map(joyy >= 95 ? joyy : 95, 95, 228, 0, 255);

  //Green has its full intensity at approx x = 217 and approx y = 95.
  //Green has two x ranges. If y is above 95 then the x range is from 133 to 232.
  //If y is below 95 then the x range is from 44 to 217.
  greenVal = joyy >=95 ? map(joyx < 133 ? 133 : joyx, 133, 232, 0, 255) :
  map(joyx > 217 ? 217 : joyx < 44 ? 44 : joyx, 44, 217, 0, 255);

  //Blue has its full intensity at approx x = 44 and approx y = 95.
  //Blue has two x ranges. If y is above 95 then the x range is from 31 to 133.
  //If y is below 95 then the x range is from 44 to 217.
  blueVal = joyy >=95 ? map(joyx > 133 ? 133 : joyx, 133, 31, 0, 255) :
  map(joyx > 217 ? 217 : joyx < 44 ? 44 : joyx, 217, 44, 0, 255);

  //Because I also want to simulate white light I need to determine if the position is roughly in the middle.
  if(joyy > 125 && joyy < 135 && joyx > 125 && joyx < 135) {
    redVal=255;
    greenVal=255;
    blueVal=255;
  } 
  analogWrite(redLED, redVal);
  analogWrite(greenLED, greenVal);
  analogWrite(blue1LED, blueVal);
  analogWrite(blue2LED, blueVal);

  delay(100);
}
This video shows the nunchuck color wheel in action:

video

No comments:

Post a Comment