Skip to content

Instantly share code, notes, and snippets.

@nbergont
Created February 17, 2019 19:58
Show Gist options
  • Save nbergont/0ae15c1ffc83781352e797e8dd695d28 to your computer and use it in GitHub Desktop.
Save nbergont/0ae15c1ffc83781352e797e8dd695d28 to your computer and use it in GitHub Desktop.
Stair leds animation
#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