Linear clock does not show all LEDs when starting (WS2811)

Hello everyone,
I am an absolute beginner with little knowledge. I built a linear clock based on the Kassel model.

The circuit is based on an ESP Wroom-32 connected to 14 WS2811, which have the following tasks:
WS2811 #0-2: single-digit seconds (9 LEDs)
WS2811 #3-4: ten-digit seconds (5 LEDs); Output "Blue" of the last WS2811 is not used
WS2811 #5-7: single-digit minutes (9 LEDs)
WS2811 #8-9: ten-digit minutes (5 LEDs); Output "Blue" of the last WS2811 is not used
WS2811 #10-12: single-digit hours (9 LEDs)
WS2811 #13: ten-digit hours (2 LEDs); Output "Blue" of the last WS2811 is not used

I used the FastLED library to control the individual LEDs. To decompose the seconds, minutes and hours into single digits and ten-digits, I used the Modulo (%) operation. The LEDs are activated and deactivated with approx. 40 if > else links. There's probably an easier way, but so far everything works as expected.

If I now disconnect the ESP32 from the power and then reconnect it, some LEDs in almost all areas are not activated immediately (blocks of three LEDs are missing). Only after these are regularly activated by the time they light up again. This can take up to six hours.

What have I already tried?

  • Activate/deactivate all LEDs immediately after start, in setup and in loop
  • Only one FastLED.show command per block
  • Delay when querying the NTP time

I really appreciate your help and know how much time something like this takes.
So thank you very much in advance.

Here is the Arduino sketch:

/*
  Project:  Linearuhr von NTC Zeit Server mit ESP32
  Author:   Michael Todtenbier
  Date:     Created 02.07.2024
  Version:  V1.0
  IDE:      Arduino IDE 1.8.19

  Required libraries (sketch -> include library -> manage libraries)
  -
*/

#include <WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
//#include <Adafruit_NeoPixel.h>
#include <FastLED.h>

#define DATA_PIN  27 // Pin für LED-Streifen
#define NUM_LEDS  14 // Anzahl der WS2811-Chips
// This is an array of leds.  One item for each led in your strip.
CRGB leds[NUM_LEDS];

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200, 60000);

// Wi-Fi Settings
const char *wifi_ssid = "YourSSID";
const char *wifi_password = "YourPassword";
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO    = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";

/*
time_t now;
tm tm;
*/


void setup () {
  Serial.begin(115200);

  // Verbindung zu WiFi herstellen
  delay(10);
  WiFi.begin(wifi_ssid, wifi_password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (++counter > 100) ESP.restart();
    Serial.print(".");
  }
  Serial.println("WiFi connected");

  //FastLED aktivieren
  FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);

  // NTP Client starten
  timeClient.begin();
}

void loop () {

  timeClient.update();

  int hours = timeClient.getHours();
  int minutes = timeClient.getMinutes();
  int seconds = timeClient.getSeconds();

  Serial.printf(" \tUhrzeit: %02d:%02d:%02d \n", hours, minutes, seconds);
               
  //Zehnerstunden
  if (((hours / 10) % 10) > 1) {
     leds[13] = CRGB::Yellow;
     FastLED.show();   
  }
  
  else if (((hours / 10) % 10) > 0) {
     leds[13] = CRGB::Red;
     FastLED.show();
  }
 
  else {
     leds[13] = CRGB::Black;
     FastLED.show();
}
     
  //Einerstunden
  if ((hours % 10) > 8) {
     leds[12] = CRGB::White;
     FastLED.show();
  }

  else if ((hours % 10) > 7) {
     leds[12] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((hours % 10) > 6) {
     leds[12] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((hours % 10) > 5) {
     leds[11] = CRGB::White;
     FastLED.show();
  }
  else if ((hours % 10) > 4) {
     leds[11] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((hours % 10) > 3) {
     leds[11] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((hours % 10) > 2) {
     leds[10] = CRGB::White;
     FastLED.show();
  }

  else if ((hours % 10) > 1) {
     leds[10] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((hours % 10) > 0) {
     leds[10] = CRGB::Red;
     FastLED.show();
  }
   
  else {
     leds[12] = CRGB::Black;
     FastLED.show();
     leds[11] = CRGB::Black;
     FastLED.show();
     leds[10] = CRGB::Black;
     FastLED.show();
}

  //Zehnerminuten
  if (((minutes / 10) % 10) > 4) {
     leds[9] = CRGB::Yellow;
     FastLED.show();
  }
  
  else if (((minutes / 10) % 10) > 3) {
     leds[9] = CRGB::Red;
     FastLED.show();
  }
  
  else if (((minutes / 10) % 10) > 2) {
     leds[8] = CRGB::White;
     FastLED.show();
  }
  
  else if (((minutes / 10) % 10) > 1) {
     leds[8] = CRGB::Yellow;
     FastLED.show();      
  }
  
  else if (((minutes / 10) % 10) > 0) {
     leds[8] = CRGB::Red;
     FastLED.show();
  }
 
  else {
     leds[9] = CRGB::Black;
     FastLED.show();
     leds[8] = CRGB::Black;
     FastLED.show();
}
     
  //Einerminuten
  if ((minutes % 10) > 8) {
     leds[7] = CRGB::White;
     FastLED.show();
  }

  else if ((minutes % 10) > 7) {
     leds[7] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((minutes % 10) > 6) {
     leds[7] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((minutes % 10) > 5) {
     leds[6] = CRGB::White;
     FastLED.show();
  }

  else if ((minutes % 10) > 4) {
     leds[6] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((minutes % 10) > 3) {
     leds[6] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((minutes % 10) > 2) {
     leds[5] = CRGB::White;
     FastLED.show();
  }

  else if ((minutes % 10) > 1) {
     leds[5] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((minutes % 10) > 0) {
     leds[5] = CRGB::Red;
     FastLED.show();
  }
   
  else {
     leds[7] = CRGB::Black;
     FastLED.show();
     leds[6] = CRGB::Black;
     FastLED.show();
     leds[5] = CRGB::Black;
     FastLED.show();

}

  //Zehnersekunden
  if (((seconds / 10) % 10) > 4) {
     leds[4] = CRGB::Yellow;
     FastLED.show();
  }
  
  else if (((seconds / 10) % 10) > 3) {
     leds[4] = CRGB::Red;
     FastLED.show();
  }
  
  else if (((seconds / 10) % 10) > 2) {
     leds[3] = CRGB::White;
     FastLED.show();
  }
  
  else if (((seconds / 10) % 10) > 1) {
     leds[3] = CRGB::Yellow;
     FastLED.show();    
  }
  
  else if (((seconds / 10) % 10) > 0) {
     leds[3] = CRGB::Red;
     FastLED.show();
  }
 
  else {
     leds[3] = CRGB::Black;
     FastLED.show();
     leds[4] = CRGB::Black;
     FastLED.show();
}
     
  //Einersekunden
  if ((seconds % 10) > 8) {
     leds[2] = CRGB::White;
     FastLED.show();
  }

  else if ((seconds % 10) > 7) {
     leds[2] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((seconds % 10) > 6) {
     leds[2] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((seconds % 10) > 5) {
     leds[1] = CRGB::White;
     FastLED.show();
  }

  else if ((seconds % 10) > 4) {
     leds[1] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((seconds % 10) > 3) {
     leds[1] = CRGB::Red;
     FastLED.show();
  }
  
  else if ((seconds % 10) > 2) {
     leds[0] = CRGB::White;
     FastLED.show();
  }

  else if ((seconds % 10) > 1) {
     leds[0] = CRGB::Yellow;
     FastLED.show();
  }

  else if ((seconds % 10) > 0) {
     leds[0] = CRGB::Red;
     FastLED.show();
  }
   
  else {
     leds[2] = CRGB::Black;
     FastLED.show();
     leds[1] = CRGB::Black;
     FastLED.show();
     leds[0] = CRGB::Black;
     FastLED.show();
}
}

Welcome to the forum

If I were you I would put the code that sets the state of all of the LEDs to the current time in a function. That function could then be called whenever you want to display the time, including from setup()

It will do no harm to update the state of all of the LEDs every second

1 Like

are this discrete leds? i mean why not addressable strip?

1 Like

Hi,
thank you very much. That would also be my goal, but unfortunately I don't know what to look for to create such a function. Could you maybe give me a tip?

i don't understand, do you want to use each color of RGB LED as single bit?
like: r g = 2, rgbrgbr=7 ?

Hi,

There are 14 addressable WS2811 chips with 39 connected LEDs. A strip doesn't really help me with this, because the watch will end up being installed in a 1/87 scale model. The watch is then equipped with 117 LEDs of type 0603.

i see, but was hc595 not better?

Yeah, that‘s correct. You can see the functionality in the embedded YouTube video

Add a new function to the sketch. Let's call it displayTime(). In that function put the code that uses the current time to determine which LEDs should be on or off and which colour they should be

Remove all of the code from loop() that controls the LEDs and instead call displayTime() every time that the value of the second changes

You don't even need to call displayTime() from setup() as it will only take one second in loop() before it is called anyway

1 Like

Might take a bit of rewiring to get the colors in the correct order, but it would be a bit simpler code-wise to directly address individual bytes in the LEDs.

As an example, this should set the seconds and 10's of seconds LEDs

  //note - set entire strip to black (0x00) first
  byte seconds_1s = seconds % 10;
  byte seconds_10s = seconds / 10;
  byte* ptr = (byte*)&leds;
  for (byte i = 0; i < seconds_1s; i++){
    *ptr++ = 0xFF;
  }
  ptr = (byte*)&leds + 9; //start of 10's of seconds LEDs
  for (byte i = 0; i < seconds_10s; i++){
    *ptr++ = 0xFF;
  }
  
/*
  Project: Linearuhr von NTC Zeit Server mit ESP32
  Author: Michael Todtenbier
  Date: Created 02.07.2024
  Version: V1.0
  IDE: Arduino IDE 1.8.19

  Required libraries (sketch -> include library -> manage libraries)
  -Grüße aus Flensburg
*/

#include <WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
//#include <Adafruit_NeoPixel.h>
#include <FastLED.h>

#define DATA_PIN 27 // Pin für LED-Streifen
const byte NUM_LEDS = 14; // Anzahl der WS2811-Chips
// This is an array of leds. One item for each led in your strip.
CRGB leds[NUM_LEDS];

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200, 60000);

// Wi-Fi Settings
const char *wifi_ssid = "YourSSID";
const char *wifi_password = "YourPassword";
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";

/*
  time_t now;
  tm tm;
*/

void setup () {
  Serial.begin(115200);

  // Verbindung zu WiFi herstellen
  delay(10);
  WiFi.begin(wifi_ssid, wifi_password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (++counter > 100) ESP.restart();
    Serial.print(".");
  }
  Serial.println("WiFi connected");

  //FastLED aktivieren
  FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);

  // NTP Client starten
  timeClient.begin();
}

void loop () {
  timeClient.update();

  byte hoursH = timeClient.getHours() / 10;
  byte hoursL = timeClient.getHours() % 10;
  byte minutesH = timeClient.getMinutes() / 10;
  byte minutesL = timeClient.getMinutes() % 10;
  byte secondsH = timeClient.getSeconds() / 10;
  byte secondsL = timeClient.getSeconds() % 10;

  Serial.printf(" \tUhrzeit: %02d:%02d:%02d \n", hours, minutes, seconds);
  for (int i = 0; i < NUM_LEDS; i++)leds[i] = CRGB::Black;


  //Zehnerstunden
  if (hoursH > 1) leds[13] = CRGB::Yellow;
  else if (hoursH) leds[13] = CRGB::Red;

  //Einerstunden
  if (hoursL > 8) leds[12] = CRGB::White;
  else if (hoursL > 7) leds[12] = CRGB::Yellow;
  else if (hoursL > 6) leds[12] = CRGB::Red;
  else if (hoursL > 5) leds[11] = CRGB::White;
  else if (hoursL > 4) leds[11] = CRGB::Yellow;
  else if (hoursL > 3) leds[11] = CRGB::Red;
  else if (hoursL > 2) leds[10] = CRGB::White;
  else if (hoursL > 1) leds[10] = CRGB::Yellow;
  else if (hoursL )leds[10] = CRGB::Red;


  //Zehnerminuten
  if ( minutesH > 4) leds[9] = CRGB::Yellow;
  else if ( minutesH > 3) leds[9] = CRGB::Red;
  else if ( minutesH > 2) leds[8] = CRGB::White;
  else if ( minutesH > 1) leds[8] = CRGB::Yellow;
  else if ( minutesH ) leds[8] = CRGB::Red;

  //Einerminuten
  if ( minutesL > 8) leds[7] = CRGB::White;
  else if ( minutesL > 7) leds[7] = CRGB::Yellow;
  else if ( minutesL > 6) leds[7] = CRGB::Red;
  else if ( minutesL > 5) leds[6] = CRGB::White;
  else if ( minutesL > 4) leds[6] = CRGB::Yellow;
  else if ( minutesL > 3) leds[6] = CRGB::Red;
  else if ( minutesL > 2) leds[5] = CRGB::White;
  else if ( minutesL > 1) leds[5] = CRGB::Yellow;
  else if ( minutesL )leds[5] = CRGB::Red;


  //Zehnersekunden
  if (secondsH > 4) leds[4] = CRGB::Yellow;
  else if (secondsH > 3) leds[4] = CRGB::Red;
  else if (secondsH > 2) leds[3] = CRGB::White;
  else if (secondsH > 1) leds[3] = CRGB::Yellow;
  else if (secondsH) leds[3] = CRGB::Red;

  //Einersekunden
  if (secondsL > 8) leds[2] = CRGB::White;
  else if (secondsL > 7) leds[2] = CRGB::Yellow;
  else if (secondsL > 6) leds[2] = CRGB::Red;
  else if (secondsL > 5) leds[1] = CRGB::White;
  else if (secondsL > 4) leds[1] = CRGB::Yellow;
  else if (secondsL > 3) leds[1] = CRGB::Red;
  else if (secondsL > 2) leds[0] = CRGB::White;
  else if (secondsL > 1) leds[0] = CRGB::Yellow;
  else if (secondsL) leds[0] = CRGB::Red;

  FastLED.show();
  FastLED.delay(1000);
}
1 Like

Hi,

In the end, however, I would need 15 WS2811. Then I could control the seconds with red, the minutes with green and the hours with blue. The final board has not yet been ordered. Did I get that right?

still why not 74hc595?

I don't quite understand what you are saying.

With 39 leds, you really only need 13 WS2811s, no need to leave unconnected outputs scattered about.

As has been asked a couple of times, why the WS2811 instead of a 74hc595, which is fairly small in a surface mount package.

What is this module that I marked with a yellow circle?

Post your wiring diagram to make it easier for us to understand your project and be able to help you better.

why the WS2811 instead of a 74hc595

Driving pixels with the WS2811 chip and using FastLED to set the colors is way easier than cobbling up enough shifting registers to do the job, even if all you were doing was on/off.

If you add PWM colour control it only makes the smart LED approach look better.

@david_2018's idea is a good one, wire 'em up and sort it out in software at the byte level.

I would think that if were convenient, a few more or less WS2811 would t be a large deal.

Mostly, though, it is nearly working now, and is (should be) already a matter of getting the code right.

This

FastLED.delay(1000);

is nothing you want to do in code like this. If once per second is a thing, just watch for the RTC seconds to change, then publish. As @UKHeliBob sez, with only this many pixels, rendering them all every second is not a bad thing.

The code should need but one call in the code to show the new contents of the pixel buffer.

a7

1 Like

Hi,

you‘re my hero for today! A big and fat thank you to Flensburg.

I have added a few little things. Seconds 1-3 went out when the fourth started. But the clear structure was so easy to read that changes were made quickly.

Now it works smoothly:

/*
  Project: Linearuhr von NTC Zeit Server mit ESP32
  Author: Michael Todtenbier
  Date: Created 02.07.2024
  Version: V1.0
  IDE: Arduino IDE 1.8.19

  Required libraries (sketch -> include library -> manage libraries)
  -Grüße aus Flensburg
*/

#include <WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
//#include <Adafruit_NeoPixel.h>
#include <FastLED.h>

#define DATA_PIN 27 // Pin für LED-Streifen
const byte NUM_LEDS = 14; // Anzahl der WS2811-Chips
// This is an array of leds. One item for each led in your strip.
CRGB leds[NUM_LEDS];

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200, 60000);

// Wi-Fi Settings
const char *wifi_ssid = "YourSSID";
const char *wifi_password = "YourPassword";
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO = "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00";

/*
  time_t now;
  tm tm;
*/

void setup () {
  Serial.begin(115200);

  // Verbindung zu WiFi herstellen
  delay(10);
  WiFi.begin(wifi_ssid, wifi_password);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (++counter > 100) ESP.restart();
    Serial.print(".");
  }
  Serial.println("WiFi connected");

  //FastLED aktivieren
  FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);

  // NTP Client starten
  timeClient.begin();
}

void loop () {
  timeClient.update();

  byte hoursH = timeClient.getHours() / 10;
  byte hoursL = timeClient.getHours() % 10;
  byte minutesH = timeClient.getMinutes() / 10;
  byte minutesL = timeClient.getMinutes() % 10;
  byte secondsH = timeClient.getSeconds() / 10;
  byte secondsL = timeClient.getSeconds() % 10;

//  Serial.printf(" \tUhrzeit: %02d:%02d:%02d \n", hours, minutes, seconds);
  for (int i = 0; i < NUM_LEDS; i++)leds[i] = CRGB::Black;


  //Zehnerstunden
  if (hoursH > 1) leds[13] = CRGB::Yellow;
  else if (hoursH ) leds[13] = CRGB::Red;

  //Einerstunden
  if (hoursL > 8) {leds[12] = CRGB::White; leds[11] = CRGB::White; leds[10] = CRGB::White;}
  else if (hoursL > 7) {leds[12] = CRGB::Yellow; leds[11] = CRGB::White; leds[10] = CRGB::White;}
  else if (hoursL > 6) {leds[12] = CRGB::Red; leds[11] = CRGB::White; leds[10] = CRGB::White;}
  else if (hoursL > 5) {leds[11] = CRGB::White; leds[10] = CRGB::White;}
  else if (hoursL > 4) {leds[11] = CRGB::Yellow; leds[10] = CRGB::White;}
  else if (hoursL > 3) {leds[11] = CRGB::Red; leds[10] = CRGB::White;}
  else if (hoursL > 2) leds[10] = CRGB::White;
  else if (hoursL > 1) leds[10] = CRGB::Yellow;
  else if (hoursL )leds[10] = CRGB::Red;


  //Zehnerminuten
  if ( minutesH > 4) {leds[9] = CRGB::Yellow; leds[8] = CRGB::White;}
  else if ( minutesH > 3) {leds[9] = CRGB::Red; leds[8] = CRGB::White;}
  else if ( minutesH > 2) leds[8] = CRGB::White;
  else if ( minutesH > 1) leds[8] = CRGB::Yellow;
  else if ( minutesH ) leds[8] = CRGB::Red;

  //Einerminuten
  if ( minutesL > 8) {leds[7] = CRGB::White; leds[6] = CRGB::White; leds[5] = CRGB::White;}
  else if ( minutesL > 7) {leds[7] = CRGB::Yellow; leds[6] = CRGB::White; leds[5] = CRGB::White;}
  else if ( minutesL > 6) {leds[7] = CRGB::Red; leds[6] = CRGB::White; leds[5] = CRGB::White;}
  else if ( minutesL > 5) {leds[6] = CRGB::White; leds[5] = CRGB::White;}
  else if ( minutesL > 4) {leds[6] = CRGB::Yellow; leds[5] = CRGB::White;}
  else if ( minutesL > 3) {leds[6] = CRGB::Red; leds[5] = CRGB::White;}
  else if ( minutesL > 2) leds[5] = CRGB::White;
  else if ( minutesL > 1) leds[5] = CRGB::Yellow;
  else if ( minutesL )leds[5] = CRGB::Red;


  //Zehnersekunden
  if (secondsH > 4) {leds[4] = CRGB::Yellow; leds[3] = CRGB::White;}
  else if (secondsH > 3) {leds[4] = CRGB::Red; leds[3] = CRGB::White;}
  else if (secondsH > 2) leds[3] = CRGB::White;
  else if (secondsH > 1) leds[3] = CRGB::Yellow;
  else if (secondsH) leds[3] = CRGB::Red;

  //Einersekunden
  if (secondsL > 8) {leds[2] = CRGB::White; leds[1] = CRGB::White; leds[0] = CRGB::White;}
  else if (secondsL > 7) {leds[2] = CRGB::Yellow; leds[1] = CRGB::White; leds[0] = CRGB::White;}
  else if (secondsL > 6) {leds[2] = CRGB::Red; leds[1] = CRGB::White; leds[0] = CRGB::White;}
  else if (secondsL > 5) {leds[1] = CRGB::White; leds[0] = CRGB::White;}
  else if (secondsL > 4) {leds[1] = CRGB::Yellow; leds[0] = CRGB::White;}
  else if (secondsL > 3) {leds[1] = CRGB::Red; leds[0] = CRGB::White;}
  else if (secondsL > 2) leds[0] = CRGB::White;
  else if (secondsL > 1) leds[0] = CRGB::Yellow;
  else if (secondsL) leds[0] = CRGB::Red;

  FastLED.show();
  FastLED.delay(1000);
}

The 74hc595 is certainly the better solution, but I am absolutely not familiar with it. On the other hand, I am very familiar with the WS2811. I have installed hundreds of them since 2020. Since the sketch is now running, there is no longer any reason to change the finished board layout.

Cheers, Michael

Lose the

  FastLED.delay(1000);
}

at the end of the loop. There will otherwise be, I feel sure, a glitch from time to time as the unstnchronized delay falls unfortunately with respect to the actual increment.

void loop () {
  timeClient.update();

  static int lastDisplayed = -1;  // impossible initial value

  int secondsNow = timeClient.getSeconds();
  if (secondsNow == lastDisplayed) return;  // not time yet

  lastDisplayed = secondsNow;

  byte hoursH = timeClient.getHours() / 10;
  byte hoursL = timeClient.getHours() % 10;
  byte minutesH = timeClient.getMinutes() / 10;
  byte minutesL = timeClient.getMinutes() % 10;

// &c.


a7

Hi,
this is a self-developed board with ten WS2811 chips. It is designed to solder LEDs directly to the outputs and has four input pins to connect the board to an Arduino.

You can find all informations at MobaLedLib Wiki.

So each single LED is connectet to one of these WS2811 starting from bottom to top of the linear clock. For example: the seconds are connectet to the first three WS2811 and their RG and B-Outputs.

When I remove the delay, the sketch requests the time about 30 times per second (you can see this on the serial monitor). With Delay, the time is only queried once per second. Currently, I still wonder what impact this has on my WLAN and whether the use of an RTC module would not be better.