#define FASTLED_INTERNAL // irritante waarschuwing uitzetten van fastled
#include "FastLED.h" // fastled lib laden
/*
* BEKNOPTE UITLEG NUMMER ZEVEN EN LEDSTRIPS (LEDS2).
* Gebruik wordt gemaakt van WS2812 programmeerbare ledstrips. Dit zijn de 5v versies, 3 pins waarvan 1 datapin.
* De LDR meet constant op intervals 2 waarden en neemt een gemiddelde. Als gemiddelde hoger is dan de LDRtrigger
* dan wordt een dimStatus op 1 gezet: verlichting mag gedimd aan. Het nummer heeft een eigen gemiddelde en zal
* daardoor eerder aanspringen. Als dimStatus=1 dan gaan de PIR metingen er ook toe doen.
*
* De PIR zet PIRstatus HIGH of Low. Zodra het HIGH gaat, gaat de PIRval óók HIGH. Vervolgens gaat het licht x-minuten
* aan. Als de PIRstatus LOW is, dus geen beweging meer, dan verloopt de tijd gewoon en gaat de PIRstatus weer naar LOW,
* en dus licht uit. Gaat de PIR wéér HIGH terwijl die tijd nog niet is verlopen, dan reset de tijd dat het aan moet
* blijven weer naar maximum, etc.
*
* Als het licht gedimd aan is en de PIR gaat HIGH (dus detectie) dan gaat het licht van de basiskleur naar wit en vol
* vermogen (fade up) en blijft aan zolang de PIRstatus HIGH is. Wanneer er geen beweging meer is gaat het naar de
* basiskleur én dimming terug.
*
* Het nummer 7 heeft een eigen strip en controller deel (LEDS1). Deze kunnen eerder aan gaan door de deelwaarde aan te
* passen in :nummerGemiddeld = (metingA+metingB)/1.25;. Afhankelijk van de status van e 3-weg schakelelaar wordt er 1
* van de drie effecten gekozen. Grotere switch of array? Meer effecten :)
*/
// +++ Code voor nummer 7 +++
#define LED_PIN_ZEVEN 7 // led pin voor nummer 7 output
#define NUM_LEDS_ZEVEN 30 // aantal leds in keten
CRGB leds1[NUM_LEDS_ZEVEN]; // fastled library aanpreken en aantal LEDs voor calculatie
int nummerGemiddeld = 0; // is gelijk aan dimStatus maar wordt voor de zeven gebruikt, kan ie eerder aan
int nummerStatus = 0; // hebben we de LDR trigger bereikt?
int effect = 2; // welk effect moet er draaien
int RPin = 5; // rechter pin van on/off/on switch
int LPin = 3; // linker pin van on/off/on switch (middelste is GND)
// +++ Code voor andere strips +++
#define LED_PIN_ACHT 8 // led pin voor andere strips output
#define NUM_LEDS_ACHT 30 // aantal leds in keten
CRGB leds2[NUM_LEDS_ACHT]; // fastled library aanpreken en aantal LEDs voor calculatie
int dimMin = 20; // hoeveel licht wanneer er geen beweging is 30
int dimMax = 250; // maximale verlichting bij beweging 250
int dimval;
int dimStatus = 0; // Uit = 0, gedimd aan is 1, maximaal aan is 2
int Rgb = 100;
int rGb = 20;
int rgB = 143;
// +++ Maar voor alle strips is geldig:
#define COLOR_ORDER RGB // kleurvolgorde GRB
#define CHIPSET NEOPIXEL // WS2812
#define FRAMES_PER_SECOND 60 // controleren op flikkeren....
bool gReverseDirection = false; // looprichting eventueel omdraaien mocht dat nodig zijn...
// +++ sensor +++
int PIRpin = 10; // PIR 10
int PIRstatus = 0 ; // standaard geen detectie, dus uit
int PIRval = 0; // de staat van de pir sensor bewaren
int LDRpin = A0; // LDR A0
int LDRtrigger = 2 ; // wanneer moet LDR iets regelen (is ANDERS dan de dimMin!)
int metingA = 0; // eerste meeting LDR, deze lager dan B zetten ivm opstart loop!!
int metingB = 0; // tweede meeting LDR
int meting = 1; // 1 = A, 2 = B waarde intellen
int gemiddeld = 0; // wat is de huidige gemiddelde waarde
const unsigned long LDRinterval = 5000; // tijd tussen de meting van LDR
const unsigned long PIRinterval = 5000; // tijd dat licht aan moet blijven na beweging detectie
unsigned long resetTime = 0; // interval reset
unsigned long resetPir = 0; // interval reset
int FadeUp = 0; // checken of we een faduup hebben gedaan, doen we maar 1 keer
int Pir = 0; // wat is de status van de Pir? 0 is inactief, 1 is actief
int MaxStatus =0;
void setup() {
// put your setup code here, to run once:
pinMode(PIRpin, INPUT); // PIR input sensor
pinMode(LDRpin, INPUT); // LDR input sensor
pinMode(2, INPUT_PULLUP); //***tjdelijk ush button****
pinMode(3, INPUT_PULLUP); //***tjdelijk ush button****
pinMode(RPin, INPUT_PULLUP); // rechter positie schakelaar
pinMode(LPin, INPUT_PULLUP); // linker positie schakelaar
FastLED.addLeds<CHIPSET,LED_PIN_ZEVEN>(leds1,NUM_LEDS_ZEVEN); // fastled laden voor strip zeven
FastLED.addLeds<CHIPSET,LED_PIN_ACHT>(leds2,NUM_LEDS_ACHT); // fastled laden voor strip acht
// Serial.begin(115200); // kan uit
}
int buttonState = LOW;
void loop() {
//LDR meten
float lightlevel = analogRead(LDRpin); //licht level max is 1023
//Serial.println(lightlevel);
// buttonState = digitalRead(2);
// check if the pushbutton is pressed. If it is, the buttonState is LOW:
/* if (buttonState == LOW) {
dimStatus=0;
}
if (buttonState == HIGH) {
dimStatus=1;
}
*/
//pir button
buttonState = digitalRead(3);
// check if the pushbutton is pressed. If it is, the buttonState is LOW:
if (buttonState == LOW) {
Pir = 0; FadeUp=0;
}
if (buttonState == HIGH) {
Pir = 1;
}
/* LDR SENSOR
* Via millis een interval intellen en wederkerend waardes invullen op metingA en metingB. Het gemiddelde hiervan wordt de trigger
* voor de verlichting. Deze doet continue meten (met interval) zodat het licht aan of uit mag). Deinterval staat nu op 5000ms,
* dus 5 seconden. Maar misschien moet dat 5 minuten o.i.d. worden zodat een donkere wolk of heldere koplampen geen trigger zijn.
*/
unsigned long currentTime = millis();
if (currentTime - resetTime >= LDRinterval && meting == 1) { // 5 intervalseconde meting
metingA=lightlevel;meting=2; // HIER KOMT INPUT WAARDE VAN LDR
resetTime = currentTime; // reset timer
//Serial.print("meting a: ");Serial.println(metingA);
}
if (currentTime - resetTime >= LDRinterval && meting == 2) { // 5 intervalseconde meting
metingB=lightlevel;meting=1; // HIER KOMT INPUT WAARDE VAN LDR
resetTime = currentTime; // reset timer
//Serial.print("meting b: ");Serial.println(metingB);
//Serial.print("Gemiddeld: ");Serial.println(gemiddeld);
}
//gemiddelde nemen
gemiddeld = (metingA+metingB)/2; // gemiddelde uitrekenen en naar int verplaatsen
if(gemiddeld <= LDRtrigger){ dimStatus = 1;}else{dimStatus=0;}
nummerGemiddeld = (metingA+metingB)/1.25; // gemiddelde uitrekenen voor de zeven, gaat eerder aan!
//if(nummerGemiddeld <= LDRtrigger){ nummerStatus = 1;}else{nummerStatus=0;} // ok, hij mag aan
//Serial.println(nummerStatus);
/* PIR SENSOR DIT DEEL ACTIVEREN!
* Wanneer de PIR HIGH gaat dan de status naar HIGH. Ook wanneer de PIR weer LOW is kan de status nog een poos HIGH blijven,
* soort van grace-time. Wanneer er na ntijd geen HIGH status van de PIR is mag de STATUS naar LOW. Maar dit doen we ALLEEN
* wanneer de LDR heeft toegestaan dat het donker genoeg is! Dus dimStatus moet 1 zijn!
*/
if(dimStatus == 1){ // Mag er gemeten worden, LDR regelt dit
if (PIRval == HIGH) { // check if the input is HIGH
Pir = 1;
if (PIRstatus == LOW) {
Serial.println("Motion detected!");
PIRstatus = HIGH;
}
} else {
Pir=0;
if (PIRstatus == HIGH){
// we have just turned of
Serial.println("Motion ended!");
//millis
if (currentTime - resetPir >= PIRinterval) { // wachten tot grace tijd voorbij is
PIRstatus = LOW;
resetPir = currentTime;}
}
}
}
/*
* De aansturing van de langere ledstrips gebeurt hier. De diverse statussen van sensor en modus bepalen wat er gebeurt.
*/
// DimStatus is 0 dus er mag nog niets gedaan worden
if(dimStatus == 0) { AllesUit();}
// nummerStatus is 0 dus ook geen nummer zeven verlichten
//if(nummerStatus == 0) { NummerUit();}
// licht mag gedimt aan -> status is dan 1
if(dimStatus == 1 && FadeUp == 0){ DimStart();}
// er is beweging, dus fade up
if(dimStatus == 1 && FadeUp == 0 && Pir ==1){
StartFadeUp();
}
// na de fadeup aanblijven op max vermogen
if(dimStatus == 1 && FadeUp == 1){
MaxLed();
}
if(dimStatus == 1 && MaxStatus==1 && Pir ==0){
StartFadeDown();
}
/*
* Code voor het huisnummer 7. Hier diverse effecten specificeren maar kunnen ook het huisnummer eerder aan
* laten gaan dan de strip... als we daarvoor een andere waarde gebruiken dan dimStatus. Gebruiken we dezelfde
* dan gaat het nummer gelijktijdig aan met de rest van de strip.
*/
/* De 3-way switch uitlezen. Als links en rechts uit zijn dan moet midden actief worden.
*/
if (!digitalRead(RPin)) //test rechter positie
{
//een effect
}
else if (!digitalRead(LPin)) //test linker positie
{
//een effect
}
else { //een effect
}
if(nummerStatus == 0) { NummerUit();}
if(effect ==1 &&nummerStatus ==1)
{meteorRain(0xff,0xff,0xff,10, 64, true, 30);}
else if
(effect ==2 &&nummerStatus ==1)
{RunningLights(0xff,0xff,0xff, 50);}
else if
(effect ==3 &&nummerStatus ==1)
{Fire(20,70,65);} //cooling / sparking en delay
}
/*
}//einde loop
/*
* Onderstaande loops worden aangeroepen bij de diverse lichtstadia van de lange strip
*
*/
void AllesUit(){
fill_solid( leds2, NUM_LEDS_ACHT, CRGB(0,0,0));FastLED.show();
} // Einde allesuit
void DimStart(){
for(int i = 0; i < NUM_LEDS_ACHT; i++ )
{leds2[i].setRGB(200,10, 50);} // basiskleur
FastLED.setBrightness(dimMin); // dimwaarde
FastLED.show();
} // einde dimstart
void StartFadeUp(){
for( int colorStep=0; colorStep<256; colorStep++ ) {
int r = colorStep; // Redness starts at zero and goes up to full
int b = colorStep; // Blue starts at full and goes down to zero
int g = colorStep; // No green needed to go from blue to red
for(int x = 0; x < NUM_LEDS_ACHT; x++){leds2[x] = CRGB(r,g,b);}
for(int z = dimMin; z < dimMax; z++){FastLED.setBrightness(z);}
delay(5);
FastLED.show();
FadeUp=1; // fadeup is gedaan dus niet herhalen
}
} // einde StartFadeUp
void MaxLed(){
for(int i = 0; i < NUM_LEDS_ACHT; i++ )
{leds2[i].setRGB(250,250,250);}
FastLED.setBrightness(250);
FastLED.show();
MaxStatus=1;
} // einde maxled
void StartFadeDown(){
for(int i = 0; i < NUM_LEDS_ACHT; i++ ) // alle leds
{leds2[i].setRGB(250,0, 0);} // basiskleur
FastLED.setBrightness(dimMin);
FastLED.show();
delay(1000);
MaxStatus=0; // fadedown is gedaan dus niet herhalen
// }
} // einde StartFadeUp
void NummerUit(){
fill_solid( leds1, NUM_LEDS_ZEVEN, CRGB(0,0,0));FastLED.show();
nummerStatus =0;
} // Einde allesuit
/*
* Extra lib voor LED aansturing: NIET VERWIJDEREN!
*/
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
// FastLED.setBrightness(250);
FastLED.show();
#endif
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds1[Pixel].r = red;
leds1[Pixel].g = green;
leds1[Pixel].b = blue;
#endif
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS_ZEVEN; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}
/*
* Onderstaande loops zijn voor het lichteffect in de 'zeven'
*
*/
/*
* effect 1
*/
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
setAll(0,0,0);
//FastLED.setBrightness(250 );
for(int i = 0; i < NUM_LEDS_ZEVEN+NUM_LEDS_ZEVEN; i++) {
// fade brightness all LEDs one step
for(int j=0; j<NUM_LEDS_ZEVEN; j++) {
if( (!meteorRandomDecay) || (random(10)>5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}
// draw meteor
for(int j = 0; j < meteorSize; j++) {
if( ( i-j <NUM_LEDS_ZEVEN) && (i-j>=0) ) {
setPixel(i-j, red, green, blue);
}
}
showStrip();
delay(SpeedDelay);
}
}
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;
oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
strip.setPixelColor(ledNo, r,g,b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds1[ledNo].fadeToBlackBy( fadeValue );
#endif
}
/*
* effect 2
*/
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
int Position=0;
for(int j=0; j<NUM_LEDS_ZEVEN*2; j++)
{
Position++; // = 0; //Position + Rate;
for(int i=0; i<NUM_LEDS_ZEVEN; i++) {
// sine wave, 3 offset waves make a rainbow!
//float level = sin(i+Position) * 127 + 128;
//setPixel(i,level,0,0);
//float level = sin(i+Position) * 127 + 128;
setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
((sin(i+Position) * 127 + 128)/255)*green,
((sin(i+Position) * 127 + 128)/255)*blue);
}
showStrip();
delay(WaveDelay);
}
}
/*
* effect 3 vuurrrrrr
*/
void Fire(int Cooling, int Sparking, int SpeedDelay) {
static byte heat[NUM_LEDS_ZEVEN];
int cooldown;
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS_ZEVEN; i++) {
cooldown = random(0, ((Cooling * 10) / NUM_LEDS_ZEVEN) + 2);
if(cooldown>heat[i]) {
heat[i]=0;
} else {
heat[i]=heat[i]-cooldown;
}
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= NUM_LEDS_ZEVEN - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
}
// Step 3. Randomly ignite new 'sparks' near the bottom
if( random(255) < Sparking ) {
int y = random(7);
heat[y] = heat[y] + random(160,255);
//heat[y] = random(160,255);
}
// Step 4. Convert heat to LED colors
for( int j = 0; j < NUM_LEDS_ZEVEN; j++) {
setPixelHeatColor(j, heat[j] );
}
showStrip();
delay(SpeedDelay);
}
void setPixelHeatColor (int Pixel, byte temperature) {
// Scale 'heat' down from 0-255 to 0-191
byte t192 = round((temperature/255.0)*191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if( t192 > 0x80) { // hottest
setPixel(Pixel, 255, 255, heatramp);
} else if( t192 > 0x40 ) { // middle
setPixel(Pixel, 255, heatramp, 0);
} else { // coolest
setPixel(Pixel, heatramp, 0, 0);
}
}