Created
December 24, 2013 20:51
-
-
Save apetrone/8117716 to your computer and use it in GitHub Desktop.
LPD8806 Holiday Lights
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
/* So I had 5 meters of LPD8806 lying around with no plans to ever use them. | |
They will be my holiday lights this year, driven by an Arduino Pro Mini 5v. | |
Date: December 2013 | |
Author: Adam Petrone | |
*/ | |
#include <SPI.h> | |
#include <LPD8806.h> | |
const uint8_t NUM_LEDS = 64; | |
const uint8_t DATA_PIN = 11; | |
const uint8_t CLOCK_PIN = 10; | |
LPD8806 strip( NUM_LEDS, DATA_PIN, CLOCK_PIN ); | |
const uint8_t NUM_LEDS2 = 94; // out of 96, because I removed two I thought were faulty. | |
const uint8_t DATA_PIN2 = 9; | |
const uint8_t CLOCK_PIN2 = 8; | |
LPD8806 strip2( NUM_LEDS2, DATA_PIN2, CLOCK_PIN2 ); | |
// gamma correction tables from Adafruit samples. These correct the RGB values | |
// on the LPD8806 so they're "perceptively" corrected. | |
PROGMEM prog_uchar gammaTable[] = { | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, | |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, | |
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, | |
4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, | |
7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, | |
11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, | |
16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, | |
23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, | |
30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39, | |
40, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50, | |
50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 62, | |
62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 74, 75, | |
76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, | |
92, 93, 94, 95, 96, 97, 98, 99,100,101,102,104,105,106,107,108, | |
109,110,111,113,114,115,116,117,118,120,121,122,123,125,126,127 | |
}; | |
void clear_color(LPD8806 & strip) | |
{ | |
for(uint8_t i = 0; i < strip.numPixels(); ++i) | |
{ | |
strip.setPixelColor( i, strip.Color(0, 0, 0) ); | |
} | |
} | |
void new_color(LPD8806 & strip, uint8_t z) | |
{ | |
for(uint8_t i = 0; i < strip.numPixels(); ++i ) | |
{ | |
int32_t red_color = strip.Color(255, 0, 0); | |
int32_t green_color = strip.Color(0, 255, 0); | |
if ((i % 2) == z) | |
{ | |
strip.setPixelColor( i, red_color ); | |
} | |
else | |
{ | |
strip.setPixelColor( i, green_color ); | |
} | |
} | |
} | |
void assign_multi_color(LPD8806 & pixels, uint8_t shift) | |
{ | |
uint32_t colors[] = { | |
pixels.Color(255, 255, 0), // yellow (because LPD8806's orange looks like red) | |
pixels.Color(255, 0, 0), // red | |
pixels.Color(255, 0, 255), // purple | |
pixels.Color(0, 0, 255), // blue | |
pixels.Color(0, 255, 0) // green | |
}; | |
uint8_t color_index = shift; | |
for(uint8_t i = 0; i < pixels.numPixels(); ++i ) | |
{ | |
// basic fill | |
pixels.setPixelColor(i, colors[color_index++]); | |
if (color_index > 4) | |
{ | |
color_index = 0; | |
} | |
} | |
} | |
uint8_t shift = 0; | |
void animate_lights(LPD8806 & pixels) | |
{ | |
assign_multi_color(pixels, shift); | |
pixels.show(); | |
} | |
void check_shift(uint8_t wait) | |
{ | |
delay(wait); // 2000 | |
shift++; | |
// num colors - 1 | |
if (shift > 4) | |
{ | |
shift = 0; | |
} | |
} | |
// "Larson scanner" = Cylon/KITT bouncing light effect; written by James Hayek | |
void scanner(LPD8806 & strip, uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t max_loops) { | |
int i, j, pos, dir; | |
pos = 0; | |
dir = 1; | |
for(i=0; i<((strip.numPixels()-1) * max_loops); i++) | |
{ | |
// Draw 5 pixels centered on pos. setPixelColor() will clip | |
// any pixels off the ends of the strip, no worries there. | |
// we'll make the colors dimmer at the edges for a nice pulse | |
// look | |
strip.setPixelColor(pos - 2, strip.Color(r/4, g/4, b/4)); | |
strip.setPixelColor(pos - 1, strip.Color(r/2, g/2, b/2)); | |
strip.setPixelColor(pos, strip.Color(r, g, b)); | |
strip.setPixelColor(pos + 1, strip.Color(r/2, g/2, b/2)); | |
strip.setPixelColor(pos + 2, strip.Color(r/4, g/4, b/4)); | |
strip.show(); | |
delay(wait); | |
// If we wanted to be sneaky we could erase just the tail end | |
// pixel, but it's much easier just to erase the whole thing | |
// and draw a new one next time. | |
for(j=-2; j<= 2; j++) | |
{ | |
strip.setPixelColor(pos+j, strip.Color(0,0,0)); | |
} | |
// Bounce off ends of strip | |
pos += dir; | |
if(pos < 0) | |
{ | |
pos = 1; | |
dir = -dir; | |
} | |
else if(pos >= strip.numPixels()) | |
{ | |
pos = strip.numPixels() - 2; | |
dir = -dir; | |
} | |
} | |
} | |
void setup() | |
{ | |
// set timer1 to default value | |
TCCR1B = TCCR1B & (0b11111000 | 0x03); | |
// set timer2 to default value | |
TCCR2B = TCCR2B & (0b11111000 | 0x04); | |
strip.begin(); | |
clear_color(strip); | |
strip.show(); | |
strip2.begin(); | |
clear_color(strip2); | |
strip2.show(); | |
delay(250); | |
} | |
void loop() | |
{ | |
uint8_t wait_time = 500; | |
uint8_t max_animate = 100; | |
for(uint8_t a = 0; a < max_animate; ++a) | |
{ | |
animate_lights(strip); | |
animate_lights(strip2); | |
check_shift(wait_time); | |
} | |
clear_color(strip); | |
scanner(strip2, 255, 255, 255, 30, 2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment