fix(P4): Heizleistungs-Kurven flackerten in großen Zeitfenstern — Bucket-Mittelung statt Einzelsample #5

Merged
thomas merged 1 commits from fix/verlauf-duty-dezimierung-mitteln into main 2026-07-13 01:27:14 +02:00
3 changed files with 41 additions and 13 deletions
+9
View File
@@ -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: Version 1.0.11:
- Verlauf-Seite ausgebaut (nur P4, keine S3-/Protokolländerung nötig): - 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. - Umschaltbares Zeitfenster: Buttons „2 min / 10 min / 30 min / 60 min" in der Kopfzeile.
+1 -1
View File
@@ -65,7 +65,7 @@
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
// Firmware // 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 // Protokoll
+31 -12
View File
@@ -1483,20 +1483,39 @@ static void chart_redraw() {
int32_t lo = INT32_MAX, hi = INT32_MIN; // Zehntelgrad int32_t lo = INT32_MAX, hi = INT32_MIN; // Zehntelgrad
bool anyW = false, anyD = false; bool anyW = false, anyD = false;
for (int i = 0; i < 120; i++) { 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 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; int32_t dW = LV_CHART_POINT_NONE, dD = LV_CHART_POINT_NONE;
if (age < (int)g_histFill) { if (ageStart < (int)g_histFill) {
int idx = (int)g_histPos - 1 - age; // Ueber den ganzen Bucket mitteln statt ein Einzelsample zu picken: das
if (idx < 0) idx += CHART_HIST_MAX; // Abtast-Raster haengt an g_histPos und wandert sonst mit jedem Sekundentick,
vW = g_hist->w[idx]; // wodurch schnell schaltende Werte (Duty-PWM) sichtbar zwischen zwei
vD = g_hist->d[idx]; // Kurvenbildern hin- und herspringen. Der Mittelwert ist zudem bei der
if (g_hist->c[idx] != CHART_HIST_NONE) vC = g_hist->c[idx]; // Heizleistung die ehrlichere Aussage als ein zufaelliger Momentwert.
dW = g_hist->dutyW[idx]; int32_t sW = 0, sD = 0, sC = 0, sDW = 0, sDD = 0;
dD = g_hist->dutyD[idx]; int nT = 0, nC = 0;
if (vW > 300) { anyW = true; if (vW < lo) lo = vW; if (vW > hi) hi = vW; } for (int s = 0; s < stride; s++) {
if (vD > 300) { anyD = true; if (vD < lo) lo = vD; if (vD > hi) hi = vD; } int age = ageStart + s;
if (vC != LV_CHART_POINT_NONE && vC > 300) { if (vC < lo) lo = vC; if (vC > hi) hi = vC; } 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_serW, i, vW);
lv_chart_set_value_by_id(g_chart, g_serD, i, vD); lv_chart_set_value_by_id(g_chart, g_serD, i, vD);