Created
July 15, 2013 18:49
-
-
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/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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