Flickering candle with LDR and time out

Hi all, I'm working on a flickering candle with neoled. The goal is to obtain a passable flickering candle effect, turn it on when it gets dark and run it for 3 hours then switch off. It will be in the lounge room in a lovely glass bowl.

I'm quite happy with the effect of the candle and the LDR works well. When the LDR condition is met I would like to run the effect for about three hours and switch off. Then stay off until the next night, a big ask the more I look into it! Here is mmmdyer's simple candle modified code so far:

#include <Adafruit_NeoPixel.h>
#define LED_TYPE   WS2812
#define COLOR_ORDER   GRB
#define NUM_PIXELS 5
#define PIN_NEO_PIXEL 4
#define DELAY_INTERVAL 100  
#define LDR_PIN A1
int LdrValue = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);


void setup() {
 pixels.begin();

}


void loop() {
  LdrValue = analogRead(LDR_PIN);
  
if(LdrValue<100) { 
  //while(delay(60*60)!=0){ 
  
  for (int p = 0; p < NUM_PIXELS; p++) {  
    pixels.clear();


pixels.setBrightness(random(0,200));
    
  int r = 223, g = 176, b = 45;

  //  Flicker, based on our initial RGB values
  int flicker = random(0, 80);
  int r1 = r - flicker;
  int g1 = g - flicker;
  int b1 = b - flicker;
  if (g1 < 0) g1 = 0;
  if (r1 < 0) r1 = 0;
  if (b1 < 0) b1 = 0;

  pixels.setPixelColor(p, r1, g1, b1);

  pixels.show();
   //delay(random(10, 20));
  }
  //}
}else{pixels.clear();
    pixels.show(); }
}

Wrapping the part of your sketch after the LDR < 100 in a three hours timer should be what you need. The changes I made to your sketch are commented. I started by initializing some counters and a state flag. Then I did a read-once of millis(); after LDR < 100 to set a start time for the three hours timer. Then, if the duration between startTime and now is greater than three hours, the pixels are set to zero, otherwise, continue with the flicker... it seems to work in wokwi simulator...

#include <Adafruit_NeoPixel.h>
#define LED_TYPE   WS2812
#define COLOR_ORDER   GRB
#define NUM_PIXELS 5
#define PIN_NEO_PIXEL 4
#define DELAY_INTERVAL 100
#define LDR_PIN A1
int LdrValue = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);

unsigned long starttime, threehours = 3 * 3600000UL; // timers
bool setStartTime = 0; // one-time-reading flag for startTime

void setup() {
  pixels.begin();
}

void loop() {
  LdrValue = analogRead(LDR_PIN);

  if (LdrValue < 100) { // when dark...

    if (setStartTime == 0) { // if startTime has not been set...
      setStartTime = 1; // set flag to not change start time again
      starttime = millis(); // start a timer
    }

    if (millis() - starttime > threehours) { // if > 3 hours...
      for (int i = 0; i < 5; i++) {
        pixels.clear();
        pixels.show();
      }
    } else { // while < 3 hours...

      //while(delay(60*60)!=0){

      for (int p = 0; p < NUM_PIXELS; p++) {
        pixels.clear();


        pixels.setBrightness(random(0, 200));

        int r = 223, g = 176, b = 45;

        //  Flicker, based on our initial RGB values
        int flicker = random(0, 80);
        int r1 = r - flicker;
        int g1 = g - flicker;
        int b1 = b - flicker;
        if (g1 < 0) g1 = 0;
        if (r1 < 0) r1 = 0;
        if (b1 < 0) b1 = 0;

        pixels.setPixelColor(p, r1, g1, b1);
        pixels.show();
      }
    }
  }
}
  • You might want to look into using an RTC.
    DS3231 about $3.00

Thanks LarryD, I'll investigate that device.

Thank you xfpd, I'll research your code and learn how it works. It will expand my knowledge.

The timer is set for three hours... so if you want to watch the timer work, you can change that big number to a smaller one. Change this:

3600000UL; // three hours

to this:

3600; // three point six seconds.

Thanks xfpd I'll run print messages and have a look at it.

| xfpd
October 22 |

  • | - |

shielphi:

learn how it works.

The timer is set for three hours... so if you want to watch the timer work, you can change that big number to a smaller one. Change this:

3600000UL; // three hours

to this:

3600; // three point six seconds.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.