Springe zum Hauptinhalt
t.animal
Anagraphein!
t.animal
Anagraphein!

kerzen.ino (Source)

#include "SoftPWM.h"
int pulseMin = 1; // Minimum number of pulses in each set
int pulseMax = 5; // Maximum number of pulses in each set
int brightMin = 128; // Baseline LED brightness. Cannot exceed 128.
int minDelay = 3000; // Minimum delay between pulse sets (ms)
int maxDelay = 8000; // Maximum delay between pulse sets (ms)
int minPulseSpeed = 3; // Minimum dimming speed for pulses (lower is faster)
int maxPulseSpeed = 5; // Maximum dimming speed for pulses (lower is faster)
int minPulseGap = 10; // Minimum delay between two pulses (ms)
int maxPulseGap = 15; // Maximum delay between two pulses (ms)
const int numberOfCandles = 14;
//#define DEBUG
class Candle {
private:
    int pin;
    unsigned long nextActionTimestamp;
    int pulsesLeftInCurrentFlicker;
    
    int brightnessOfCurrentPulse;
    int currentBrightness;
    int currentPulseSpeed;
    int currentPulseDuration;
    Candle* adjacentCandles[numberOfCandles];
    bool triggerAdjacentFlicker = false;
public:
    Candle() : Candle(0){};
    Candle(int pin) : pin(pin) {
      for(int i=0; i<numberOfCandles; i++) {
        adjacentCandles[i] = NULL;
      }
      scheduleNextFlicker();
    }
    void addAdjacentCandle(Candle* otherCandle){
      for(int i=0; i<numberOfCandles; i++) {
        if(adjacentCandles[i] == NULL){
          adjacentCandles[i] = otherCandle;
          return;
        }
      }
    }
    void adjacentFlicker() {
      scheduleNextFlicker();
      nextActionTimestamp = millis();
      triggerAdjacentFlicker = false;
    }
    void execute() {
        if(nextActionTimestamp > millis()){
            return;
        }
        if(triggerAdjacentFlicker) {
          for(int i=0; i<numberOfCandles; i++) {
            if(adjacentCandles[i] != NULL){
              adjacentCandles[i]->adjacentFlicker();
            }
          }
          triggerAdjacentFlicker = false;
        }
        if(pulsesLeftInCurrentFlicker == 0) {
            scheduleNextFlicker();
            return;
        }
        if(currentBrightness != brightnessOfCurrentPulse) {
            brightnessStep();
            waitFor(currentPulseSpeed);
            return;
        }
        if(currentBrightness == brightMin){
            pulsesLeftInCurrentFlicker--;
            waitFor(currentPulseDuration);
            determineSettingsOfNextPulse();
        } else {
            brightnessOfCurrentPulse = brightMin;
        }
    }
private:
    void scheduleNextFlicker() {
        pulsesLeftInCurrentFlicker = random(pulseMin, pulseMax);
        determineSettingsOfNextPulse();
        triggerAdjacentFlicker = true;
        waitFor(random(minDelay, maxDelay));
    }
    void determineSettingsOfNextPulse() {
        currentPulseSpeed = random(minPulseSpeed, maxPulseSpeed);
        currentPulseDuration = random(minPulseGap, maxPulseGap);
        brightnessOfCurrentPulse = 224 - random(96);
    }
    void waitFor(int milliseconds){
        nextActionTimestamp = millis() + milliseconds;
    }
    void brightnessStep() {
        if(currentBrightness < brightnessOfCurrentPulse) {
            currentBrightness++;
        } else {
            currentBrightness--;
        }
        SoftPWMSet(pin, currentBrightness);
    }
};
Candle candles[numberOfCandles];
void setup()
{
    #ifdef DEBUG  
      Serial.begin(115200);
      Serial.println("started");
    #endif
    randomSeed(analogRead(A0));
    SoftPWMBegin();
    for (byte i = 0; i < numberOfCandles; i++) {
        candles[i] = Candle(i);
    }
    Candle *buerger = candles + 6;
    Candle *bild = candles + 3;
    Candle *erker = candles + 4;
    Candle *schmied = candles + 7;
    Candle *bauern = candles + 5;
    Candle *spitzgiebel = candles + 9;
    Candle *gasthaus = candles + 12;
    Candle *kapelle = candles + 11;
    Candle *rathaus = candles + 10;
    buerger->addAdjacentCandle(bild);
    buerger->addAdjacentCandle(bauern);
    buerger->addAdjacentCandle(erker);
    bild->addAdjacentCandle(buerger);
    bild->addAdjacentCandle(erker);
    erker->addAdjacentCandle(bild);
    erker->addAdjacentCandle(buerger);
    erker->addAdjacentCandle(schmied);
    spitzgiebel->addAdjacentCandle(gasthaus);
    gasthaus->addAdjacentCandle(spitzgiebel);
    gasthaus->addAdjacentCandle(kapelle);
    gasthaus->addAdjacentCandle(rathaus);
    kapelle->addAdjacentCandle(gasthaus);
    kapelle->addAdjacentCandle(rathaus);
    rathaus->addAdjacentCandle(kapelle);
    rathaus->addAdjacentCandle(gasthaus);
}
void loop()
{
    for (byte i = 0; i  < numberOfCandles; i++) {
        candles[i].execute();
    }
}