Dim LED with RTC

Hello,

I started a 132 WS2812B LEDs Wall Clock project and I am in a blocking point. I will have 60 LEDs for seconds, 60 for minutes and 12 for hours. As my question, How can I create something like mapping for seconds to pwm? because I need every second that pass from RTC to dim a LED from 0 to 255 so I can have a nice flow between seconds.

RTC used is DS1307 and RTClib.h as library and works. for now I successfully assigned every LED for seconds.

Google could’t help me :frowning: I am not an advance user of programming (just as a hobby).

Let me know if anyone have ideas. My tough is that I can somehow split a second in 256 values for the PWM like mapping. I made a little chart for a better understanding of my question :smiley:

Best Regards.

As you presumably have at least part of this project working, you should already know that WS2812B LEDs are not controlled via PWM. Perhaps you should rephrase your question.

Indeed, I just wanted to show my needs, maybe the question is wrong. I just wanted some logic to create that mapping. Fading is easly controlled by leds*.setLightBy(PWM). I think you got the point anyway.*
Thanks.

One method may be to maintain a ‚Äúbrightness‚ÄĚ array with 60 elements. Every second, the element corresponding to the current second would be set to maximum brightness while the other elements would be scaled by 1/60th. You‚Äôd then use this array to update the brightness of the corresponding ‚Äúseconds‚ÄĚ LEDs.

You didn’t state which WS2812B library you’re using. The FastLed Library has some features that might be useful to you. First, it allows you to specify LED colors in HSV space. So, that gives you direct access to the brightness while keeping Hue and Saturation constant. It also has several dimming methods and temporal dithering that purport to keep the colors looking correct as the brightness is reduced.

Hi,

Thank you for the reply‚Äôs. I use fastled library for my project. I know it have brightness control with leds*.setLightBy(x) which I played with some sine wave but I couldn‚Äôt synchronize the fade effect with seconds.. I don‚Äôt know how I can ‚Äúsplit‚ÄĚ 1 second, in 256 values for the brightness control. I don‚Äôt know how to use the array function with my project, can you give me an example? Let‚Äôs say we have this 2 variables for seconds: currentSecond and prevSecond.*
Thank you again.

Without seeing your code, I can't provide anything more than the general guidance I already have.

EDIT:
BTW, an array is a data structure, not a "function" - array - Arduino Reference

My code isn’t such a big deal but here you go:

#include "FastLED.h"
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// How many leds in your strip?
#define NUM_LEDS 60


// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
int sec;
int pSec;
int brightness = 0;
int brightness2 = 150;
int fadeAmount = 5;



void setup() {
  while (!Serial);

  Serial.begin(9600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);


}

void loop() {
  DateTime now = rtc.now();

  sec = now.second();
  int currentSecond;

  if (sec == 0) {
    pSec = 59;
  } else {
    pSec = sec - 1;
  }

  Serial.print("OK, Second = ");
  Serial.println(sec, DEC);
  Serial.print("OK, Last Second = ");
  Serial.println(pSec, DEC);
  delay(1);

  leds[sec].setRGB(30, 30, 0);
  leds[pSec].setRGB(30, 30, 0);

  FastLED.show();
  FastLED.clear();
}

For now, two LEDs are on with the ongoing second & previous second.
Sorry for the array misunderstanding, thanks.

First, remember that your loop() function is called hundreds (maybe thousands) of times per seconds. But, the RTC seconds only changes once per second. So, there’s no point in doing any updates or calling FastLed functions every time through loop(). Instead, only do it one time when the seconds value changes. Look at the State Change example in the Arduino IDE.

Once you’ve fixed the timing so that you’re only trying to update the LEDs once per second, try something like this:

 leds[sec].setRGB(30, 30, 0);
  for (uint8_t i = 1; i < NUM_LEDS; i++) {
    sec++;
    if (sec >= NUM_LEDS) {
      sec -= NUM_LEDS;
    }
    leds[sec].fadeLightBy (4);
  }
  FastLED.show();

Lastly, when you‚Äôre ready to clean up your code, consider the appropriateness of the variables you‚Äôre using. A variable representing seconds will only take on values 0-59. So, why are you using an int? Seconds will never be negative or more than 59. A ‚Äėuint8_t‚Äô is much more appropriate. Also, variables like ‚Äėsec‚Äô that are assigned a new value every time loop() executes don‚Äôt need to be global. They can be local.

  while (!Serial);

  Serial.begin(9600);

While Serial is not ready, do nothing. When it is, ask it to get started. It's a good thing you don't have an Arduino with a 32U4 chip where the while() statement does something useful.

  int currentSecond;

This variable is never used.

Thank you for your response gfvalvo,

I just made to receive a value every second with State Change which I believe is a brilliant idea.
But in your example LED’s just goes from 1 to 60 and not every second… my point was to increase brightness within one second from 0 to 255 for each LED at that particular second.

I was trying all day to make it work without success or maybe I just missing your point… Please make it more clear :frowning:

Here is where I currently am with the State Change example working with my RTC :

#include "FastLED.h"
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// How many leds in your strip?
#define NUM_LEDS 60
#define TRAIL    100

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
int sec = 0;
int pSec = 0;
int secState = 0;
int lSecState = 0;


void setup() {
  while (!Serial);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop() {
  DateTime now = rtc.now();
  secState = now.second();

  if (secState != lSecState) {
    if (secState > lSecState) {
      sec++;
      if (sec == 60 && secState > lSecState) {
        sec = 0;
      }
    }
    Serial.print("OK, Sec: ");
    Serial.println(sec);
    delay(20);
  }
  lSecState = secState;


  leds[sec].setRGB(30, 30, 30);
  FastLED.show();
  FastLED.clear();
}

From the title of your post ‚ÄúDim LED with RTC‚ÄĚ and use of the word ‚Äúdim‚ÄĚ elsewhere, I though you wanted the LED for the current second to be brightest and those for the previous seconds to dim over time. That was the sample code that I provided, although you didn‚Äôt implement it as I posted.

The code below is what I thought you wanted. It lights up the current second’s LED the brightest and dims the rest every second. So, the LED from one second ago is a little dimmer than the current second while the LED form 59 seconds ago is the dimmest.

Perhaps you should write a more complete set a requirements describing what you really want.

#include "FastLED.h"
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// How many leds in your strip?
#define NUM_LEDS 60

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5

// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(9600);
  while (!Serial);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop() {
  static uint8_t prevSecValue = 255;
  DateTime now = rtc.now();
  uint8_t currentSecValue = now.second();

  if (currentSecValue != prevSecValue) {
    leds[currentSecValue].setRGB(255, 255, 255);
    uint8_t tempSec = currentSecValue;
    for (uint8_t i = 1; i < NUM_LEDS; i++) {
      tempSec++;
      if (tempSec >= NUM_LEDS) {
        tempSec -= NUM_LEDS;
      }
      leds[tempSec].fadeLightBy (5);
    }
    FastLED.show();
  }
  prevSecValue = currentSecValue;
}

Thank you again for your reply, I made it to work somehow or another… I really appreciate your effort
It’s done my way, not clean at all but it works :))

Maybe from the code above you will understand what I wanted and you’ll help me make it in the right way:

#include "FastLED.h"
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// How many leds in your strip?
#define NUM_LEDS 60
#define TRAIL    100

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
int sec = 0;
int pSec = 0;
int fSec = 0;
int secState = 0;
int lSecState = 0;
int fBrightness = 0;
int pBrightness = 0;

void setup() {
  while (!Serial);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop() {
  DateTime now = rtc.now();
  secState = now.second();

  if (secState != lSecState) {
    if (secState > lSecState) {
      sec++;

      if (sec == 60 && secState > lSecState) {
        sec = 0;
      }
    }

    Serial.print("OK, Sec: ");
    Serial.println(sec);
    Serial.print("Last Sec:");
    Serial.println(lSecState);

    delay(50);
  }

  lSecState = secState;
  pSec = sec - 1;
  fSec = sec + 1;

  leds[sec].setRGB(70, 0, 40);

  fadeOut();
  fadeIn();

}

void fadeOut() {
  for (int i = 0; i < 256; i++) {
    pBrightness = i;
    leds[pSec].setRGB(70, 0, 40);
    leds[pSec].fadeLightBy(pBrightness);
    FastLED.show();
  }
}

void fadeIn() {
  for (int i = 255; i > 0; i--) {
    fBrightness = i;
    leds[fSec].setRGB(70, 0, 40);
    leds[fSec].fadeLightBy(fBrightness);
    FastLED.show();
  }
}

Ok, I will try to explain my needs again.

Only 3 LEDs will be controlled every second at the same time as:

  • First LED that is in front of current second LED and the brightness will go from 0 to 255 then:
  • Second LED that will stay at 255 for the current second;
  • 3rd LED that will go from 255 to 0;

Here I tried to create a chart to show how I need to control the brightness depending on time (seconds):

So every designated seconds LEDs (which are 60) will be controlled 3 seconds/minute like this:

With the current code that I wrote it works but not that well...

I hope I made myself clear...
Thank you for your help.

I can't see you pictures, probably because of where they are hosted, but, to be clear, you want three LEDs active at any point in time. Lets call them ledPrev, ledCurr, and ledNext. If it is 17 seconds after the minute, ledPrv would be 16, ledCurr would be 17, and ledNext would be 18.

You want ledPrev to be fading down, ledCurr to be HIGH, and ledNext to be fading up.

The whole fade cycle, up and down, should complete all 255 steps in one second (or slightly less).

Is that correct?

If so, it seems pretty easy to implement.

Yes, that’s exactly what I need, PaulS! Thank you!
Easy is for you with 92,459 posts only in this forum :)) not for a hobbyist like me :frowning:
I am an enthusiast and the above code is all my mind could think… and took me some several hours…
Attached you can find the charts. Let me know if you want to help me :smiley:

void fadeOut() {
  for (int i = 0; i < 256; i++) {
    pBrightness = i;
    leds[pSec].setRGB(70, 0, 40);
    leds[pSec].fadeLightBy(pBrightness);
    FastLED.show();
  }
}

How long will it take this for loop to iterate all 256 times?

You will, in your final program, understand that loop() already loops. None of your fading will involve any for loops.

There is a time for fading to start. That is when you discover that the second value has changed. Record that time, using millis().

Since you want to fade up or down 255 steps, in 1000 milliseconds, you’ve have to change the brightness value once every 3.92156 milliseconds. Since you don’t have that level of granularity, you need to decide what to do.

One possibility would be to fade up to/down from 250, so you would step up or down once every 4 milliseconds.

Another possibility would be to step up or down more than one step at a time. The human eye will not detect the difference between analogWrite(somePin, 208) and analogWrite(somePin, 209).

Look at the blink without delay example. On each iteration through loop(), see if the second value changed. If so, record when in a suitably named variable (of type unsigned long), such as fadeStart, and reset the brightness value (call it fadeValue) to 0.

Suppose that you decide that steps of 1, to a max of 250, were appropriate. That means a change every 4 milliseconds. If the interval between now (obtained using millis()) and then (the time in fadeStart) is greater than, or equal to, the step interval (4), set the fadeStart value to now, increment fadeValue by 1, and change the values applied to the ledPrev and ledNext pixels. You only need one fade value, because the value to apply to one pin is fadeValue and the value to apply to the other pin is 250 - fadeValue.

You only need to set the color of the three pins when the second value changes. Apply the changes using FastLED.show().

You can change the brightness of both the previous and next LEDs, and then call FastLED.show() to commit both of the changes at once.

Hello,

Thank you very much for the explanations but I still could’t figure it out how to get them in sync… maybe you could tell me what I did wrong to my code…

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
12OK, Sec:  47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
OK, Sec:  48
95
96
97
98
99

Code:

#include "FastLED.h"
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// How many leds in your strip?
#define NUM_LEDS 60
#define TRAIL    100

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5
#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
int sec = 0;
int pSec = 0;
int fSec = 0;
int secState = 0;
int lSecState = 0;
int fBrightness = 0;
int pBrightness = 0;

void setup() {
  while (!Serial);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop() {
  DateTime now = rtc.now();
  secState = now.second();
  unsigned long cMillis = millis();
  unsigned long fadeStart;
  //Serial.println(cMillis);

  if (secState != lSecState) {
    leds[sec].setRGB(70, 0, 70);
    fadeStart = millis();

    sec = secState;
    pSec = sec - 1;
    fSec = sec + 1;

    if (sec == 59) {
      fSec = 0;
    }

    if (sec == 0) {
      pSec = 59;
    }

        Serial.print("OK, Sec:  ");
        Serial.println(sec);

    FastLED.show();
    FastLED.clear();
  }

  lSecState = secState;

  if(cMillis - fadeStart >= 4){
    fadeStart = millis();
    pBrightness++;
    Serial.println(pBrightness);
    if (pBrightness >= 250){
      pBrightness = 0;
    }  
  }
}

Your requirements (as I understood them) were interesting enough that I decided to play with some code for possible application in one of my projects. A couple things to note about the code below:

  • I had a string of APA102 LEDS so that‚Äôs what I used. There‚Äôs a line you can comment out to return to WS2812B.

  • I didn‚Äôt have an RTC so I simulated one with a millis timer. There‚Äôs a line you can comment out to enable the RTC.

  • I found logarithmic fades looked better than linear (IMO). There‚Äôs a line you can comment out to switch to linear fading.

  • I found fading a basic color (R, G, or B) to look better than a blended color. This is because at low brightness levels you can‚Äôt have fractional LED values so the color can shift. Whereas with a single color you can continue to dim it all the way down to zero with integers.

Besides the above macros for LED type, RTC, and fade type, there are several constants you can play with to change the effect. Give it a look.

#define LOG_FADE        // comment out this line for Linear LED fading
#define SIMULATE_RTC    // comment out this line for real RTC
#define USE_APA102      // comment out this line for WS2812B

#include <Arduino.h>
#include "FastLED.h"

#ifndef SIMULATE_RTC
#include <Wire.h>
#include "RTClib.h"
#endif

#ifdef SIMULATE_RTC
const uint32_t simTimer = 1000;
uint32_t secondTimer;
#else
RTC_DS1307 rtc;
#endif

const uint8_t numLeds = 60;

#ifdef USE_APA102
const uint8_t dataPin = 11;
const uint8_t clockPin = 13;
#else
const uint8_t dataPin = 5;
#endif

const uint8_t numValues = 32;   // number of LED brightness levels
const uint8_t hue = 160;        // Pure Blue
const uint8_t sat = 255;
const uint8_t minVal = 1;       // minimum brightness level dimmed to before going off, must be non-zero for logarithmic fading.
const uint8_t maxVal = 255;     // highest pixel brightness
uint8_t values[numValues];      // holds the LED brightness levels

#ifdef SIMULATE_RTC
const uint32_t milliInterval = simTimer / (numValues - 2);
#else
const uint32_t milliInterval = 1000 / (numValues - 2);
#endif

CRGB leds[numLeds];

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Starting");
#ifdef USE_APA102
  LEDS.addLeds<APA102, dataPin, clockPin, BGR, DATA_RATE_MHZ(18)>(leds,
      numLeds);
#else
  FastLED.addLeds<WS2812B, dataPin, RGB>(leds, numLeds);
#endif

  for (uint8_t i = 0; i < numLeds; i++) {
    leds[i] = CHSV(hue, sat, 0);
  }
  FastLED.show();

  values[0] = 0;
#ifdef LOG_FADE
  // Logarithmic Fade
  float v = log10(minVal);
  float delta = (log10(maxVal) - v) / (numValues - 2);
  for (uint8_t i = 1; i < numValues; i++) {
    values[i] = pow(10, v) + 0.5;
    v += delta;
  }
#else
  // Linear Fade
  float v = minVal;
  float delta = (maxVal - v) / (numValues - 2);
  for (uint8_t i = 1; i < numValues; i++) {
    values[i] = v + 0.5;
    v += delta;
  }
#endif

#ifdef SIMULATE_RTC
  secondTimer = millis();
#else
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1)
      ;
  }

  if (!rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
#endif
}

void loop() {
  static uint8_t rtcSeconds = 0;
  static uint8_t previousLed = 0;
  static uint8_t currentLed = 0;
  static uint8_t nextLed = 0;
  static uint8_t lastRtcSeconds = 255;
  static uint8_t stepCount = 0;
  static uint32_t fadeTimer;

#ifdef SIMULATE_RTC
  if (millis() - secondTimer > simTimer) {
    secondTimer += simTimer;
    rtcSeconds++;
    if (rtcSeconds >= 60) {
      rtcSeconds = 0;
    }
  }
#else
  DateTime now = rtc.now();
  rtcSeconds = now.second();
#endif

  if (rtcSeconds != lastRtcSeconds) {
    // extinguish all 3 LEDs in case RTC jumped by more that 1 second
    leds[previousLed] = CHSV(hue, sat, values[0]);
    leds[currentLed] = CHSV(hue, sat, values[0]);
    leds[nextLed] = CHSV(hue, sat, values[0]);

    currentLed = rtcSeconds;
    previousLed = (currentLed > 0) ? currentLed - 1 : numLeds - 1;
    nextLed = (currentLed < numLeds - 1) ? currentLed + 1 : 0;
    leds[previousLed] = CHSV(hue, sat, values[numValues - 2]);
    leds[currentLed] = CHSV(hue, sat, values[numValues - 1]);
    leds[nextLed] = CHSV(hue, sat, values[1]);
    fadeTimer = millis();
    stepCount = 1;
    FastLED.show();
  } else {
    if ((millis() - fadeTimer >= milliInterval) && (stepCount < numValues - 2)) {
      fadeTimer += milliInterval;
      stepCount++;
      leds[previousLed] = CHSV(hue, sat, values[numValues - stepCount - 1]);
      leds[nextLed] = CHSV(hue, sat, values[stepCount]);
      FastLED.show();
    }
  }
  lastRtcSeconds = rtcSeconds;
}

Thank you very much gfvalvo for that complex code :o

I figure it out the sync code that I wanted but I will use yours instead because to be honest I don't know where to place "fadeLightBy()" "setRGB()" and FastLED.show() and I tried all kinds of combinations :stuck_out_tongue_closed_eyes:

if (cMillis - fadeStart >= 4) {
    pBrightness = (cMillis - fadeStart) / 4;
    fBrightness = 250 - pBrightness;
    fadeStart = millis(); 
    leds[pSec].fadeLightBy(pBrightness);
    leds[pSec].fadeLightBy(pBrightness);

Anyway, I learned a lot about millis() and some math also that I did't know is necessary with this and for sure I will be use them in the future.
Thank you both guys!
Cheers!

GabyK:
Thank you very much gfvalvo for that complex code :o

Actually, the main loop() portion of that code is pretty straightforward - classic millis()-based timing. The ‚Äė#ifdef‚Äô options and set up for the fading array only make it look complex. Actually, I just made a small change to it in the post, so copy it now and give it a try.

The next thing to consider is that your code accesses the RTC over the I2C bus on EVERY pass through loop. Because I2C is relatively slow, that makes your code quite inefficient. It might even become intermittently non-responsive to user inputs or other functions you could want your project to perform.

There‚Äôs no need to do that. You should look into using the ‚ÄúTime.h‚ÄĚ library. It keeps track of time using an internal millis()-based counter variable that can be accessed efficiently because no external peripherals are involved. Then, you just need to ‚Äútrue-up‚ÄĚ this internal time with the RTC periodically. You could probably get away with doing that every few hours. But, it certainly isn‚Äôt needed more often than say every 15 minutes. The library comes with examples of doing this.