diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index d5df872..e21f6a8 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,11 @@ +Version 1.8.6: +- Die Uhrzeit verschwindet nicht mehr, wenn die Hauptplatine ihre Zeit gerade neu abgleicht. + Der P4 merkt sich die zuletzt empfangene Uhrzeit und zählt zwischen den Meldungen selbst + weiter; sobald die Hauptplatine wieder eine Zeit schickt, gilt deren Wert. +- Der P4 stellt dabei nichts richtig und ersetzt keine Zeitquelle - er überbrückt nur die + Lücke. Hat er noch nie eine Uhrzeit bekommen, bleibt die Anzeige wie bisher leer. +- Gilt für die Uhr in der Kopfleiste und für die große Standby-Uhr. + Version 1.8.5: - Die Verzögerung von rund zwei Sekunden rund um den Standby ist behoben. Sie lag nicht an der Helligkeitsumschaltung, sondern daran, dass die Standby-Uhr bei JEDER Zustandsmeldung diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 55035fc..98d4d43 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -3895,6 +3895,44 @@ static void dash_brew_mode_tick(const MachineState& st) { dash_brew_mode(aktiv || (war && (uint32_t)(jetzt - zuletzt) < DASH_BREW_HOLD_MS)); } + +// ------------------------------------------------------------------------------------ +// Uhr läuft lokal weiter +// +// Die Uhrzeit kommt von der Hauptplatine und ist leer, solange dort keine Zeitquelle +// synchronisiert ist. Bei einem erneuten Abgleich ist sie kurz weg - auf dem Display +// verschwand die Uhr dann fuer ein paar Sekunden, was gerade im Standby unruhig wirkt. +// +// Deshalb merkt sich der P4 die zuletzt empfangene Zeit und zaehlt zwischen den Meldungen +// selbst weiter. Er stellt nichts richtig: Sobald die Hauptplatine wieder eine Zeit +// schickt, gilt deren Wert. Die lokale Uhr ueberbrueckt nur die Luecke. +// ------------------------------------------------------------------------------------ +static bool g_clockKnown = false; // schon einmal eine Zeit empfangen? +static uint32_t g_clockMinute = 0; // zuletzt bekannte Uhrzeit in Minuten seit Mitternacht +static uint32_t g_clockTick = 0; // Zeitpunkt (lv_tick), zu dem sie galt + +// "HH:MM" der Hauptplatine uebernehmen. Andere Formate werden nicht angetastet. +static void clock_note(const String& hhmm) { + if (hhmm.length() < 5 || hhmm.charAt(2) != ':') return; + int h = hhmm.substring(0, 2).toInt(); + int m = hhmm.substring(3, 5).toInt(); + if (h < 0 || h > 23 || m < 0 || m > 59) return; + g_clockMinute = (uint32_t)(h * 60 + m); + g_clockTick = lv_tick_get(); + g_clockKnown = true; +} + +// Anzuzeigende Uhrzeit: die der Hauptplatine, solange sie eine schickt - sonst die lokal +// weitergezaehlte. Leerer Rueckgabewert heisst: noch nie eine Zeit gehabt, nichts anzeigen. +static String clock_text(const String& vonS3) { + if (vonS3.length()) return vonS3; + if (!g_clockKnown) return String(); + uint32_t min = g_clockMinute + (uint32_t)((lv_tick_get() - g_clockTick) / 60000UL); + char b[6]; + snprintf(b, sizeof(b), "%02u:%02u", (unsigned)((min / 60) % 24), (unsigned)(min % 60)); + return String(b); +} + void ui_update(const MachineState& st) { if (!g_uiReady) return; @@ -3911,10 +3949,13 @@ void ui_update(const MachineState& st) { bool wifiOk = st.wifiConnected && !st.apMode; if (g_wifiIcon) lv_obj_set_style_text_color(g_wifiIcon, wifiOk ? COL_OK : (st.apMode ? COL_WARN : COL_TEXT_MUT), 0); - // Uhrzeit (nur wenn NTP synchronisiert) + // Uhrzeit. Angezeigt wird die der Hauptplatine; faellt sie voruebergehend aus, zaehlt + // der P4 die zuletzt bekannte Zeit selbst weiter (siehe clock_text). + clock_note(st.timeStr); + String zeit = clock_text(st.timeStr); if (g_clock) { - if (st.timeStr.length()) { - lv_label_set_text(g_clock, st.timeStr.c_str()); + if (zeit.length()) { + label_set_if_changed(g_clock, zeit.c_str()); lv_obj_remove_flag(g_clock, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(g_clock, LV_OBJ_FLAG_HIDDEN); @@ -3927,7 +3968,7 @@ void ui_update(const MachineState& st) { if (g_standbyScreen) { bool shouldShow = st.standbyActive && st.standbyShowClock; if (shouldShow) { - lv_label_set_text(g_standbyClock, st.timeStr.length() ? st.timeStr.c_str() : "--:--"); + label_set_if_changed(g_standbyClock, zeit.length() ? zeit.c_str() : "--:--"); if (!g_standbyShown) { ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation g_standbyShown = true;