Skip to content

Instantly share code, notes, and snippets.

@apetrone
Created December 24, 2013 20:51
Show Gist options
  • Save apetrone/8117716 to your computer and use it in GitHub Desktop.
Save apetrone/8117716 to your computer and use it in GitHub Desktop.
LPD8806 Holiday Lights
/* 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