Ich habs mir jetzt nochmal angeschaut und es ist wirklich keinerlei Systematik drin. Manchmal blinkt es nach einer Kompilierung, manchmal dann mit dem selben File nicht. Unabhängig von der Boardversion in der Boardverwaltung (alte/neue Version und mehrere dazwischen probiert) und unabhängig davon ob per USB oder OTA geflasht.
Interessant ist, dass die Fehlermeldung für fehlende Wlan-Verbindung am Anfang ("kein Funk") nur kommt, wenn die Anzeige dann blinkt. Bleiben die Leds am Anfang weiß, so tritt kein Blinken auf.
Fehler sieht so aus, wiederholt sich alle 2 s:
VID_20250108_212414.mp4
Alle 2 Sekunden, da ich definiert habe, dass die Leds nur alle 2 Sekunden aktualisiert werden.
#define FASTLED_ESP8266_RAW_PIN_ORDER
#include <FastLED.h>
#include <ESP8266WiFi.h>
#include <time.h> // time() ctime()
#include <sys/time.h> // struct timeval
#include "wordclock_words.c"
#include "wordclock_eeprom.h"
#include <Dusk2Dawn.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#define NUM_LEDS 140
#define NUM_LINES 11
#define DATA_PIN 2
#define SSID "hasi"
#define KEY "mausi"
#define TZ 1 // (utc+) TZ in hours
#define DST_MN 0 // use 60mn for summer time in some countries
#define TZ_SEC ((TZ)*3600)
#define DST_SEC ((DST_MN)*60)
CRGB leds[NUM_LEDS];
CRGB color_line[NUM_LINES];
CRGB color_line1[NUM_LINES];
CRGB color_line2[NUM_LINES];
CRGB color_ambient;
void word2stripe(const int[], int, CRGB color = CRGB::Orange);
void blankscreen(bool commit = false);
const char* host = "esp8266-webupdate";
bool beforeSunrise = false;
bool afterSunset = false;
bool Ambient_on = false;
int laSunrise = 0;
int laSunset = 0;
uint32_t millis_start = 0;
uint32_t millis_delay = 0;
uint8_t hourx;
uint8_t minx;
uint8_t sekx;
uint8_t wdayx;
uint8_t mdayx;
uint8_t monx;
uint8_t yearx;
int timeinmin;
timeval tv;
time_t now;
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
blankscreen(true);
// config time
configTime(TZ_SEC, DST_SEC, "pool.ntp.org");
//connect to WiFi
WiFi.mode(WIFI_STA);
WiFi.hostname("WordClock");
WiFi.begin(SSID, KEY);
while (WiFi.status() != WL_CONNECTED) { // show "KEIN FUNK"
word2stripe(word_KEIN, sizeof(word_KEIN) / sizeof(int), CRGB::Red);
word2stripe(word_FUNK, sizeof(word_FUNK) / sizeof(int), CRGB::Red);
FastLED.show();
delay(5000);
}
//Farben definieren
color_line1[1] = CRGB(102, 255, 255); //kalt
color_line1[2] = CRGB(122, 255, 214);
color_line1[3] = CRGB(143, 255, 173);
color_line1[4] = CRGB(163, 255, 133);
color_line1[5] = CRGB(184, 255, 92);
color_line1[6] = CRGB(204, 255, 51);
color_line1[7] = CRGB(153, 217, 38);
color_line1[8] = CRGB(102, 179, 26);
color_line1[9] = CRGB(51, 140, 13);
color_line1[10] = CRGB(0, 102, 0);
color_line2[1] = CRGB(102, 255, 255); //warm
color_line2[2] = CRGB(122, 255, 214);
color_line2[3] = CRGB(143, 255, 173);
color_line2[4] = CRGB(163, 255, 133);
color_line2[5] = CRGB(184, 255, 92);
color_line2[6] = CRGB(204, 255, 51);
color_line2[7] = CRGB(217, 204, 38);
color_line2[8] = CRGB(230, 153, 26);
color_line2[9] = CRGB(242, 101, 13);
color_line2[10] = CRGB(255, 50, 0);
gettimeofday(&tv, nullptr); //erstes mal Zeit holen
now = time(nullptr);
MDNS.begin(host);
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
}
void loop() {
httpServer.handleClient(); //Client für Updateprozedur
if (millis() - millis_delay > (2000 - 709)) { //Anti-delay-Abfrage, Programmlaufzeit berücksichtigt, sonst wird Uhr ungenau
if (millis() - millis_start > 900000) { //15 min vergangen, Zeit neu holen
gettimeofday(&tv, nullptr);
now = time(nullptr);
millis_start = millis(); //Zeit in ms seit Arduinostart
} else {
now = now + 2; // 2 s draufaddieren
}
blankscreen(true); // all pixels to black, "Aufräumen" der LEDs, sonst würden iwann alle leuchten
Ambient_on = false;
hourx = localtime(&now)->tm_hour;
minx = localtime(&now)->tm_min;
sekx = localtime(&now)->tm_sec;
wdayx = localtime(&now)->tm_wday;
mdayx = localtime(&now)->tm_mday;
monx = localtime(&now)->tm_mon;
timeinmin = hourx * 60 + minx;
if (LEDs_on()) {
timeToStripe(hourx, minx, sekx); // calculate time and fill leds array
FastLED.setBrightness(brightness());
FastLED.setDither(0);
FastLED.show();
FastLED.delay(5);
}
if (millis() < 600000) {
printdiagnosis();
}
millis_delay = millis();
}
}
// push word to leds array
void word2stripe(const int word[], int len, CRGB color) {
for (int letter = 0; letter < len; letter++) {
leds[word[letter]] = color;
}
}
// blank screen (to specific color if given, and put it on the matrix if set)
void blankscreen(bool commit) {
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB(0, 0, 0);
if (commit) {
FastLED.show();
}
}
}
//sollen LEDs leuchten?
boolean LEDs_on() {
if (((hourx == 6) && (wdayx > 0 && wdayx < 6)) || // früh unter der Woche, 0= So, 1 = Mo, 5 = Fr, 6 = Sa, - 6-7 Uhr
((hourx > 15 && hourx < 23) && (wdayx > 0 && wdayx < 6)) || // Mo-Fr abend 16-23 Uhr
((hourx > 6 && hourx < 23) && (wdayx == 6 || wdayx == 0)) || //tagsüber Samstag, Sonntag 7-23 Uhr
//(hourx > 6 && hourx < 23) || //nur während Homeoffice
(((mdayx > 19 && monx == 11) || (mdayx < 7 && monx == 0)) && (hourx > 6 && hourx < 23))) { //Weihnachten bis heilig drei Könige
return true;
} else {
return false;
}
}
//Mappingfunktion - Dreisatz
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//Helligkeit LEDs festlegen
byte brightness() {
int high = 200;
int low = 10;
int atsun = 60; //Helligkeit bei Sonnenauf/untergang
int set_startdim = laSunset - 120; // 3h vor Sonnenuntergang
int set_enddim = laSunset + 180;
int rise_startdim = laSunrise - 60;
int rise_enddim = laSunrise + 180;
if (timeinmin <= set_startdim && timeinmin >= rise_enddim) { //tagsüber
return high;
}
if (timeinmin >= set_enddim || timeinmin <= rise_startdim) { //nachts
return low;
}
if (timeinmin > set_startdim && timeinmin < set_enddim) { // Zeitraum für Dimmen abends
if (timeinmin < laSunset) { // Dimmen vor Sonnenuntergang
return mapfloat(timeinmin, laSunset, set_startdim, atsun, high);
} else { // Dimmen nach Sonnenuntergang
return mapfloat(timeinmin, set_enddim, laSunset, low, atsun);
}
}
if (timeinmin < rise_enddim && timeinmin > rise_startdim) { // Zeitraum für Dimmen früh
if (timeinmin > laSunrise) { // Dimmen nach Sonnenaufgang
return mapfloat(timeinmin, laSunrise, rise_enddim, atsun, high);
} else { // Dimmen vor Sonnenaufgang
return mapfloat(timeinmin, rise_startdim, laSunrise, low, atsun);
}
}
return atsun; //Notfallwert, falls keine if-Bedingung greift
}
//calculate if sunset/rise
void isSun() {
..
}
// push the time (words) to leds array
void timeToStripe(uint8_t hours, uint8_t mins, uint8_t secs) {
//Farbe der Buchstaben korrekt auswaehlen
isSun();
if (afterSunset) {
for (int line = 0; line < NUM_LINES; line++) {
color_line[line] = color_line2[line];
}
} else {
for (int line = 0; line < NUM_LINES; line++) {
color_line[line] = color_line1[line];
}
}
// show "ES IST"
word2stripe(word_ES, sizeof(word_ES) / sizeof(int), color_line[1]);
word2stripe(word_IST, sizeof(word_IST) / sizeof(int), color_line[1]);
//Ambientebeleuchtung
if (beforeSunrise) {
color_ambient = CRGB(255, 255, 255);
Ambient_on = true;
} else if (beforeSunrise == false && afterSunset == false) {
color_ambient = CRGB(0, 0, 0);
} else if (afterSunset) {
color_ambient = color_line2[10];
Ambient_on = true;
}
word2stripe(ambient_OBEN, sizeof(ambient_OBEN) / sizeof(int), color_ambient);
word2stripe(ambient_LINKS, sizeof(ambient_LINKS) / sizeof(int), color_ambient);
word2stripe(ambient_RECHTS, sizeof(ambient_RECHTS) / sizeof(int), color_ambient);
word2stripe(ambient_UNTEN, sizeof(ambient_UNTEN) / sizeof(int), color_ambient);
//Sekundenzeiger
int secs2 = secs / 2.5;
if (Ambient_on) {
leds[A[secs2]] = CRGB(0, 0, 0);
if (secs2 > 0 && secs2 < 5 || secs2 > 6 && secs2 < 11 || secs2 > 12 && secs2 < 17 || secs2 > 18 && secs2 < 24) {
leds[A[secs2 - 1]] = color_ambient / 2.9;
leds[A[secs2 + 1]] = color_ambient / 2.9;
}
if (secs2 == 0 || secs2 == 6 || secs2 == 12 || secs2 == 18) {
leds[A[secs2 + 1]] = color_ambient / 2.9;
}
if (secs2 == 5 || secs2 == 11 || secs2 == 17 || secs2 == 24) {
leds[A[secs2 - 1]] = color_ambient / 2.9;
}
} else {
leds[A[secs2]] = CRGB(255, 255, 255);
}
// restliche Uhrzeit
if (mins >= 5 && mins < 10) {
..
}
int singleMinutes = mins % 5;
switch (singleMinutes) {
case 1:
word2stripe(min_ONE, sizeof(min_ONE) / sizeof(int), color_line[1]);
break;
case 2:
word2stripe(min_ONE, sizeof(min_ONE) / sizeof(int), color_line[1]);
word2stripe(min_TWO, sizeof(min_TWO) / sizeof(int), color_line[1]);
break;
case 3:
word2stripe(min_ONE, sizeof(min_ONE) / sizeof(int), color_line[1]);
word2stripe(min_TWO, sizeof(min_TWO) / sizeof(int), color_line[1]);
word2stripe(min_THREE, sizeof(min_THREE) / sizeof(int), color_line[10]);
break;
case 4:
word2stripe(min_ONE, sizeof(min_ONE) / sizeof(int), color_line[1]);
word2stripe(min_TWO, sizeof(min_TWO) / sizeof(int), color_line[1]);
word2stripe(min_THREE, sizeof(min_THREE) / sizeof(int), color_line[10]);
word2stripe(min_FOUR, sizeof(min_FOUR) / sizeof(int), color_line[10]);
break;
}
if (mins >= 15) {
hours++;
}
if (hours >= 12) {
hours -= 12;
}
switch (hours) {
case 0:
word2stripe(word_ZWOELF, sizeof(word_ZWOELF) / sizeof(int), color_line[9]);
break;
case 1:
if (mins > 4) {
word2stripe(word_EINS, sizeof(word_EINS) / sizeof(int), color_line[6]);
} else {
word2stripe(word_EIN, sizeof(word_EIN) / sizeof(int), color_line[6]);
}
break;
..
}
// show "UHR" if full hour
if (mins < 5) {
word2stripe(word_UHR, sizeof(word_UHR) / sizeof(int), color_line[10]);
}
}
void printdiagnosis() {
..
}
So sieht der ganze, an unrelevanten Stellen gekürzte Text dazu aus. Ich erwarte jetzt aber nicht, dass den jemand von euch gleich durchgeht.