How to Fade in Out with specific time using DS3231 and WS2812B

I'm building a project where I would required to fade in and fade out using DS3231 and WS2812B.

Got stuck in below code, Need help. If anyone can support me it will be really a great help.
Im new to arduino programing.

below is the code:
</>

#include <FastLED.h>
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
Time t;
float Celsius = 0;
float Fahrenheit = 0;

#define LED_PIN 6
#define NUM_LEDS 60

CRGB leds[NUM_LEDS];

const int moonlight_HR1 = 0;
const int moonlight_MIN1 = 0;
const int moonlight_HR2 = 6;
const int moonlight_MIN2 = 0;

int fadeAmount = 5;
int brightness = 0;

void setup()
{

Serial.begin(115200);
rtc.begin();

FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}

void loop()
{
t = rtc.getTime();
Serial.println("========================================");
Serial.print(rtc.getDOWStr());
Serial.print(" ");
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
Serial.println(rtc.getTimeStr());
Serial.print("Hardware Temperature: ");
Serial.print(rtc.getTemp());
Serial.println(" C");
delay(1000);

if (t.hour == moonlight_HR1 && t.min == moonlight_MIN1) {
moonlightAnimation();
}
}

void moonlightAnimation(){

for(int i = 0; i < NUM_LEDS; i++ )
{
leds[i].setRGB(0,0,10); // Set Color HERE!!!
leds[i].fadeLightBy(brightness);
}
FastLED.show();
brightness = brightness + fadeAmount;
if(brightness == 0 || brightness == 255)
{
fadeAmount = -fadeAmount ;
}
delay(9);

}

</>

Show us a good schematic of your proposed circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.


Show us your attempt at the sketch.
In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.

Use the </> icon from the ‘reply menu’ to attach the copied sketch.

#include <FastLED.h>
#include <DS3231.h>
DS3231  rtc(SDA, SCL);
Time t;

#define LED_PIN   6
#define NUM_LEDS  10

CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB


const int moon_HR1 = 0;
const int moon_MIN1 = 0;
const int moon_HR2 = 6;
const int moon_MIN2 = 0;



int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;


void setup()
{
  Serial.begin(115200);
  rtc.begin();
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}


void loop()
{
  RTC();

  if (t.hour == moon_HR1 && t.min == moon_MIN1) {  // LED will be turned On given HR and Min.
    moonlightAnimation();
  }

  else {
    NoAnimation();
  }
  FastLED.show();

}


///////////////////////////VOID FUNCTION LOOPS/////////////////////////////////////////////////////////////////////


void RTC() {
  t = rtc.getTime();
  Serial.println("========================================");
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");
  Serial.println(rtc.getTimeStr());

}

void moonlightAnimation() {
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 20); // Set Color HERE!!!
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();
  brightness = brightness + fadeAmount;
  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
  {
    fadeAmount = -fadeAmount ;
  }
  delay(30);
}

void NoAnimation() {
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 0); // Set Color HERE!!!
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();
  brightness = brightness + fadeAmount;
  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
  {
    fadeAmount = -fadeAmount ;
  }
  delay(30);
}


What’s not working ?

if (t.hour == moonlight_HR1 && t.min == moonlight_MIN1)

Suggest you use:

if (t.hour == moonlight_HR1 && t.min == moonlight_MIN1 && t.sec == moonlight_SEC1)

1 Like

But LEDs are not staying on. even after using else if.
Purpose is that the leds will fade in 01 hr and fade out 06 hrs. and then remain off.

#include <FastLED.h>
#include <DS3231.h>
DS3231  rtc(SDA, SCL);
Time t;

#define LED_PIN   6
#define NUM_LEDS  10

CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB


const int moon_HR1  = 11;
const int moon_MIN1 = 25;
const int moon_SEC1 = 0;
const int moon_HR2  = 18;
const int moon_MIN2 = 20;
const int moon_SEC2 = 0;



int fadeAmount = 5;  // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;


void setup()
{
  Serial.begin(115200);
  rtc.begin();
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}


void loop()
{
  RTC();

  if (t.hour == moon_HR1 && t.min == moon_MIN1 && t.sec == moon_SEC1) {  // LED will be turned On given HR and Min.
    moonlightAnimation();
  }

  else if (t.hour == moon_HR2 && t.min == moon_MIN2 && t.sec == moon_SEC2) {
    NoAnimation();
  }
  else {
    NoAnimation();
  }
  FastLED.show();

}


///////////////////////////VOID FUNCTION LOOPS/////////////////////////////////////////////////////////////////////


void RTC() {
  t = rtc.getTime();
  Serial.println("========================================");
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");
  Serial.println(rtc.getTimeStr());

}

void moonlightAnimation() {
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 20); // Set Color HERE!!!
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();
  brightness = brightness + fadeAmount;
  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
  {
    fadeAmount = -fadeAmount ;
  }
  delay(9);
}

void NoAnimation() {
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 0); // Set Color HERE!!!
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();
  brightness = brightness + fadeAmount;
  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
  {
    fadeAmount = -fadeAmount ;
  }
  delay(3000);
}


Please explain exactly what you want to happen ?

// Version  YY/MM/DD    Description
// 1.00     21 10 17    functioning sketch


#include <Wire.h>
#include "RTClib.h"  //https://github.com/adafruit/RTClib  <-----<<<< use this library
#include <FastLED.h>

//***********************************************************************
#define ENABLED             true
#define DISABLED            false

#define LED_PIN              6
#define NUM_LEDS            10

CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB

bool pixelFlag1           = DISABLED;
bool pixelFlag2           = DISABLED;

const byte heartbeatLED   = 13;  //flashes every 500ms to show if code is blocking

byte lastSecond;

int fadeAmount            = 5;
int brightness            = 0;

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
DateTime now;

//TIMER stuff
unsigned long pixelMillis_1;
unsigned long pixelMillis_2;
unsigned long heartbeatMillis;

//***********************************************************************
void setup ()
{
  Serial.begin(9600);

  pinMode(heartbeatLED, OUTPUT);

  //******************************
  rtc.begin();
  //
  //rtc.adjust(DateTime(2021, 10, 17, 22, 34,  0));
  //                    YYYY  MM  DT  HH  MM  SS

  //******************************
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

  //Pixels all OFF
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 0);
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();

} //END of setup()

//***********************************************************************
void loop ()
{
  now = rtc.now();

  //******************************
  //is it time to print the time of day ?
  if (lastSecond != now.second())
  {
    lastSecond = now.second();
    printTime();
  }

  //******************************
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart the timer
    heartbeatMillis = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //******************************
  if (pixelFlag1 == DISABLED && now.hour() == 0 && now.minute() == 17 && now.second() == 0)
  {
    //enable the TIMER
    pixelFlag1 = ENABLED;

    //reset the TIMER
    pixelMillis_1 = millis();
  }

  //******************************
  if (pixelFlag2 == DISABLED && now.hour() == 0 && now.minute() == 18 && now.second() == 0)
  {
    //enable the TIMER
    pixelFlag2 = ENABLED;

    //reset the TIMER
    pixelMillis_2 = millis();
  }

  //******************************
  //if the TIMER is enabled has it expired ?
  if (pixelFlag1 == ENABLED && millis() - pixelMillis_1 >= 100)
  {
    //restart the TIMER
    pixelMillis_1 = millis();

    moonlightAnimation();

    brightness = brightness + fadeAmount;

    if (brightness > 255)
    {
      brightness = 255;
      fadeAmount = -fadeAmount;

      pixelFlag1 = DISABLED;
    }
  }

  //******************************
  //if the TIMER is enabled has it expired ?
  if (pixelFlag2 == ENABLED && millis() - pixelMillis_2 >= 200)
  {
    //restart the TIMER
    pixelMillis_2 = millis();

    NoAnimation();

    brightness = brightness + fadeAmount;

    if (brightness < 0)
    {
      brightness = 0;
      fadeAmount = -fadeAmount;

      pixelFlag2 = DISABLED;
    }
  }

  //******************************
  //other non blocking code goes here
  //******************************

} //END of loop()


//******************************************************************************
void printTime()
{
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  printDigits(now.minute());
  printDigits(now.second());
  Serial.println();

} //END of printTime()

//******************************************************************************
void printDigits(int digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(':');
  if (digits < 10)
  {
    Serial.print('0');
  }
  Serial.print(digits);

} //END of printDigits(int digits)


//******************************************************************************
void moonlightAnimation()
{
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 255); // Set Color HERE!!!
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();

} //END of moonlightAnimation()


//******************************************************************************
void NoAnimation()
{
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 255);
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();

} //END of NoAnimation()

My purpose is that led starts sunlight animation fade in during morning and fade out during evening, also led starts moon light animation fade in during night and fade out during early morning.
This is required for my aquarium project and home alarm project. Where i can set the time based on my wish.
At this moment i started with moon light animation because sunlight animation has lot of gradient and have no idea how to do that.

Thank you alot for supporting and contributing to my project.

Try the sketch in post #6, you may have to install the required new RTC library as pointed out to you.


What exactly is to happen during the sunlight animation fade ?

Include timing information and intensity when you respond ?


What exactly is to happen during the moon light animation ?

Include timing information and intensity when you respond ?

1 Like

Thanks Larry for the code.
I can not see any animation happening to WS2318B leds.

I need this to be independent of the timer irrespective to any animation.

//TIMER stuff
unsigned long pixelMillis_1;
unsigned long pixelMillis_2;
unsigned long heartbeatMillis;

I want to have full control on the time setting of sunrise and moon phases like below.

// a set of sunrise animation will initiate from 8 am RGB will gradually increases PWM = 0 until afternoon animation.
const int Sunlight_HR  = 8;  
const int Sunlight_MIN = 59;
const int Sunlight_SEC = 0;

// a set of afternoon animation will initiate from 12 pm RGB will gradually increases PWM = 200 to 255 with full brightness until Sunset animation.
const int Afternoon_HR  = 11;
const int Afternoon_MIN = 59;
const int Afternoon_SEC = 0;

// a set of sunset animation will initiate from 2 pm RGB will gradually decreases PWM = 255 to 0 with full brightness until Moon light animation .
const int Sunset_HR  = 13;
const int Sunset_MIN = 59;
const int Sunset_SEC = 0;

// a set of moon light animation will initiate from 8 pm B (Blue led) will gradually increases PWM = 0 to 200 with full brightness until midnight animation.
const int Moon_HR  = 19;
const int Moon_MIN = 59;
const int Moon_SEC = 0;

// a set of midnight animation will initiate from 12 am RG (LED) will gradually increases PWM = 0 to 130 and B (LED) decrease PWM = 200 to 130 with 40% of brightness until morning animation.
const int Midnight_HR  = 23;
const int Midnight_MIN = 59;
const int Midnight_SEC = 0;

// a set of Morning animation will initiate from 4 am RGB will gradually increases PWM = 130 to 0  with brightness from 40 % to 0 % until No Animation.
const int Morning_HR  = 3;
const int Morning_MIN = 59;
const int Morning_SEC = 0;

// a set of Noanimation will initiate from 7 am RGB PWM = 0  with brightness  0 % until morning animation.
const int Morning_HR  = 6;
const int Morning_MIN = 59;
const int Morning_SEC = 0;


I am currently working on the colors for those animations where sunrise to dusk animations will have
Red < Orange < yellow < white > greenish yellow > reddish orange > purple> light blue.

and moon phase.
navy blue < blue < light blue <white (low brightness - 40%) > blue > light blue > sunrise.

I am not following your explanation of what is needed.

Please reword.

For example, you may want:
At 8AM the RGB LED is OFF.
Between 8AM to 11:59:59 the LED should increase in intensity from 0 and stop at 255.
NOTE, each fade intensity increment is 5 as per your sketch.
255 / 5 = 51 increments.
8AM to 12PM is 4 hours. (240 minutes)
Therefore 240 / 51 = 4.7 minutes for each change in intensity.

Please word your reply similar to above.

Yes Larry exactly..
From 6-8 am LED should be off.

Sunlight : From 8 am to 11 am LED intensity to be increased from 0 to 255 and remain constant until 2 pm. from 2 - 4 pm intensity to be reduced from 255 to 0.

Moon light: Again at 8 pm to 11 pm only blue led intensity to be increase from 0 - 255 with 40 % brightness and reduces 255-0 from 2 am to 5 am.

This should be quite close to what's needed for the time between 8-12.

The other times are left for you to do; use this example as a starting off point.

// Version  YY/MM/DD    Description
// 1.00     21 10 17    functioning sketch
// 1.01     21 10 22    added 8:00 to 12:00 fade code

#include <Wire.h>
#include "RTClib.h"  //https://github.com/adafruit/RTClib  <-----<<<< use this library
#include <FastLED.h>

//***********************************************************************
#define ENABLED             true
#define DISABLED            false

#define LED_PIN              6
#define NUM_LEDS            10

CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB

bool _8amFlag             = DISABLED;

const byte heartbeatLED   = 13;  //flashes every 500ms to show if code is blocking

byte lastSecond;

int fadeAmount            = 5;
int brightness            = 0;

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
DateTime now;

//TIMER stuff
unsigned long _8amMillis;
unsigned long heartbeatMillis;

//8AM to 12PM is 4 hours
//fadeAmount is 5 and the range of brightness is 0-255
//255 / 5 = 51 separate intensities
//4 hours / 51 = 4.7 minutes between each of the 51 intensities
//4 minutes is 4 * 60 * 1000ul = 240,000ms
//.7 minutes is ~42 seconds = 42 * 1000ul = 42,000ms
const unsigned long _8amInterval  = (4 * 60 * 1000ul) + 42000ul; //ms per intensity interval

//***********************************************************************
void setup ()
{
  Serial.begin(9600);

  pinMode(heartbeatLED, OUTPUT);

  //******************************
  rtc.begin();
  //
  //rtc.adjust(DateTime(2021, 10, 17, 22, 34,  0));
  //                    YYYY  MM  DT  HH  MM  SS

  //******************************
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

  //Pixels all OFF
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(0, 0, 0);
    leds[i].fadeLightBy(brightness);
  }

  FastLED.show();

} //END of setup()

//***********************************************************************
void loop ()
{
  now = rtc.now();

  //******************************
  //is it time to print the time of day ?
  if (lastSecond != now.second())
  {
    lastSecond = now.second();
    printTime();
  }

  //******************************
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart the timer
    heartbeatMillis = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //******************************
  //at 08:00:00 AM
  if (_8amFlag == DISABLED && now.hour() == 8 && now.minute() == 0 && now.second() == 0)
  {
    //enable the TIMER
    _8amFlag = ENABLED;

    //reset the TIMER
    _8amMillis = millis();
  }

  //******************************
  //if this TIMER is enabled has it expired ?
  if (_8amFlag == ENABLED && millis() - _8amMillis >= _8amInterval)
  {
    //restart this TIMER
    _8amMillis = millis();

    Serial.print("Brightness = ");
    Serial.println(brightness);

    _8amAnimation();

    brightness = brightness + fadeAmount;

    if (brightness > 255)
    {
      //we are now at full brightness
      brightness = 255;
      fadeAmount = -fadeAmount;

      //disable this TIMER
      _8amFlag = DISABLED;
    }
  }

  //******************************
  //other non blocking code goes here
  //******************************

} //END of loop()


//******************************************************************************
void printTime()
{
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  printDigits(now.minute());
  printDigits(now.second());
  Serial.println();

} //END of printTime()

//******************************************************************************
void printDigits(int digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(':');
  if (digits < 10)
  {
    Serial.print('0');
  }
  Serial.print(digits);

} //END of printDigits(int digits)


//******************************************************************************
void _8amAnimation()
{
  for (int i = 0; i < NUM_LEDS; i++ )
  {
    leds[i].setRGB(255, 255, 255);     //white
    leds[i].fadeLightBy(255 - brightness);
  }

  FastLED.show();

} //END of _8amAnimation()


//******************************************************************************
1 Like

LED are not getting on from 8 am and no activity, even after changing time in between 8 am - 12 pm

Remember the fade from 0 to 255 will slowly happen over the period of 4 hours, a fade of 5 happening every 4.7 minutes.


For testing, change the following line to 1 second and adjust the trigger time to current time so you can prematurely trigger LED fading up:
const unsigned long _8amInterval = (4 * 60 * 1000ul) + 42000ul; //ms per intensity interval
Change To:
const unsigned long _8amInterval = 1000ul; //ms per intensity interval


Trigger time, change as needed for testing:
//at 08:00:00 AM
if (_8amFlag == DISABLED && now.hour() == 8 && now.minute() == 0 && now.second() == 0)



The code works here just fine.

This is exactly what I was wanting to do, but not for a fish tank, but for my bedroom. :grinning: What circuit are you using?

@Larry may be Im not getting the code correctly. I am still unable to run any animations with the code even after changing the above codes you mentioned.

Im currently working in a breadboard with 5v 2amp power supply for WS2812B, nano & DS3231.
cuircit is preety easy. connect data pin of WS2812B with with 470 resistor nano and GND and VCC with power supply.

1 Like

Does the sketch compile and upload properly into the Arduino ?

Show us a good image of your actual wiring.

Make a schematic of the circuit and show us.

Schematic_WS2812B_SUNRISE_SUNSET_MOONLIGHT_2021-11-05.pdf (38.8 KB)

I attached the rough sketch for reference.

@LarryD Is it necessary to include miles function ? can you please explain that.

Your schematic does not show a GND on the RTC.