• Music
  • Hardware
  • Photography
  • Web
  • Story

Ambilight

PreviousPauseNext

Parts

Arduino Board:
http://www.adafruit.com/products/50

Ambient Monitor Lighting Kit:
http://www.adafruit.com/products/461

USB Cable:
http://www.adafruit.com/products/62

How To

http://www.ladyada.net/make/adalight/

Notes

Project in progress.

The colorful photo is a prototype demonstrating a button and a knob as controlling input, with an LCD screen displaying input values.

Example code below responds to two inputs: the button switches between display modes, the knob controls the direction of movement left or right as well as the speed.

#include "SPI.h"
#include "WS2801.h"

// include the library code:
#include <LiquidCrystal.h>

/*****************************************************************************
Example sketch for driving WS2801 pixels
*****************************************************************************/

// Choose which 2 pins you will use for output.
// Can be any valid output pins.
// The colors of the wires may be totally different so
// BE SURE TO CHECK YOUR PIXELS TO SEE WHICH WIRES TO USE!
int dataPin = 2;
int clockPin = 13;
// Don't forget to connect the ground wire to Arduino ground, and the +5V wire to a +5V supply

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

//variable potentiometer - pin Analog 0
int sensorPin = 0;
double sensorValue = 0;

//digital pin 4
int buttonPin = 4;
int buttonVal = 0;

int low = 0;
int high = 256 * 5;
  
// Set the first variable to the NUMBER of pixels. 25 = 25 pixels in a row
WS2801 strip = WS2801(25, dataPin, clockPin);

// Optional: leave off pin #s to use hardware SPI
// (pinout is then specific to each board and can't be changed)
//WS2801 strip = WS2801(25);

void setup() {

  // set up the LCD's number of columns and rows: 
  lcd.begin(16,2);
  
  // set up button
  pinMode(buttonPin, INPUT);
  
  // setup LCDs
  strip.begin();

  // Update the strip, to start they are all 'off'
  strip.show();
}


void loop() {
  // Some example procedures showing how to display to the pixels

  
  //colorWipe(Color(255, 0, 0), 50);
  //colorWipe(Color(0, 255, 0), 50);
  //colorWipe(Color(0, 0, 255), 50);
  
  rainbowCycle(20);
  
  rainbow(20);
}

void rainbow(uint8_t wait) {
  int i, j;
  
  while (j >= low && j <= high) { 
  //for (j=0; j < 256; j++) {     // 3 cycles of all 256 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel( (i + j) % 255));
    }  
    strip.show();   // write all the pixels out

    lcd.setCursor(0, 0);
    lcd.print("cycle: "); 
    lcd.print(j);
    
    sensorValue = analogRead(sensorPin);
    
    sensorValue = sensorValue / 50 - 10;

    lcd.setCursor(0, 1);
    lcd.print("wait: "); 
    lcd.print(sensorValue);

    if (sensorValue < 0) {
      sensorValue = sensorValue - (sensorValue * 2);
      j--;
    } else {
      j++;
    }
    
    if (j == high) {
      j = low;
    } else if (j == low) {
      j = high; 
    }

    delay(sensorValue);
    
    buttonVal = digitalRead(buttonPin);
    if (buttonVal == LOW) {
      break;
    }
    
  }
  
}

// Slightly different, this one makes the rainbow wheel equally distributed 
// along the chain
void rainbowCycle(uint8_t wait) {
  int i, j;
  

  
  while (j >= low && j <= high) {
  //for (j=0; j < 256 * 5; j++) {     // 5 cycles of all 25 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      // tricky math! we use each pixel as a fraction of the full 96-color wheel
      // (thats the i / strip.numPixels() part)
      // Then add in j which makes the colors go around per pixel
      // the % 96 is to make the wheel cycle around
      strip.setPixelColor(i, Wheel( ((i * 256 / strip.numPixels()) + j) % 256) );

    }  
    strip.show();   // write all the pixels out

    lcd.setCursor(0, 0);
    lcd.print("cycle: "); 
    lcd.print(j);
    
    sensorValue = analogRead(sensorPin);
    
    sensorValue = sensorValue / 50 - 10;

    lcd.setCursor(0, 1);
    lcd.print("wait: "); 
    lcd.print(sensorValue);

    if (sensorValue < 0) {
      sensorValue = sensorValue - (sensorValue * 2);
      j--;
    } else {
      j++;
    }
    
    if (j == high) {
      j = low;
    } else if (j == low) {
      j = high; 
    }
    
    
    delay(sensorValue);
    
    
    buttonVal = digitalRead(buttonPin);
    if (buttonVal == LOW) {
      break;
    }
    
  }
}

// fill the dots one after the other with said color
// good for testing purposes
void colorWipe(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

/* Helper functions */

// Create a 24 bit color value from R,G,B
uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}

//Input a value 0 to 255 to get a color value.
//The colours are a transition r - g -b - back to r
uint32_t Wheel(byte WheelPos)
{
  if (WheelPos < 85) {
   return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
   WheelPos -= 85;
   return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170; 
   return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

kai @ think in 3d.net