Skip to content

Instantly share code, notes, and snippets.

@holachek
Created July 15, 2013 18:49
Show Gist options
  • Save holachek/6002368 to your computer and use it in GitHub Desktop.
Save holachek/6002368 to your computer and use it in GitHub Desktop.
TechChange Arduino Mood light! To run it this code, you'll need an Arduino Uno (or derivative), a piezo element, and a WS2801-compatible RGB LED (e.g., https://www.sparkfun.com/products/10504). You'll also need to download & install the FastSPI_LED library for Arduino: https://code.google.com/p/fastspi/
// TechChange Mood Lamp
// Version 0.1
// Michael Holachek
// Hardware:
// WS2801 LED connected to pins A3-A5
// Piezo element connected to pin 11 and ground
#include <FastSPI_LED.h>
#define PIEZO 11
#define LED_PIN A3
#define NUM_LEDS 1
// Set up WS2801 communication
struct CRGB { unsigned char g; unsigned char r; unsigned char b; };
struct CRGB *leds;
// TechChange colors!
int blue[3] = {74, 162, 217};
int yellow[3] = {253, 229, 9};
int black[3] = {0, 0, 0};
// initial colors
int redVal = black[0];
int grnVal = black[1];
int bluVal = black[2];
// mood lamp options
int wait = 10;
int hold = 100;
int repeat = 3;
int j = 0;
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
void setup(){
// power for WS2801 LED
pinMode(A5, OUTPUT);
digitalWrite(A5, LOW);
pinMode(A4, OUTPUT);
digitalWrite(A4, HIGH);
// init WS2801 LED
FastSPI_LED.setLeds(NUM_LEDS);
FastSPI_LED.setChipset(CFastSPI_LED::SPI_TM1809);
FastSPI_LED.setPin(LED_PIN);
FastSPI_LED.init();
FastSPI_LED.start();
leds = (struct CRGB*)FastSPI_LED.getRGBData();
// start up by displaying blue
snapTo(blue);
// play the TechChange theme song!
pinMode(PIEZO, OUTPUT);
tone(PIEZO, 262);
delay(150);
noTone(PIEZO);
delay(250);
tone(PIEZO, 262);
delay(150);
noTone(PIEZO);
delay(100);
tone(PIEZO, 392);
delay(150);
noTone(PIEZO);
delay(200);
tone(PIEZO, 392);
delay(150);
noTone(PIEZO);
delay(100);
snapTo(yellow);
tone(PIEZO, 330);
delay(200);
noTone(PIEZO);
delay(5000);
}
void loop(){
// mood lamp
int randomColor[3] = {random(0, 250), random(0, 250), random(0, 250)};
fadeTo(randomColor, random(0, 10), random(0, 10));
}
// LED functions
// instant snap to color
void snapTo(int color[3]){
for(int n=0; n<NUM_LEDS; n++){
leds[n].r = color[0];
leds[n].g = color[1];
leds[n].b = color[2];
}
FastSPI_LED.show();
}
// calculation function for crossfading
int calculateStep(int prevValue, int endValue) {
int step = endValue - prevValue; // What's the overall gap?
if (step) { // If its non-zero,
step = 1020/step; // divide by 1020
}
return step;
}
int calculateVal(int step, int val, int i) {
if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
if (step > 0) { // increment the value if step is positive...
val += 1;
}
else if (step < 0) { // ...or decrement it if step is negative
val -= 1;
}
}
// Defensive driving: make sure val stays in the range 0-250
if (val > 250) {
val = 250;
}
else if (val < 0) {
val = 0;
}
return val;
}
// turn all LEDs off
void off(){
for(int n=0; n<NUM_LEDS; n++){
leds[n].r = 0;
leds[n].g = 0;
leds[n].b = 0;
}
FastSPI_LED.show();
}
// fade LED to color
void fadeTo(int color[3], int wait, int hold){
// Convert to 0-250
int R = color[0];
int G = color[1];
int B = color[2];
int stepR = calculateStep(prevR, R);
int stepG = calculateStep(prevG, G);
int stepB = calculateStep(prevB, B);
for (int i = 0; i <= 1020; i++) {
redVal = calculateVal(stepR, redVal, i);
grnVal = calculateVal(stepG, grnVal, i);
bluVal = calculateVal(stepB, bluVal, i);
for(int n=0; n<NUM_LEDS; n++){
leds[n].r = redVal;
leds[n].g = grnVal;
leds[n].b = bluVal;
}
FastSPI_LED.show();
delay(wait); // Pause for 'wait' milliseconds before resuming the loop
}
// Update current values for next loop
prevR = redVal;
prevG = grnVal;
prevB = bluVal;
delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment