Re: noční osvětlení schodů Arduino UNO
Napsal: 13 led 2019, 18:05
Až pojedu přes Blansko, tak se stavím a zajdem na pivo
České fórum pro všechny nadšence do Arduina a dalších technologií.
https://forum.hwkitchen.cz/
Kód: Vybrat vše
/*
* Description: Motion activated stair lights.
* Author: Dean Montgomery
* Version: 2.5
*
* Date: Feb 17, 2018
*
* 2 PIR sesors at the top and bottom of the stairs.
* WS28012B Addressable RGB lights - 2 LEDs on each stair - This spread out the strip of 30 and left 2-pairs for spare bulbs.
* My Arduino is at the top of the stairs and the RGB strip is connected at the top.
* This will cycle through several varitions of stair walkers.
*
* Version 2 is a rewrite to properly handle multi-tasking the PIR sensors in parallel with LED updates.
* TODO: Do some code cleanup, variable naming etc.
*
*/
#include "FastLED.h"
//#include <avr/eeprom.h>
#define NUM_LEDS 17
#define LEDS_PER_STAIR 1 // Number of Leds per stair. Not yet currenlty changable - just noteable
#define BRIGHTNESS 120 // 0...255 ( used in fade7 )
#define PIN_LED 3 // LED Data pin
#define PIN_PIR_DOWN 5 // PIR Downstairs Pin
#define PIN_PIR_UP 7 // PIR Upstairs Pin
#define GO_UP -1 // Direction control - Arduino at top of stairs
#define GO_DOWN 1 // Direction control - Arduino at top of stairs
uint8_t gHue = 0; // track color shifts.
int16_t gStair = 0; // track curent stair.
int16_t gStairLeds = 0; // tracking lights per stair.
uint8_t gBright = 0; // track brightness
uint16_t gUpDown[NUM_LEDS]; // directional array to walk/loop up or down stairs.
int8_t gupDownDir = 1; // direction of animation up or down
CRGB leds[NUM_LEDS]; // setup leds object to access the string
CRGBPalette16 gPalette; // some favorite and random colors for display.
CRGBPalette16 fade6 = (CRGB( BRIGHTNESS, 0, 0), CRGB(BRIGHTNESS,BRIGHTNESS,0), CRGB(0,BRIGHTNESS,0),
CRGB(0,BRIGHTNESS,BRIGHTNESS), CRGB(0,0,BRIGHTNESS), CRGB(BRIGHTNESS, 0, BRIGHTNESS),
CRGB( BRIGHTNESS, 0, 0));
CRGBPalette16 z;
int8_t gLastPalette = 15; // track last chosen palette.
unsigned long currentMillis = millis(); // define here so it does not redefine in the loop.
long previousMillis = 0;
long previousOffMillis = 0; // countdown power off timer
long offInterval = 30000; // 1000mills * 30sec
long effectInterval = 40;
enum Effects { effectWalk, effectFlicker, effectFade6 };
Effects effect = effectWalk;
enum WalkEffects { sparkle, pulsate1, pulsate2, flash };
WalkEffects walk_effect = sparkle;
// Stages of the animation. Allows for PIR sensor to re-activation the run stage of the animation.
enum Stage { off, stage_init, stage_grow, stage_init_run, stage_run, stage_init_dim, stage_dim };
Stage stage = off;
int i = 0;
int x = 0;
uint8_t topBrightness = 200; // May preserve LED life if not running at full brightness 255?
uint8_t rnd = 0;
uint8_t r = 0, g = 0, b = 0, h = 0, s = 0, v = 0; // red green blue hue sat val
int16_t stair = 0;
CRGB c1;
CRGB c2;
CRGB trans;
CRGB trans2;
void setup() {
delay (3000); // Power Up 3 second safety delay.
//Serial.begin(115200);
randomSeed(millis());
FastLED.addLeds<WS2812B, PIN_LED, GRB>(leds, NUM_LEDS); // NOTE set LED string type here.
FastLED.setDither( 0 ); // Stops flikering in animations.
pinMode(PIN_PIR_DOWN, INPUT); //5
pinMode(PIN_PIR_UP, INPUT); //7
pinMode(13, OUTPUT);
digitalWrite(PIN_PIR_DOWN, LOW);
digitalWrite(PIN_PIR_UP, LOW);
welcomeRainbow(); // rainbow - give time for PIR sensors to colibrate.
setUpDown(GO_DOWN); // populate the array index used for stair direction.
setPalette(); // setup some favorite & random colors
stage = off;
}
// Main Loop track PIR sensors.
void loop() {
currentMillis = millis();
readSensors();
if(currentMillis - previousMillis > effectInterval) {
previousMillis = currentMillis;
update_effect();
FastLED.show();
}
if((currentMillis - previousOffMillis > offInterval) && stage == stage_run){
stage = stage_init_dim;
i = 0; r = 0; g = 0; b = 0;
}
}
void readSensors(){
if ( digitalRead(PIN_PIR_UP) == HIGH ){ // Walk Down.
previousOffMillis = currentMillis;
if ( stage == off ){
chooseEffects();
stage = stage_init;
setUpDown(GO_DOWN);
} else if ( stage == stage_dim || stage == stage_init_dim ){
stage = stage_init_run;
}
} else if ( digitalRead(PIN_PIR_DOWN) == HIGH ){ // Walk Up.
previousOffMillis = currentMillis;
if ( stage == off ){
chooseEffects();
stage = stage_init;
setUpDown(GO_UP);
} else if ( stage == stage_dim || stage == stage_init_dim){
stage = stage_init_run;
}
}
}
void chooseEffects(){
randomSeed(millis());
r = random8(1, 255);
//effect = effectFlicker; return; // temporarily force effect for debugging: effectWalk, effectFlicker, effectFade6
if ( r >= 0 && r <= 100 ){
effect = effectWalk; // My favorite transition with random effect variations
} else if ( r > 100 && r <= 175 ){
effect = effectFlicker; // Candle with embers.
} else {
effect = effectFade6; // hueshift rainbow.
}
}
void update_effect(){
if ( effect == effectWalk ){
walk();
} else if ( effect == effectFlicker ){
flicker();
} else if ( effect == effectFade6 ){
fade();
}
}
// setup walking gUpDown array in forward: 0,1,2,3... or reverse: ...3,2,1,0
void setUpDown(int8_t upDownDir){
gupDownDir = upDownDir;
uint8_t gStairStart = 0;
if (upDownDir == GO_UP){
for ( gStair = NUM_LEDS -1; gStair >= 0; gStair-- ){
gUpDown[gStair] = gStairStart++;
}
} else {
for ( gStair = 0; gStair <= NUM_LEDS; gStair++ ){
gUpDown[gStair] = gStairStart++;
}
}
}
// Increment to the next color pair in the palette.
void choosePalette(){
if ( gLastPalette >= 15 ) {
gLastPalette = 0;
} else {
gLastPalette+=2;
}
}
// Fill a palette with some colors that my wife picked.
void setPalette(){
/*
* Jenn's colors RGB 0 0 81 BLUE
* 0 100 100 Teal 006464
* 60 100 100 Cool White 3C6464
* 60 10 100 Violet 3C0A64
* 60 0 50 Purple 3C0032
* start white fades to Teal
* violet to purple
* teal to blue
* red to blue
*/
uint8_t r = random8(1, 255); // call it once first.
fill_solid( gPalette, 16, CRGB::Red);
gPalette[0] = CRGB( 60, 100, 100 ); // Jenn cool white
gPalette[1] = CRGB( 0, 90, 90 ); // Jenn teal
gPalette[2] = CRGB( 60, 10, 100 ); // Jenn violet
gPalette[3] = CRGB( 60, 0, 50 ); // Jenn purple
gPalette[4] = CRGB( 0, 0, 81); // Jenn blue
gPalette[5] = CRGB( 100, 0, 0); // Red
gPalette[6] = CRGB( 0, 0, 100); // Blue
gPalette[7] = CRGB( 120, 0, 120);
// Random fill the rest.
for (uint8_t i = 8; i<16; i++){
gPalette[i] = CRGB(random8(3,100), random8(3,100), random8(3,100));
}
}
// Walk the stairs adding random effects.
void walk() {
if ( stage == stage_init ){
topBrightness = 200;
// Pick two colors from the palette.
choosePalette();
c1 = gPalette[gLastPalette];
c2 = gPalette[gLastPalette+1];
// chance of a random palette
if ( random8( 5 ) == 3 ){
c1 = CRGB(random8(3,100),random8(3,100),random8(3,100));
c2 = CRGB(random8(3,100),random8(3,100),random8(3,100));
}
// fix random Black palette.
if ( (int(c1.r) + int(c1.g) + int(c1.b)) < 8 ){
c1 = gPalette[2];
c2 = gPalette[4];
}
trans = CRGB::Black;
trans2 = CRGB::Black;
z[0] = c2;
z[1] = c1;
z[2] = CRGB(random8(2,100),random8(2,100),random8(2,100));
z[3] = c1;
z[4] = c2;
//(r2-r1)/ticks * tick)
gStair=0;
gBright=0;
effectInterval=5;
i = 0;
x = 0;
r = 0;
g = 0;
b = 0;
walk_effect = (WalkEffects)random8( 0, 4 );
stage = stage_grow;
} else if ( stage == stage_grow ) {
if (gBright < 255){
if ( gStair <= (NUM_LEDS - LEDS_PER_STAIR)) {
trans = blend(CRGB::Black,c1,gBright); // fade in next two
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = trans;
}
}
if ( gStair >= LEDS_PER_STAIR ) { // shift last two stairs to the 2nd color.
trans2 = blend(c1,c2,gBright);
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair - (1 + gStairLeds)]] = trans2;
}
}
gBright = qadd8(gBright, 4);
} else {
if ( gStair <= ( NUM_LEDS - LEDS_PER_STAIR ) ) {
gStair+=LEDS_PER_STAIR; //next stair.
} else {
stage = stage_init_run;
gStair = 0;
}
gBright = 0;
}
} else if ( stage == stage_init_run ) {
fill_solid(leds, NUM_LEDS, c2);
x = 0;
stage = stage_run;
} else if ( stage == stage_run ) {
trans2 = c2;
randomEffect(); // waits for timer to run out.
} else if ( stage == stage_init_dim ) {
effectInterval = 3;
for(b=0; b<255; b++) {
trans = blend(trans2,c2,b);
fill_solid(leds, NUM_LEDS, trans);
FastLED.show();
FastLED.delay(8);
}
effectInterval = 8;
gBright = 0;
gStair = 0;
stage = stage_dim;
} else if ( stage == stage_dim ) {
if ( gBright <= topBrightness ) {
if ( gStair <= ( NUM_LEDS - LEDS_PER_STAIR ) ){
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]].fadeToBlackBy( 6 );
}
gBright+=4;
} else {
stage = off;
}
} else {
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = CRGB( 0, 0, 0);
}
gStair += LEDS_PER_STAIR;
gBright = 0;
}
} else {
stage = off;
}
}
// Random effects for the walk() stair function.
void randomEffect(){
if ( walk_effect == sparkle ) {
effectInterval = 8;
fill_solid(leds, NUM_LEDS, c2);
addGlitter(80);
} else if ( walk_effect == pulsate1 ) {
effectInterval = 10;
if ( b < 255 ){
if ( i < 4 ) {
trans2 = blend(z[i],z[i+1],b);
fill_solid(leds, NUM_LEDS, trans2);
b=qadd8(b,1);
} else {
i = 0;
}
} else {
i++;
b=0;
}
} else if ( walk_effect == pulsate2 ) {
effectInterval = 5;
for(gStair=0; gStair < NUM_LEDS; gStair++) {
trans2 = blend(c1,c2,quadwave8(r+=( -20 * gupDownDir )));
leds[gStair] = trans2;
}
gStair = 0;
r = ++g;
} else if ( walk_effect == flash ) {
if ( x == 0 ) {
for(gStair=0; gStair <= (NUM_LEDS - LEDS_PER_STAIR); gStair+=LEDS_PER_STAIR) {
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = CRGB( 100, 100, 100);
}
FastLED.show();
FastLED.delay(1);
}
for(gStair=0; gStair <= (NUM_LEDS - LEDS_PER_STAIR); gStair+=LEDS_PER_STAIR) {
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = c2;
}
FastLED.show();
FastLED.delay(1);
}
x = 1;
gStair=0;
}
}
}
// Sparkle rainbow welcome give delay to calibrate pir sensors. This also indicates if program crashed.
void welcomeRainbow(){
for ( int i = 0; i < 500; i++ ){
rainbowWithGlitter();
FastLED.show();
FastLED.delay(8.3);
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
}
for (int tick=0; tick < 64; tick++){
for ( uint16_t i = 0; i < NUM_LEDS; i++ ){
leds[i].fadeToBlackBy( 64 );
FastLED.show();
FastLED.delay(1);
}
}
}
// built-in FastLED rainbow, plus some random sparkly glitter
void rainbowWithGlitter() {
rainbow();
addGlitter(80);
}
// paint rainbow
void rainbow() {
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, gHue, 7);
}
// Add random glitter
void addGlitter( fract8 chanceOfGlitter) {
if( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB(100,100,100);
}
}
// Candle flicker, blown out, + ember glow
void flicker(){
if ( stage == stage_init ){
i = 0;
rnd = 0;
r = 0; g = 0; b = 0;
stair = 0;
gStair = 0;
x = 0;
gBright = 0;
effectInterval = 27;
stage = stage_grow;
} else if ( stage == stage_grow ){
if ( i <= 10 ){ // number of flicker between steps
if ( gStair <= (NUM_LEDS - LEDS_PER_STAIR)){ // for each step
for ( stair = 0; stair <= gStair; stair += LEDS_PER_STAIR ){ // up to currently lit step.
rnd = random8(1, 4);
if ( rnd == 2 ){
gBright = random8(110,140);
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[stair + gStairLeds]] = CHSV( 60, 200, gBright );
}
}
}
i++;
} else {
stage = stage_init_run;
}
} else {
i = 0;
gStair += LEDS_PER_STAIR;
}
} else if ( stage == stage_init_run ){
stage = stage_run;
} else if ( stage == stage_run ){
for( gStair = 0; gStair <= (NUM_LEDS - LEDS_PER_STAIR); gStair += LEDS_PER_STAIR) {
rnd = random8(1, 4);
if ( rnd == 2 ){
gBright = random8(110,140);
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gStair + gStairLeds] = CHSV( 60, 200, gBright );
}
}
}
} else if ( stage == stage_init_dim ){
// Blow out candles and leave an ember.
for(gStair=0; gStair <= (NUM_LEDS - LEDS_PER_STAIR); gStair += LEDS_PER_STAIR) {
rnd = random8(4, 6);
r = rnd+1;
g = rnd-2;
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = CRGB( r,g,0 );
}
FastLED.show();
FastLED.delay(50);
}
i = 0;
gStair=0;
stage = stage_dim;
} else if ( stage == stage_dim ){
if ( i <= 150 ){
rnd = random8(0, NUM_LEDS);
leds[gUpDown[rnd]].fadeToBlackBy( 3 );
i++;
} else {
fill_solid(leds, NUM_LEDS, CRGB( 0, 0, 0 ));
FastLED.show();
stage = off;
}
} else {
stage = off;
}
}
// Fade6 effect with each led using a hue shift
void fade(){
if ( stage == stage_init ){
gBright = 0;
gStair = 0;
effectInterval = 5;
h = 128;
s = 140;
v = BRIGHTNESS;
r = 0;
g = ( random8() < 120 );
stage = stage_grow;
} else if ( stage == stage_grow ){
if ( gBright<255 ){
if ( gStair <= (NUM_LEDS - LEDS_PER_STAIR) ){
trans = blend(CHSV(h,s,0),CHSV(h,s,v),gBright);
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds ]] = trans;
}
gBright = qadd8(gBright, 1);
} else {
stage = stage_init_run;
gBright=0;
gStair=0;
}
gBright = qadd8(gBright, 2);
} else {
gBright = 0;
gStair += LEDS_PER_STAIR;
}
} else if ( stage == stage_init_run ) {
v = BRIGHTNESS;
effectInterval = 70;
stage = stage_run;
} else if ( stage == stage_run ){
r = h;
for(gStair=0; gStair < NUM_LEDS; gStair++) {
h+=(3*gupDownDir); // left PIR go down
leds[gUpDown[gStair]] = CHSV(h, s, v);
}
h = r + (3*gupDownDir*-1);
} else if ( stage == stage_init_dim ){
effectInterval = 7;
h = h - gStair;
gStair = 0;
stage = stage_dim;
} else if ( stage == stage_dim ){
if ( v > 0 ) {
if ( gStair <= (NUM_LEDS - LEDS_PER_STAIR )){
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = CHSV(gStair + h, s, v);
}
v = qsub8(v, 1);
} else {
stage = off;
}
} else {
for ( gStairLeds=0; gStairLeds < LEDS_PER_STAIR; gStairLeds++ ){
leds[gUpDown[gStair + gStairLeds]] = CRGB( 0, 0, 0);
}
gStair += LEDS_PER_STAIR;
v = BRIGHTNESS;
h+=2;
}
} else {
stage = off;
}
}
Kód: Vybrat vše
#include <Adafruit_NeoPixel.h>
#define vystup_na_pasek 13
int jas = 100; //JAS PASKU
int cas = 200; //POSTUPNE ROZSVICOVANI
int mezi_cas = 2000; //DOBA SVITU
byte pocet_led = 240; // POCET LED
byte pocet_led_schod = 1; //DOPLNENO O POCET LED NA SCHOD
byte nahoru = 5; //PIR 1
byte dolu = 7; //PIR 2
byte R = 255;
byte G = 255;
byte B = 100;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(pocet_led, vystup_na_pasek, NEO_GRB + NEO_KHZ800);
void setup() {
pinMode(nahoru, INPUT_PULLUP);
pinMode(dolu, INPUT_PULLUP);
strip.begin();
strip.show();
Serial.begin(9600);
}
void loop() {
if (digitalRead(dolu) == LOW) { DOLU(); }
if (digitalRead(nahoru) == LOW) { NAHORU(); }
}
void DOLU(){
int s = pocet_led_schod;
for(byte i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, R, G, G);
s--;
if (s==0) { strip.show(); s = pocet_led_schod;}
strip.setBrightness(jas);
delay(cas);
}
delay (mezi_cas);
for(byte i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, 0, 0, 0);
s--;
if (s==0) { strip.show(); s = pocet_led_schod;}
delay(cas);
}
}
void NAHORU(){
int s = pocet_led_schod +1 ;
for(byte i=pocet_led; i>0; i--) {
strip.setPixelColor(i, R, G, B);
s--;
if (s==0) { strip.show(); s = pocet_led_schod;}
strip.setBrightness(jas);
delay(cas);
}
strip.setPixelColor(0, R, G, B);
strip.show();
delay (mezi_cas);
for(byte i=pocet_led; i>0; i--) {
strip.setPixelColor(i, 0, 0, 0);
s--;
if (s==0) { strip.show(); s = pocet_led_schod;}
delay(cas);
}
strip.setPixelColor(0, 0, 0, 0);//Zhasnuti posledniho
strip.show();
}