Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
384 lines (335 sloc) 9.93 KB
#include "LPD8806/LPD8806.h"
#include "SPI.h"
#include <avr/sleep.h>
#include "carrot.h"
//since data is on 11 and clock is on 13, we can use hardware SPI
LPD8806 strip = LPD8806(96);
int powerPin = 4;
int upModePin = 3;
int upColorPin = 2;
int upModeButtonState = HIGH;
int upModeButtonCycles = 0;
int upColorButtonState = HIGH;
int upColorButtonCycles = 0;
int CYCLES_DEBOUNCE = 2; //check the button for X ticks to see if it is bouncing
int MAX_COLORS = 8;
int MAX_MODES = 7;
int MAX_STRIPES = 5;
unsigned long tick = 0;
int mode = 1;
int color = 1;
uint16_t i, j, x, y ;
uint32_t c, d;
// Set the first variable to the NUMBER of pixels. 32 = 32 pixels in a row
// The LED strips are 32 LEDs per meter but you can extend/cut the strip
void ISR_Wake() {
detachInterrupt(0);
detachInterrupt(1);
}
void blackout() {
for(int i=0; i < strip.numPixels()+1; i++) {
strip.setPixelColor(i, strip.Color(0,0,0));
}
strip.show();
}
void triggerSleep() {
blackout();
attachInterrupt(0,ISR_Wake,LOW); //pin 2
attachInterrupt(1,ISR_Wake,LOW); //pin 3
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
//sleeping, until rudely interrupted
sleep_disable();
}
void triggerModeUp() {
++mode;
blackout();
}
void triggerColorUp() {
color++;
blackout();
}
void handleButtons() {
if(digitalRead(powerPin) == LOW) {
triggerSleep();
}
// software debounce
if(digitalRead(upModePin) != upModeButtonState) {
upModeButtonCycles++;
if(upModeButtonCycles > CYCLES_DEBOUNCE) {
upModeButtonCycles = 0;
upModeButtonState = digitalRead(upModePin);
if(upModeButtonState == LOW) {
triggerModeUp();
}
}
}
// software debounce
if(digitalRead(upColorPin) != upColorButtonState) {
upColorButtonCycles++;
if(upColorButtonCycles > CYCLES_DEBOUNCE) {
upColorButtonCycles = 0;
upColorButtonState = digitalRead(upColorPin);
if(upColorButtonState == LOW) {
triggerColorUp();
}
}
}
}
void handleStrip() {
switch(mode%MAX_MODES) {
case 0: //solid
c = GetColor(color%MAX_COLORS);
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
break;
case 1:
c = GetColor((tick%3+color)% MAX_COLORS);
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
break;
case 2:
if(tick % 15 == 0) {
c = GetColor(color%MAX_COLORS);
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
}
if(tick % 15 == 1) {
c = strip.Color(0,0,0);
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
}
break;
case 3: //chasers
d = (color / MAX_COLORS) % MAX_STRIPES + 1; //chaser
c = GetColor(color % MAX_COLORS); //color
j = tick % (strip.numPixels()/d);
for(i=0; i < strip.numPixels(); i++) {
if(i % (strip.numPixels()/d) == j) {
strip.setPixelColor(i, c);
}
else {
strip.setPixelColor(i, strip.Color(0,0,0));
}
}
break;
case 4: //chasers + statics
d = (color / MAX_COLORS) % MAX_STRIPES + 1; //chaser
c = GetColor(color % MAX_COLORS); //color
j = tick % (strip.numPixels()/d);
for(i=0; i < strip.numPixels(); i++) {
x = i % (strip.numPixels()/d);
if((x == j) || (x == 0)) {
strip.setPixelColor(i, c);
}
else {
strip.setPixelColor(i, strip.Color(0,0,0));
}
}
break;
case 5: //fuckin' rainbows
j = tick % 384;
for(i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 384 / strip.numPixels() * (color%MAX_COLORS)) + j) % 384));
}
break;
case 6: //carrot POV
j = tick % 158;
d = carrot[j];
//green //orange
c = (j < 30)?GetColor((color+2)%MAX_COLORS):GetColor((color+3)%MAX_COLORS);
for(i=0;i<32;i++) {
//adding 32 to the index makes it appear on the side opposite the controller
if(d & 0x00000001) {
strip.setPixelColor(i+32, c);
}
else {
strip.setPixelColor(i+32, strip.Color(0,0,0));
}
d >>= 1;
}
break;
}
strip.setPixelColor(strip.numPixels()-1, strip.Color(0,0,0)); //set that last LED off because it overlaps
strip.show();
}
void setup() {
// Start up the LED strip
strip.begin();
pinMode(powerPin, INPUT); // declare pushbutton as input
pinMode(upModePin, INPUT); // declare pushbutton as input
pinMode(upColorPin, INPUT); // declare pushbutton as input
triggerSleep();
}
void loop() {
tick++;
handleStrip();
handleButtons();
}
// 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);
}
}
// Chase a dot down the strip
// good for testing purposes
void colorChase(uint32_t c, uint8_t wait) {
int i;
for (i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, 0); // turn all pixels off
}
for (i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c); // set one pixel
strip.show(); // refresh strip display
delay(wait); // hold image for a moment
strip.setPixelColor(i, 0); // erase pixel (but don't refresh yet)
}
strip.show(); // for last erased pixel
}
// An "ordered dither" fills every pixel in a sequence that looks
// sparkly and almost random, but actually follows a specific order.
void dither(uint32_t c, uint8_t wait) {
// Determine highest bit needed to represent pixel index
int hiBit = 0;
int n = strip.numPixels() - 1;
for(int bit=1; bit < 0x8000; bit <<= 1) {
if(n & bit) hiBit = bit;
}
int bit, reverse;
for(int i=0; i<(hiBit << 1); i++) {
// Reverse the bits in i to create ordered dither:
reverse = 0;
for(bit=1; bit <= hiBit; bit <<= 1) {
reverse <<= 1;
if(i & bit) reverse |= 1;
}
strip.setPixelColor(reverse, c);
strip.show();
delay(wait);
}
delay(250); // Hold image for 1/4 sec
}
// "Larson scanner" = Cylon/KITT bouncing light effect
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
int i, j, pos, dir;
pos = 0;
dir = 1;
for(i=0; i<((strip.numPixels()-1) * 8); 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;
}
}
}
// Sine wave effect
#define PI 3.14159265
void wave(uint32_t c, int cycles, uint8_t wait) {
float y;
byte r, g, b, r2, g2, b2;
// Need to decompose color into its r, g, b elements
g = (c >> 16) & 0x7f;
r = (c >> 8) & 0x7f;
b = c & 0x7f;
for(int x=0; x<(strip.numPixels()*5); x++)
{
for(int i=0; i<strip.numPixels(); i++) {
y = sin(PI * (float)cycles * (float)(x + i) / (float)strip.numPixels());
if(y >= 0.0) {
// Peaks of sine wave are white
y = 1.0 - y; // Translate Y to 0.0 (top) to 1.0 (center)
r2 = 127 - (byte)((float)(127 - r) * y);
g2 = 127 - (byte)((float)(127 - g) * y);
b2 = 127 - (byte)((float)(127 - b) * y);
} else {
// Troughs of sine wave are black
y += 1.0; // Translate Y to 0.0 (bottom) to 1.0 (center)
r2 = (byte)((float)r * y);
g2 = (byte)((float)g * y);
b2 = (byte)((float)b * y);
}
strip.setPixelColor(i, r2, g2, b2);
}
strip.show();
delay(wait);
}
}
/* Helper functions */
//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g - b - back to r
uint32_t Wheel(uint16_t WheelPos)
{
byte r, g, b;
switch(WheelPos / 128)
{
case 0:
r = 127 - WheelPos % 128; // red down
g = WheelPos % 128; // green up
b = 0; // blue off
break;
case 1:
g = 127 - WheelPos % 128; // green down
b = WheelPos % 128; // blue up
r = 0; // red off
break;
case 2:
b = 127 - WheelPos % 128; // blue down
r = WheelPos % 128; // red up
g = 0; // green off
break;
}
return(strip.Color(r,g,b));
}
uint32_t GetColor(int c)
{
switch(c) {
case 0:
return strip.Color(127,0,0);
case 1:
return strip.Color(0,0,127);
case 2:
return strip.Color(0,127,0);
case 3:
return strip.Color(127,31,0);
case 4:
return strip.Color(127,127,0);
case 5:
return strip.Color(0,127,127);
case 6:
return strip.Color(127,0,127);
case 7:
return strip.Color(127,127,127);
default:
return strip.Color(0,0,0);
}
}
You can’t perform that action at this time.