diff --git a/P4_Display_Firmware/Changelog.txt b/P4_Display_Firmware/Changelog.txt index 30e6e7d..1b7488e 100644 --- a/P4_Display_Firmware/Changelog.txt +++ b/P4_Display_Firmware/Changelog.txt @@ -1,3 +1,16 @@ +Version 1.10.3: +- Direkt nach dem Aufwachen aus dem Standby zog die Wasserkurve eine kurze Delle nach + unten. Ursache ist die Messung, nicht der Kessel: In genau diesem Moment schalten die + Heizungen, und der Wassersensor hängt als NTC am ADC. Ein Kessel kann binnen einer + Sekunde nicht um Grade einbrechen. +- Die Verlaufskurven halten deshalb rund um jeden Standby-Wechsel sechs Sekunden lang + ihren letzten Wert, statt die gestörte Probe einzutragen. Das gilt für die kleinen + Kurven im Dashboard und für die große Verlaufsseite. +- Die angezeigten Temperaturzahlen bleiben unverändert: Dort steht weiter, was gemessen + wird. +- Die Versionsanzeige stand seit dem Zurücknehmen von 1.6.11 auf 1.6.10 fest und wurde bei + keinem der folgenden Stände mitgezogen. Sie zeigt jetzt wieder den echten Stand. + Version 1.10.2: - Die Verlaufskurven im Dashboard wurden überhaupt nicht fortgeschrieben. Der Code dafür stand am Ende der Umschaltung „Heizleistung anzeigen" auf der Verlauf-Seite - also im diff --git a/P4_Display_Firmware/config.h b/P4_Display_Firmware/config.h index 969092c..8653d6a 100644 --- a/P4_Display_Firmware/config.h +++ b/P4_Display_Firmware/config.h @@ -126,7 +126,7 @@ // ------------------------------------------------------------------------------------- // Firmware // ------------------------------------------------------------------------------------- -#define DISPLAY_FW_VERSION "1.6.10" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) +#define DISPLAY_FW_VERSION "1.10.3" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) // ------------------------------------------------------------------------------------- // Protokoll diff --git a/P4_Display_Firmware/ui.cpp b/P4_Display_Firmware/ui.cpp index 9fe67b7..8de0dce 100644 --- a/P4_Display_Firmware/ui.cpp +++ b/P4_Display_Firmware/ui.cpp @@ -1122,6 +1122,17 @@ static lv_obj_t* tempField(lv_obj_t* parent, const char* title, lv_color_t accen static int32_t g_sparkMin = INT32_MIN; // zuletzt gesetzter Ausschnitt, fuer beide gleich static int32_t g_sparkMax = INT32_MIN; +// Kurz nach einem Standby-Wechsel sackt die Wassertemperatur fuer einen Sekundenbruchteil +// ab. In genau diesem Moment schalten die Heizungen, und der Wassersensor ist ein NTC am +// ADC - ein Kessel kann binnen einer Sekunde nicht um Grade einbrechen, die Delle ist also +// eine Stoerung der Messung, kein Vorgang an der Maschine. Fuer die Dauer des Uebergangs +// schreiben die Verlaufskurven deshalb den letzten Wert von vor dem Wechsel weiter. Die +// angezeigten Zahlen bleiben unangetastet - was gemessen wird, steht dort weiter drin. +#define KURVEN_SPERRE_MS 6000 +static uint32_t g_kurvenSperreBis = 0; // millis(); bis dahin Werte halten +static float g_haltW = 0.0f; +static float g_haltD = 0.0f; + static void spark_scan(lv_obj_t* ch, lv_chart_series_t* ser, int32_t* mn, int32_t* mx) { if (!ch || !ser) return; int32_t* pts = lv_chart_get_y_array(ch, ser); @@ -1959,17 +1970,23 @@ static void chart_sample_cb(lv_timer_t*) { // // Bewusst vor dem Ausstieg unten: Die Kurven im Dashboard haengen nicht daran, ob // die Verlauf-Seite mit ihrem grossen Diagramm schon aufgebaut ist. + // Sperrfrist nach einem Standby-Wechsel: letzten Wert halten statt der frischen Probe. + bool sperre = g_kurvenSperreBis != 0 && (int32_t)(millis() - g_kurvenSperreBis) < 0; + if (!sperre) { g_haltW = g_state.tempW; g_haltD = g_state.tempD; } + const float probeW = sperre ? g_haltW : g_state.tempW; + const float probeD = sperre ? g_haltD : g_state.tempD; + if (g_sparkSerW && g_sparkW) - lv_chart_set_next_value(g_sparkW, g_sparkSerW, (int32_t)(g_state.tempW * 10.0f)); + lv_chart_set_next_value(g_sparkW, g_sparkSerW, (int32_t)(probeW * 10.0f)); if (g_sparkSerD && g_sparkD) - lv_chart_set_next_value(g_sparkD, g_sparkSerD, (int32_t)(g_state.tempD * 10.0f)); + lv_chart_set_next_value(g_sparkD, g_sparkSerD, (int32_t)(probeD * 10.0f)); spark_ranges_fit(); // gemeinsame Skala, damit die Hoehen vergleichbar bleiben if (!g_chart || !g_hist) return; // 1-s-Probe in die 60-min-Historie (Ringpuffer); Anzeige zeichnet chart_redraw bool caseOn = g_state.caseSensorEnabled && g_state.hasCaseTemp; - g_hist->w[g_histPos] = (int16_t)(g_state.tempW * 10.0f + 0.5f); - g_hist->d[g_histPos] = (int16_t)(g_state.tempD * 10.0f + 0.5f); + g_hist->w[g_histPos] = (int16_t)(probeW * 10.0f + 0.5f); + g_hist->d[g_histPos] = (int16_t)(probeD * 10.0f + 0.5f); g_hist->c[g_histPos] = caseOn ? (int16_t)(g_state.caseTemp * 10.0f + 0.5f) : CHART_HIST_NONE; float dw = g_state.dutyW, dd = g_state.dutyD; g_hist->dutyW[g_histPos] = (uint8_t)(dw < 0.0f ? 0 : (dw > 100.0f ? 100 : (int)(dw + 0.5f))); @@ -4258,6 +4275,16 @@ void ui_update(const MachineState& st) { // Standby-Uhr-Overlay (Backlight wird in onState gesteuert). Uebergaenge werden weich // gefadet: Einschlafen blendet die Uhr ein, Aufwecken blendet sie aus. Nur bei echtem // Statuswechsel animieren (g_standbyShown), sonst nur Uhrzeit/Vordergrund aktualisieren. + // Standby-Wechsel merken: die Verlaufskurven halten danach kurz ihren letzten Wert, + // damit die Messstoerung beim Schalten der Heizungen keine Delle in die Linie zieht. + static bool letzterStandby = false; + if (st.standbyActive != letzterStandby) { + letzterStandby = st.standbyActive; + g_haltW = st.tempW; + g_haltD = st.tempD; + g_kurvenSperreBis = millis() + KURVEN_SPERRE_MS; + } + if (g_standbyScreen) { bool shouldShow = st.standbyActive && st.standbyShowClock; if (shouldShow) {