Created
February 17, 2019 19:58
-
-
Save nbergont/0ae15c1ffc83781352e797e8dd695d28 to your computer and use it in GitHub Desktop.
Stair leds animation
This file contains hidden or 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
#include <FastLED.h> | |
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) | |
#warning "Requires FastLED 3.1 or later; check github for latest code." | |
#endif | |
#define NUM_LEDS 130 | |
#define DATA_PIN 3 | |
#define BRIGHTNESS 200 | |
#define FRAMES_PER_SECOND 60 | |
#define DETECT_TOP 4 | |
#define DETECT_DOWN 5 | |
#define SWITCH_PIN 6 | |
#define FADE_DURATION 2500 //2.5s | |
#define LIGHT_DURATION 4000 //4s | |
#define FADE_LEDS 50 | |
#define FADE_COEF ((NUM_LEDS*2)/FADE_LEDS) | |
#define FADE_MAX (NUM_LEDS*FADE_COEF+255) | |
typedef uint8_t (*fadeFunc)(int, int, uint8_t); | |
// Define the array of leds | |
CRGB leds[NUM_LEDS]; | |
enum{ | |
WAIT_INPUT, | |
FADE_ON, | |
LIGHT_ON, | |
FADE_OFF | |
} state; | |
typedef enum{ | |
TOP2DOWN, | |
DOWN2TOP, | |
NONE | |
} edir; | |
unsigned long startTime = 0; | |
CRGBPalette16 palette; | |
uint8_t index = 0; | |
edir current_dir = NONE; //Current direction | |
void setup() { | |
delay(500); //Boot delay | |
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); | |
FastLED.setBrightness(BRIGHTNESS); | |
//FastLED.setTemperature(HighNoonSun); // Candle Tungsten40W Tungsten100W Halogen CarbonArc HighNoonSun DirectSunlight OvercastSky ClearBlueSky StandardFluorescent | |
startTime = millis(); | |
state = WAIT_INPUT; | |
//Test pattern | |
fill_solid(leds, NUM_LEDS, CRGB::White); | |
FastLED.show(); | |
FastLED.delay(4000); | |
fill_solid(leds, NUM_LEDS, CRGB::Black); | |
FastLED.show(); | |
} | |
void loop() { | |
unsigned long elapsedTime = millis() - startTime; | |
switch(state) | |
{ | |
case WAIT_INPUT: | |
//Dectect PIR | |
current_dir = detectPIR(); | |
if(current_dir != NONE) | |
{ | |
startTime = millis(); | |
state = FADE_ON; | |
randPalette(); | |
} | |
break; | |
case FADE_ON: | |
if(elapsedTime > FADE_DURATION) | |
{ | |
startTime = millis(); | |
state = LIGHT_ON; | |
} | |
else | |
{ | |
computeLeds(); | |
if(current_dir == TOP2DOWN) | |
fadeOn(elapsedTime, fadeOnLeft); | |
else //DOWN2TOP | |
fadeOn(elapsedTime, fadeOnRight); | |
} | |
break; | |
case LIGHT_ON: | |
if(elapsedTime > LIGHT_DURATION) | |
{ | |
startTime = millis(); | |
state = FADE_OFF; | |
} | |
else | |
{ | |
computeLeds(); | |
if(detectPIR() != NONE) //Reset timer while detection | |
startTime = millis(); | |
} | |
break; | |
case FADE_OFF: //Fade Off | |
if(elapsedTime > FADE_DURATION) | |
{ | |
startTime = millis(); | |
state = WAIT_INPUT; | |
fill_solid(leds, NUM_LEDS, CRGB::Black); | |
FastLED.show(); | |
} | |
else | |
{ | |
computeLeds(); | |
if(current_dir == TOP2DOWN) | |
fadeOff(elapsedTime, fadeOffLeft); | |
else //DOWN2TOP | |
fadeOff(elapsedTime, fadeOffRight); | |
} | |
break; | |
} | |
//Show leds | |
if(state != WAIT_INPUT) | |
{ | |
FastLED.show(); | |
FastLED.delay(1000/FRAMES_PER_SECOND); | |
} | |
} | |
char detectPIR(){ | |
if(digitalRead(DETECT_TOP) == HIGH) | |
return TOP2DOWN; | |
if(digitalRead(DETECT_DOWN) == HIGH) | |
return DOWN2TOP; | |
return NONE; | |
} | |
DEFINE_GRADIENT_PALETTE( es_autumn_02_gp ) { | |
0, 86, 6, 1, | |
127, 255,255,125, | |
153, 255,255,125, | |
242, 194, 96, 1, | |
255, 194, 96, 1}; | |
DEFINE_GRADIENT_PALETTE( es_autumn_20_gp ) { | |
0, 24, 39, 1, | |
76, 87, 53, 1, | |
140, 208, 71, 3, | |
244, 215,161, 75, | |
255, 215,161, 75}; | |
DEFINE_GRADIENT_PALETTE( es_seadreams_06_gp ) { | |
0, 237,207,197, | |
45, 224,187,174, | |
178, 46,199,190, | |
242, 1, 96,172, | |
255, 1, 96,172}; | |
DEFINE_GRADIENT_PALETTE( es_landscape_61_gp ) { | |
0, 90,199, 1, | |
89, 73,219, 6, | |
127, 34,189, 6, | |
128, 113,221, 75, | |
130, 255,252,255, | |
178, 64,189,255, | |
255, 1,122,255}; | |
DEFINE_GRADIENT_PALETTE( es_landscape_87_gp ) { | |
0, 161,142, 54, | |
63, 171,152,100, | |
96, 146,180,155, | |
127, 123,209,221, | |
255, 1, 75,226}; | |
DEFINE_GRADIENT_PALETTE( es_ocean_breeze_057_gp ) { | |
0, 115, 82, 49, | |
76, 87, 51, 22, | |
79, 249, 71, 9, | |
101, 249,122, 17, | |
140, 247,121, 38, | |
178, 175,125, 71, | |
229, 123,108, 83, | |
255, 83, 97, 83}; | |
DEFINE_GRADIENT_PALETTE( es_ocean_breeze_121_gp ) { | |
0, 206,213,123, | |
51, 135,209,212, | |
89, 35,157,160, | |
127, 5, 84,100, | |
153, 1, 15, 26, | |
155, 110,180,197, | |
255, 1, 79,109}; | |
DEFINE_GRADIENT_PALETTE( Sunset_Yellow_gp ) { | |
0, 10, 62,123, | |
36, 56,130,103, | |
87, 153,225, 85, | |
100, 199,217, 68, | |
107, 255,207, 54, | |
115, 247,152, 57, | |
120, 239,107, 61, | |
128, 247,152, 57, | |
180, 255,207, 54, | |
223, 255,227, 48, | |
255, 255,248, 42}; | |
DEFINE_GRADIENT_PALETTE( Sunset_Wow_gp ) { | |
0, 109, 4, 24, | |
25, 173, 25, 15, | |
51, 255, 67, 8, | |
76, 255, 87, 9, | |
103, 255,111, 10, | |
108, 184, 36, 14, | |
112, 126, 3, 20, | |
117, 179, 21, 14, | |
123, 244, 55, 9, | |
135, 249, 70, 8, | |
152, 255, 86, 8, | |
196, 192, 28, 12, | |
255, 139, 2, 17}; | |
DEFINE_GRADIENT_PALETTE( Lemon_Sky_gp ) { | |
0, 192, 86, 79, | |
48, 144, 77, 68, | |
92, 106, 68, 59, | |
96, 159, 97, 66, | |
124, 229,133, 74, | |
198, 229,187, 72, | |
255, 232,255, 68}; | |
DEFINE_GRADIENT_PALETTE( HighGreyClouds_gp ) { | |
0, 1, 17,135, | |
25, 15, 71,178, | |
65, 58,166,228, | |
85, 112,207,228, | |
90, 190,255,230, | |
120, 126,187,199, | |
178, 78,130,170, | |
216, 64, 96,105, | |
255, 51, 68, 57}; | |
DEFINE_GRADIENT_PALETTE( Colorfull_gp ) { | |
0, 10, 85, 5, | |
25, 29,109, 18, | |
60, 59,138, 42, | |
93, 83, 99, 52, | |
106, 110, 66, 64, | |
109, 123, 49, 65, | |
113, 139, 35, 66, | |
116, 192,117, 98, | |
124, 255,255,137, | |
168, 100,180,155, | |
255, 22,121,174}; | |
void randPalette(){ | |
static CRGBPalette16 rp[] = {OceanColors_p, CloudColors_p, ForestColors_p, es_autumn_02_gp,es_autumn_20_gp,es_seadreams_06_gp, | |
es_landscape_61_gp,es_landscape_87_gp,es_ocean_breeze_057_gp,es_ocean_breeze_121_gp,Sunset_Yellow_gp, | |
Sunset_Wow_gp,Lemon_Sky_gp,HighGreyClouds_gp,Colorfull_gp}; | |
if(digitalRead(SWITCH_PIN) == HIGH) | |
{ | |
palette = rp[random8(sizeof(rp)/sizeof(CRGBPalette16))]; | |
} | |
else | |
{ | |
//Black & white | |
for(int i=0; i<16; i++) | |
palette[i] = CHSV(255, 0, i%2 ? random8(60, 180) : 255); | |
} | |
} | |
void computeLeds(){ | |
for( uint16_t i = 0; i < NUM_LEDS; i++) { | |
leds[i] = blend( ColorFromPalette(palette, i*2+index), ColorFromPalette(palette, NUM_LEDS - i+index), 127); | |
} | |
EVERY_N_MILLISECONDS(60) { index++; } | |
} | |
void fadeOn(unsigned long elapsedTime, fadeFunc func){ | |
int frame = (FADE_MAX*elapsedTime)/FADE_DURATION; | |
int bright = dim8_raw((255*elapsedTime)/FADE_DURATION); | |
for(int i=0; i<NUM_LEDS; i++) | |
leds[i].nscale8(func(i, frame, bright)); | |
} | |
void fadeOff(unsigned long elapsedTime, fadeFunc func){ | |
int frame = (FADE_MAX*elapsedTime)/FADE_DURATION; | |
int bright = dim8_raw(255 - (255*elapsedTime)/FADE_DURATION); | |
for(int i=0; i<NUM_LEDS; i++) | |
leds[i].nscale8(func(i, frame, bright)); | |
} | |
inline uint8_t fadeOffLeft(int led, int frame, uint8_t bright){ | |
return constrain(led*FADE_COEF - frame + bright, 0, bright); | |
} | |
inline uint8_t fadeOnLeft(int led, int frame, uint8_t bright){ | |
return bright - fadeOffLeft(led, frame, bright); | |
} | |
inline uint8_t fadeOffRight(int led, int frame, uint8_t bright){ | |
return bright - fadeOffLeft(led, FADE_MAX - frame, bright); | |
} | |
inline uint8_t fadeOnRight(int led, int frame, uint8_t bright){ | |
return fadeOffLeft(led, FADE_MAX - frame, bright); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment