From f43375e99128927b63d24991b4e777d61a996d52 Mon Sep 17 00:00:00 2001 From: raw-designs Date: Mon, 13 Jul 2026 01:26:26 +0200 Subject: [PATCH] =?UTF-8?q?fix(P4):=20Heizleistungs-Kurven=20flackerten=20?= =?UTF-8?q?in=20gro=C3=9Fen=20Zeitfenstern=20=E2=80=94=20Bucket-Mittelung?= =?UTF-8?q?=20statt=20Einzelsample?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Dezimierung im Verlauf-Chart pickte pro Punkt ein Einzelsample; das Abtast-Raster hing an g_histPos und wanderte mit jedem Sekundentick um eine Position. Die schnell schaltende Heizleistung (PWM) sprang dadurch sichtbar zwischen zwei Kurvenbildern hin und her. Jetzt wird über den gesamten stride-Bucket gemittelt — Bild steht ruhig, Leistungs-Kurve zeigt die echte mittlere Heizleistung. Version 1.0.12. Co-Authored-By: Claude Fable 5 --- JC_Display_Firmware/Changelog.txt | 9 +++++++ JC_Display_Firmware/config.h | 2 +- JC_Display_Firmware/ui.cpp | 43 ++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/JC_Display_Firmware/Changelog.txt b/JC_Display_Firmware/Changelog.txt index f0597cc..37c9328 100644 --- a/JC_Display_Firmware/Changelog.txt +++ b/JC_Display_Firmware/Changelog.txt @@ -1,3 +1,12 @@ +Version 1.0.12: +- Verlauf-Chart: Flackernde Heizleistungs-Kurven in den großen Zeitfenstern behoben. Die + Dezimierung pickte pro Chart-Punkt ein Einzelsample, dessen Abtast-Raster mit jedem + Sekundentick um eine Position wanderte — die schnell schaltende Heizleistung (PWM) + sprang dadurch sichtbar zwischen zwei Kurvenbildern hin und her. Jetzt wird über den + gesamten Zeitabschnitt eines Chart-Punkts gemittelt: das Bild steht ruhig, und die + Leistungs-Kurve zeigt die tatsächliche mittlere Heizleistung statt zufälliger + Momentwerte. Im 2-min-Fenster (1 Sample je Punkt) ändert sich nichts. + Version 1.0.11: - Verlauf-Seite ausgebaut (nur P4, keine S3-/Protokolländerung nötig): - Umschaltbares Zeitfenster: Buttons „2 min / 10 min / 30 min / 60 min" in der Kopfzeile. diff --git a/JC_Display_Firmware/config.h b/JC_Display_Firmware/config.h index cbfdbfa..f3058e7 100644 --- a/JC_Display_Firmware/config.h +++ b/JC_Display_Firmware/config.h @@ -65,7 +65,7 @@ // ------------------------------------------------------------------------------------- // Firmware // ------------------------------------------------------------------------------------- -#define DISPLAY_FW_VERSION "1.0.11" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) +#define DISPLAY_FW_VERSION "1.0.12" // Firmware-Stand der P4-Display-Steuerung (Info-Seite) // ------------------------------------------------------------------------------------- // Protokoll diff --git a/JC_Display_Firmware/ui.cpp b/JC_Display_Firmware/ui.cpp index 6c3c93d..9a939ba 100644 --- a/JC_Display_Firmware/ui.cpp +++ b/JC_Display_Firmware/ui.cpp @@ -1483,20 +1483,39 @@ static void chart_redraw() { int32_t lo = INT32_MAX, hi = INT32_MIN; // Zehntelgrad bool anyW = false, anyD = false; for (int i = 0; i < 120; i++) { - int age = (119 - i) * stride; // Alter der Probe (Sekunden) + int ageStart = (119 - i) * stride; // juengstes Alter im Bucket (Sekunden) int32_t vW = LV_CHART_POINT_NONE, vD = LV_CHART_POINT_NONE, vC = LV_CHART_POINT_NONE; int32_t dW = LV_CHART_POINT_NONE, dD = LV_CHART_POINT_NONE; - if (age < (int)g_histFill) { - int idx = (int)g_histPos - 1 - age; - if (idx < 0) idx += CHART_HIST_MAX; - vW = g_hist->w[idx]; - vD = g_hist->d[idx]; - if (g_hist->c[idx] != CHART_HIST_NONE) vC = g_hist->c[idx]; - dW = g_hist->dutyW[idx]; - dD = g_hist->dutyD[idx]; - if (vW > 300) { anyW = true; if (vW < lo) lo = vW; if (vW > hi) hi = vW; } - if (vD > 300) { anyD = true; if (vD < lo) lo = vD; if (vD > hi) hi = vD; } - if (vC != LV_CHART_POINT_NONE && vC > 300) { if (vC < lo) lo = vC; if (vC > hi) hi = vC; } + if (ageStart < (int)g_histFill) { + // Ueber den ganzen Bucket mitteln statt ein Einzelsample zu picken: das + // Abtast-Raster haengt an g_histPos und wandert sonst mit jedem Sekundentick, + // wodurch schnell schaltende Werte (Duty-PWM) sichtbar zwischen zwei + // Kurvenbildern hin- und herspringen. Der Mittelwert ist zudem bei der + // Heizleistung die ehrlichere Aussage als ein zufaelliger Momentwert. + int32_t sW = 0, sD = 0, sC = 0, sDW = 0, sDD = 0; + int nT = 0, nC = 0; + for (int s = 0; s < stride; s++) { + int age = ageStart + s; + if (age >= (int)g_histFill) break; + int idx = (int)g_histPos - 1 - age; + if (idx < 0) idx += CHART_HIST_MAX; + sW += g_hist->w[idx]; + sD += g_hist->d[idx]; + sDW += g_hist->dutyW[idx]; + sDD += g_hist->dutyD[idx]; + nT++; + if (g_hist->c[idx] != CHART_HIST_NONE) { sC += g_hist->c[idx]; nC++; } + } + if (nT > 0) { + vW = (sW + nT / 2) / nT; + vD = (sD + nT / 2) / nT; + dW = (sDW + nT / 2) / nT; + dD = (sDD + nT / 2) / nT; + if (nC > 0) vC = (sC + nC / 2) / nC; + if (vW > 300) { anyW = true; if (vW < lo) lo = vW; if (vW > hi) hi = vW; } + if (vD > 300) { anyD = true; if (vD < lo) lo = vD; if (vD > hi) hi = vD; } + if (vC != LV_CHART_POINT_NONE && vC > 300) { if (vC < lo) lo = vC; if (vC > hi) hi = vC; } + } } lv_chart_set_value_by_id(g_chart, g_serW, i, vW); lv_chart_set_value_by_id(g_chart, g_serD, i, vD); -- 2.54.0