#include <FastLED.h>
#include <avr/sleep.h>
#define NUM_LEDS 3
#define LED_PIN 12 // doen't use 13 - it's the builtin led pin
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define STARTBUTTON_PIN 2
#define DEMO_TIME 30
#define TIMEBUTTON1_PIN 3
#define TIMEBUTTON1_TIME 120
#define TIMEBUTTON2_PIN 4
#define TIMEBUTTON2_TIME 300
#define TIMEBUTTON3_PIN 5
#define TIMEBUTTON3_TIME 900
#define TIMEBUTTON4_PIN 6
#define TIMEBUTTON4_TIME 1800
#define TIMEBUTTON5_PIN 7
#define TIMEBUTTON5_TIME 2700
#define TIMEBUTTON6_PIN 8
#define TIMEBUTTON6_TIME 3600
CRGB leds[NUM_LEDS];
unsigned long totalTimeSeconds = DEMO_TIME;
CRGB noColor = CRGB::DarkOliveGreen;
// müssten methoden sein, funktionert aber als methoden irgendwie nicht
unsigned long totalTime = totalTimeSeconds * 1000;
CRGB initialColor = CRGB(0,150,0);
unsigned long phase2Time = totalTime / 8 * 5;
CRGB phase2Color = CRGB::DarkOrange;
unsigned long phase3Time = totalTime / 8 * 7;
CRGB phase3Color = CRGB::Red;
const unsigned long maxIdleTime = 300000;
CRGB targetColor = noColor;
unsigned long startTime = 0;
unsigned long idleStartTime = 0;
unsigned long idleLedStart = 0;
int idleLedState = LOW;
bool timerActive = false;
int buttonStateCurrent = HIGH;
int buttonStatePrevious = HIGH;
void setup() {
FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS);
pinMode(STARTBUTTON_PIN, INPUT_PULLUP);
pinMode(TIMEBUTTON1_PIN, INPUT_PULLUP);
pinMode(TIMEBUTTON2_PIN, INPUT_PULLUP);
pinMode(TIMEBUTTON3_PIN, INPUT_PULLUP);
pinMode (LED_BUILTIN, OUTPUT);
}
bool blinkFadeUpDown = false;
const unsigned long blinkFadeDuration = 2500;
const unsigned long totalBlinkDuration = 10 * 1000;
unsigned long blinkFadeStart = 0;
unsigned long blinkStart = 0;
void loop()
{
unsigned long currentMillis = millis();
buttonStateCurrent = debounceDigital(STARTBUTTON_PIN);
// only toggle timer on state change
if (buttonStateCurrent != buttonStatePrevious && buttonStateCurrent == LOW)
{ timerActive = !timerActive; }
buttonStatePrevious = buttonStateCurrent;
if (!timerActive)
{
if (currentMillis - idleLedStart >= 1000)
{
idleLedStart = currentMillis;
if (idleLedState == LOW) idleLedState = HIGH; else idleLedState = LOW;
digitalWrite (LED_BUILTIN, idleLedState);
}
// buttons an 5V hängen und auf write umschalten um LEDs zu betreiben
if (digitalRead(TIMEBUTTON1_PIN) == LOW) totalTimeSeconds = TIMEBUTTON1_TIME;
if (digitalRead(TIMEBUTTON2_PIN) == LOW) totalTimeSeconds = TIMEBUTTON2_TIME;
if (digitalRead(TIMEBUTTON3_PIN) == LOW) totalTimeSeconds = TIMEBUTTON3_TIME;
if (digitalRead(TIMEBUTTON4_PIN) == LOW) totalTimeSeconds = TIMEBUTTON4_TIME;
if (digitalRead(TIMEBUTTON5_PIN) == LOW) totalTimeSeconds = TIMEBUTTON5_TIME;
if (digitalRead(TIMEBUTTON6_PIN) == LOW) totalTimeSeconds = TIMEBUTTON6_TIME;
if (idleStartTime == 0) idleStartTime = currentMillis;
if (currentMillis - idleStartTime > maxIdleTime) goToSleep();
targetColor = noColor;
setAllLEDs(targetColor);
FastLED.show();
startTime = 0;
return;
}
digitalWrite (LED_BUILTIN, LOW);
idleStartTime = 0;
if (startTime == 0) startTime = currentMillis;
// timer wird noch nicht beendet
if (blinkStart > 0 && currentMillis - blinkStart > totalBlinkDuration) timerActive = false;
if (currentMillis - startTime > totalTime) // blink
{
if (blinkStart == 0) blinkStart = currentMillis;
if (blinkFadeUpDown)
{ targetColor = phase3Color; }
else
{ targetColor = noColor; }
fadeAllLEDs(targetColor, 5);
if (blinkFadeStart == 0) blinkFadeStart = currentMillis;
if (currentMillis - blinkFadeStart > blinkFadeDuration)
{
blinkFadeStart = 0;
blinkFadeUpDown = !blinkFadeUpDown;
}
}
else if(currentMillis - startTime > phase3Time) // fade to red
{
targetColor = phase3Color;
fadeAllLEDs(targetColor);
}
else if(currentMillis - startTime > phase2Time) // fade to orange
{
targetColor = phase2Color;
fadeAllLEDs(targetColor);
}
else // show green
{
targetColor = initialColor;
setAllLEDs(targetColor);
}
FastLED.delay(25);
}
void goToSleep()
{
digitalWrite (LED_BUILTIN, LOW);
delay(1000);
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
}
unsigned long lastDebounceTime;
int debounceDelay = 50;
int debounceLast = HIGH;
int debounceCurrent = HIGH;
int debounceDigital(int digitalPin)
{
int reading = digitalRead(digitalPin);
if (reading != debounceLast) lastDebounceTime = millis();
if ((millis() - lastDebounceTime) > debounceDelay)
if (reading != debounceCurrent)
debounceCurrent = reading;
debounceLast = reading;
return debounceCurrent;
}
// Quick color change for all LEDs
void setAllLEDs(CRGB color) { for(uint16_t i = 0; i < NUM_LEDS; i++) leds[i] = color; }
// Fade all by some amount
void fadeAllLEDs(CRGB color, uint8_t amount) { fadeTowardColor(leds, NUM_LEDS, color, amount);}
// Fade all slowly
void fadeAllLEDs(CRGB color) { fadeAllLEDs(color, 1); }
// Helper function that blends one uint8_t toward another by a given amount
void nblendU8TowardU8( uint8_t& cur, const uint8_t target, uint8_t amount)
{
if( cur == target) return;
if( cur < target ) {
uint8_t delta = target - cur;
delta = scale8_video( delta, amount);
cur += delta;
} else {
uint8_t delta = cur - target;
delta = scale8_video( delta, amount);
cur -= delta;
}
}
// Blend one CRGB color toward another CRGB color by a given amount.
// Blending is linear, and done in the RGB color space.
// This function modifies 'cur' in place.
CRGB fadeTowardColor( CRGB& cur, const CRGB& target, uint8_t amount)
{
nblendU8TowardU8( cur.red, target.red, amount);
nblendU8TowardU8( cur.green, target.green, amount);
nblendU8TowardU8( cur.blue, target.blue, amount);
return cur;
}
// Fade an entire array of CRGBs toward a given background color by a given amount
// This function modifies the pixel array in place.
void fadeTowardColor( CRGB* L, uint16_t N, const CRGB& bgColor, uint8_t fadeAmount)
{
for( uint16_t i = 0; i < N; i++) {
fadeTowardColor( L[i], bgColor, fadeAmount);
}
}