Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* candle for Adafruit NeoPixel
- 1 pixel version
- by Tim Bartlett, December 2013
- Version for FastLED and removed instances of delay()
- Adapted by Rob Hilken, February 2016
- */
- // current settings for 3.5v Teensy 3.1
- #include <FastLED.h>
- #define LED_PIN 2
- #define NUM_LEDS 1
- #define BRIGHTNESS 100 // set at 25 to run powersaving
- struct CRGB leds[NUM_LEDS];
- unsigned long currentMillis;
- // Candle animation randomiser and status monitor
- byte candleAnimStatus[NUM_LEDS]; // 1: On, 2: Burn, 3: Flicker, 4: Flutter
- byte randomAnimNumber; // to store random animation number from 1-4
- unsigned long candleAnimOnTimes[NUM_LEDS]; // millis() at switching on LED
- int candleAnimLength; // random between 1000 and 10000 milliseconds
- // Storing the RGB Values of the LED
- byte ledRedValue[NUM_LEDS];
- byte ledGreenValue[NUM_LEDS];
- byte ledBlueValue[NUM_LEDS];
- // color variables: mix RGB (0-255) for desired yellow
- byte redPx = 255;
- byte grnHigh = 100; //110-120 for 5v, 135 for 3.3v
- byte bluePx = 10; //10 for 5v, 15 for 3.3v
- // animation time variables, with recommendations
- byte burnDepth = 14; //10 for 5v, 14 for 3.3v -- how much green dips below grnHigh for normal burn -
- byte flutterDepth = 30; //25 for 5v, 30 for 3.3v -- maximum dip for flutter
- byte cycleTime = 120; //120 -- duration of one dip in milliseconds
- // pay no attention to that man behind the curtain
- byte fDelay;
- // byte flickerDepth;
- byte burnDelay;
- byte burnLow;
- byte flickDelay;
- byte flickLow;
- byte flutDelay;
- byte flutLow;
- // declare functions because of bug
- // https://github.com/FastLED/FastLED/issues/234
- bool flutter(byte f, byte n);
- bool flicker(byte f, byte n);
- bool burn(byte f, byte n);
- void on(byte n);
- bool fire(byte grnLow, byte animLed);
- bool doDelay(unsigned long duration);
- void candleAnimation(byte animateCandleNumber);
- void setup() {
- FastLED.addLeds<WS2811, LED_PIN, RGB>(leds, NUM_LEDS);
- FastLED.setBrightness( BRIGHTNESS );
- randomSeed(analogRead(0));
- byte flickerDepth = (burnDepth + flutterDepth) / 2.4;
- burnLow = grnHigh - burnDepth;
- burnDelay = (cycleTime / 2) / burnDepth;
- flickLow = grnHigh - flickerDepth;
- flickDelay = (cycleTime / 2) / flickerDepth;
- flutLow = grnHigh - flutterDepth;
- flutDelay = ((cycleTime / 2) / flutterDepth);
- Serial.begin(9600);
- // while the serial stream is not open, do nothing:
- while (!Serial);
- // Print variable values for debugging
- Serial.print("flickerDepth = ");
- Serial.println(flickerDepth);
- Serial.print("burnLow = ");
- Serial.println(burnLow);
- Serial.print("burnDelay = ");
- Serial.println(burnDelay);
- Serial.print("flickLow = ");
- Serial.println(flickLow);
- Serial.print("flickDelay = ");
- Serial.println(flickDelay);
- Serial.print("flutLow = ");
- Serial.println(flutLow);
- Serial.print("flutDelay = ");
- Serial.println(flutDelay);
- }
- void loop() {
- currentMillis = millis();
- candleAnimation(0); // pass ledNumber
- FastLED.show();
- }
- void candleAnimation(byte animateCandleNumber)
- {
- /* each state of the animation calls one of the following animation elements:
- 1. on() = solid yellow - does not need a flicker so does not pass a variable
- 2. burn(onForSeconds) = candle is burning normally, flickering slightly
- 3. flicker(onForSeconds) = candle flickers noticably
- 4. flutter(onForSeconds) = the candle needs air!
- the onForSeconds variable tells how long to play that animation element for and also
- passes down into the elements that require effects
- */
- // candleAnimLength = random(0, 10);
- // randomAnimNumber = random(0, 4);
- // candleAnimStatus[animateCandleNumber] = random(0, 4);
- // initial value 0
- static byte statenumber = 0;
- // allows for onForSecondss of each animation to be changed easily
- byte onForSeconds; // in seconds
- switch (statenumber)
- {
- // state 0: burn for seconds equal to onForSeconds
- case 0:
- // burn
- onForSeconds = 10;
- Serial.println("Case 0: Burn");
- if (burn(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 1;
- }
- break;
- // state 1: flicker for seconds equal to onForSeconds
- case 1:
- // flicker
- onForSeconds = 5;
- Serial.println("Case 1: Flicker");
- if (flicker(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 2;
- }
- break;
- // state 2: burn for seconds equal to onForSeconds
- case 2:
- // burn
- onForSeconds = 8;
- Serial.println("Case 2: Burn");
- if (burn(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 3;
- }
- break;
- // state 3: flutter for seconds equal to onForSeconds
- case 3:
- // flutter
- onForSeconds = 5;
- Serial.println("Case 3: Flutter");
- if (flutter(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 4;
- }
- break;
- // state 4: burn for seconds equal to onForSeconds
- case 4:
- // burn
- onForSeconds = 3;
- Serial.println("Case 4: Burn");
- if (burn(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 5;
- }
- break;
- // state 5: on for seconds equal to onForSeconds
- case 5:
- // on
- onForSeconds = 10;
- Serial.println("Case 5: On");
- on(animateCandleNumber); // does not pass the variable as no effect is required
- // delay
- if (doDelay(onForSeconds * 1000)) // converts to seconds
- {
- // go to next state
- statenumber = 6;
- }
- break;
- // state 6: burn for seconds equal to onForSeconds
- case 6:
- // burn
- onForSeconds = 10;
- Serial.println("Case 6: Burn");
- if (burn(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 7;
- }
- break;
- // state 7: flicker for seconds equal to onForSeconds and loop back
- case 7:
- // flicker
- onForSeconds = 10;
- Serial.println("Case 7: Flicker");
- if (flicker(onForSeconds, animateCandleNumber) == true)
- {
- // go to next state
- statenumber = 0;
- }
- break;
- }
- }
- /*
- For Main Animation States
- non-blocking delay for duration milliseconds
- returns false if delay in progress, else true
- */
- bool doDelay(unsigned long duration)
- {
- // variable to keep track of previous millis
- static unsigned long previousMillis = 0;
- // if delay not started
- if (previousMillis == 0)
- {
- // start delay
- previousMillis = currentMillis;
- }
- // if delay has lapsed
- if (currentMillis - previousMillis >= duration)
- {
- // reset previous millis
- previousMillis = 0;
- // indicate that delay has lapsed
- return true;
- }
- // indicate delay in progress
- return false;
- }
- /*
- For Animation Element Effects
- non-blocking delay for duration milliseconds
- returns false if delay in progress, else true
- */
- // basic fire function - not called in main loop
- bool fire(byte grnLow, byte animLed) {
- // remember if we're dimming (true) or brightening (false)
- static bool fDimming = true;
- // remember value for grnPx
- static int grnPx = grnHigh;
- // remember start time of delay
- static unsigned long previousMillis = 0;
- //Serial.print("Seconds: ");
- //Serial.println(currentMillis / 1000);
- //Serial.print("Green: ");
- //Serial.println(grnPx);
- //Serial.print("fDelay: ");
- //Serial.println(fDelay);
- // if in dimming mode
- if (fDimming == true)
- {
- Serial.println("Dimming");
- // if timing not started yet
- if (previousMillis == 0)
- {
- leds[animLed] = CRGB(redPx, grnPx, bluePx);
- // set start time
- previousMillis = currentMillis;
- }
- // if delay lapsed
- if (currentMillis - previousMillis >= fDelay)
- {
- // decrement grnPx
- grnPx--;
- // reset start time
- previousMillis = 0;
- }
- // if lower limit reached
- if (grnPx <= grnLow)
- {
- // switch to next state
- fDimming = false;
- }
- }
- // if in brightening mode
- else
- {
- Serial.println("Brightening");
- // if timing not started yet
- if (previousMillis == 0)
- {
- leds[animLed] = CRGB(redPx, grnPx, bluePx);
- // set start time
- previousMillis = currentMillis;
- }
- // if delay lapsed
- if (currentMillis - previousMillis >= fDelay)
- {
- // increment grnPx
- grnPx++;
- // reset start time
- previousMillis = 0;
- }
- // if upper limit reached
- if (grnPx >= grnHigh)
- {
- // switch to previous state
- fDimming = true; // This is causing a bug. when commented grnPx continues to rise
- // indicate that we have done one cycle dim and brighten
- Serial.println("This is the original TRUE return point");
- return true; //<-- Returns True once and then only returns false after that
- }
- }
- // indicate function not completed yet
- Serial.println("Fire = false");
- return false;
- }
- // fire animations
- void on(byte n) {
- byte grnPx = grnHigh - 5;
- leds[n] = CRGB(redPx, grnPx, bluePx);
- }
- bool burn(byte f, byte n) {
- byte fRep = f * (1000 / cycleTime);
- fDelay = burnDelay;
- // remember var count; initial value zero
- static byte var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(burnLow, n) == true)
- {
- // increment var
- var++;
- }
- Serial.print("var = ");
- Serial.println(var);
- // if not fRep cycles done
- if (var < fRep)
- {
- // indicate burn (still) in progress
- return false;
- }
- else {
- // reset var
- var = 0;
- // indicate burn completed
- Serial.println("Burn Complete");
- return true;
- }
- }
- bool flicker(byte f, byte n) {
- byte fRep = f * (1000 / cycleTime);
- static byte statenumber = 0;
- static byte var = 0;
- switch (statenumber)
- {
- // state 0: burn once
- case 0:
- fDelay = burnDelay;
- if (fire(burnLow, n) == true)
- {
- // go to next state
- statenumber = 1;
- }
- break;
- // state 1: flicker fRep times
- case 1:
- fDelay = flickDelay;
- // remember var count; initial value zero
- var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(flickLow, n) == true)
- {
- // increment var
- var++;
- }
- // if not fRep cycles done
- if (var < fRep)
- {
- // indicate burn (still) in progress
- return false;
- }
- if (var == fRep)
- {
- // go to next state
- statenumber = 2;
- // reset var
- var = 0;
- }
- break;
- // state 2: burn three times
- case 2:
- fDelay = burnDelay;
- // remember var count; initial value zero
- var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(burnLow, n) == true)
- {
- // increment var
- var++;
- }
- // if not fRep cycles done
- if (var < 3)
- {
- // indicate burn (still) in progress
- return false;
- }
- break;
- }
- // indicate flicker completed
- return true;
- }
- bool flutter(byte f, byte n) {
- byte fRep = f * (1000 / cycleTime);
- static byte statenumber = 0;
- static byte var = 0;
- switch (statenumber)
- {
- // state 0: burn once
- case 0:
- fDelay = burnDelay;
- if (fire(burnLow, n) == true)
- {
- // go to next state
- statenumber = 1;
- }
- break;
- // state 1: flicker once
- case 1:
- fDelay = flickDelay;
- if (fire(flickLow, n) == true)
- {
- // go to next state
- statenumber = 2;
- }
- break;
- // state 2 flutter fRep times
- case 2:
- fDelay = flutDelay;
- // remember var count; initial value zero
- var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(flutLow, n) == true)
- {
- // increment var
- var++;
- }
- // if not fRep cycles done
- if (var < fRep)
- {
- // indicate burn (still) in progress
- return false;
- }
- if (var == fRep)
- {
- // go to next state
- statenumber = 3;
- // reset var
- var = 0;
- }
- break;
- // state 3: flicker two times
- case 3:
- fDelay = flickDelay;
- // remember var count; initial value zero
- var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(flickLow, n) == true)
- {
- // increment var
- var++;
- }
- // if not fRep cycles done
- if (var < 2)
- {
- // indicate burn (still) in progress
- return false;
- }
- if (var == 2)
- {
- // go to next state
- statenumber = 4;
- // reset var
- var = 0;
- }
- break;
- // state 4: burn two times
- case 4:
- fDelay = burnDelay;
- // remember var count; initial value zero
- var = 0;
- // call fire; if the result is true, a cycle has been completed
- if (fire(burnLow, n) == true)
- {
- // increment var
- var++;
- }
- // if not fRep cycles done
- if (var < 2)
- {
- // indicate burn (still) in progress
- return false;
- }
- break;
- }
- // indicate flutter completed
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment