Der Punkt sass mittig auf dem letzten Messwert und damit auf der rechten
Kante der Kurvenflaeche - seine rechte Haelfte lag ausserhalb und wurde
abgeschnitten. Er sitzt jetzt vollstaendig innerhalb; der Schein darf
weiterhin darueber hinausreichen.
Der Punkt ist auf etwa zwei Drittel verkleinert. Das Pulsieren ist neu
choreografiert: Der Punkt selbst atmet leicht, der Schein macht das
Gegenteil - zieht der Punkt sich zusammen, geht der Schein auf.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx7wu7uXXgRzp1zHUhtUa6
Das Diagramm beschnitt seine Kinder an der eigenen Kante: Der Punkt am
rechten Ende war angeschnitten, und vom Schein war nichts zu sehen -
damit blieb auch das Pulsieren unsichtbar. Punkt und Schein duerfen jetzt
darueber hinausreichen; der Schein ist kraeftiger, der Punkt etwas
groesser.
Die Kurven verlaufen jetzt weich statt kantig. Gemessen wird weiterhin
einmal je Sekunde, gezeichnet viermal so fein: Zwischen zwei Messwerten
liegen vier Stuetzpunkte auf einem Kosinusbogen, der an den Messpunkten
waagerecht beginnt und endet. Linienenden und -ecken sind abgerundet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx7wu7uXXgRzp1zHUhtUa6
Der aelteste Wert einer Kurve liegt jetzt links genau auf halber Hoehe,
die Kurve waechst von dort nach oben oder unten. Der Verlauf sieht damit
bei jeder Kesseltemperatur gleich aus.
Beide Kurven behalten denselben Massstab. Die absolute Hoehe laesst sich
dadurch nicht mehr zwischen Wasser und Dampf vergleichen, der Ausschlag
aber schon.
Am juengsten Messwert sitzt ein kleiner weisser Punkt mit weichem Schein,
der langsam pulsiert. Beide Linien sind weiss.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx7wu7uXXgRzp1zHUhtUa6
Die Massnahme aus 1.10.3 verlaengerte die Delle, statt sie zu entfernen.
Sie hielt beim Umschalten des Standby-Merkers den zuletzt gemeldeten Wert
fest - zu diesem Zeitpunkt lag die gestoerte Probe aber bereits an.
Festgehalten wurde also ausgerechnet die Delle, und das sekundenlang.
Die Verlaufskurven tragen jetzt den mittleren Wert der letzten fuenf
Proben ein (Median). Ein bis zwei verirrte Proben verschwinden damit
vollstaendig, unabhaengig vom Zeitpunkt. Echte Aenderungen kommen
unverfaelscht durch, nur zwei Sekunden spaeter.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011gwqJf2DcqHFQpoY3XkDHX
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 haengt 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 gestoerte Probe einzutragen.
Das gilt fuer die kleinen Kurven im Dashboard und fuer die grosse
Verlaufsseite. Die angezeigten Temperaturzahlen bleiben unveraendert.
Ausserdem: DISPLAY_FW_VERSION stand seit dem Ruecknehmen von 1.6.11 auf
1.6.10 fest und wurde bei keinem der folgenden Staende mitgezogen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fe8KxS47iPmuByJPs5RvEw
Die Linien blieben identisch und unbewegt - kein Skalierungsproblem, wie
1.10.0 und 1.10.1 angenommen hatten.
lv_chart_set_next_value() für g_sparkW/g_sparkD stand am Ende von
chart_duty_btn_cb(), dem Callback des Heizleistungs-Umschalters auf der
Verlauf-SEITE. Die Sparklines wuchsen also nur, wenn jemand genau diesen
Knopf drückte. Ansonsten zeigten sie unverändert, was lv_chart_set_all_value()
beim Aufbau der Darstellung eingetragen hatte.
Der Block sitzt jetzt in chart_sample_cb() (1-s-Timer), und zwar vor dessen
"if (!g_chart || !g_hist) return" - die Dashboard-Kurven sollen nicht davon
abhängen, ob die Verlauf-Seite samt großem Diagramm aufgebaut ist.
Die gemeinsame Skala aus 1.10.1 bleibt richtig, konnte bisher aber nichts
ausrichten, weil nie neue Werte ankamen.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012gBXGt5M22ns5YfNJRaiMu
Nachbesserung zu 1.10.0. Dort bekam jede Kurve ihren eigenen Ausschnitt aus
ihren eigenen min/max. Bei zwei flachen Kurven (Wasser 70 °C, Dampf 0 °C)
greift beidesmal die Mindestspanne, jede Linie sitzt mittig in ihrem Fenster -
und beide liegen auf identischer Höhe. Die Skalierung war zu clever: Bewegung
wurde sichtbar, aber die Höhe verlor jede Bedeutung.
- spark_range_fit(ch, ser) ersetzt durch spark_ranges_fit(): scannt beide
Serien, bildet einen gemeinsamen Bereich und setzt ihn auf beide Charts.
- Der gemerkte Bereich liegt jetzt in zwei Datei-Statics statt in user_data
der Charts; das nimmt auch das nicht freigegebene lv_malloc bei jedem
Neuaufbau der Temperaturzeile weg.
- build_temp_row_content() setzt den Merker beim Aufbau zurück und ruft
spark_ranges_fit() erst, wenn beide Kurven stehen.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZJ2iUTbm7Zz5DTPkwgJyC
Die Sparklines im Dashboard lagen flach auf gleicher Höhe und bewegten sich
nicht, obwohl ein Kessel bei 80 °C stand und der andere bei 0.
Ursache: lv_chart_set_range() war an den Sollwert gebunden (soll-60 bis
soll+30 in Zehntelgrad). Liegt die Temperatur unter diesem Fenster - beim
Aufheizen oder bei abgeschaltetem Kessel -, klemmt LVGL jeden Punkt auf den
unteren Rand. Beide Kurven landeten dadurch auf derselben Linie.
- Neues spark_range_fit(): Ausschnitt aus min/max der vorhandenen Punkte
(lv_chart_get_y_array), Mindestspanne DASH_SPARK_MIN_SPAN (40 = 4,0 °C),
sonst ein Achtel Luft nach oben und unten.
- Der zuletzt gesetzte Bereich wird in user_data gemerkt, weil LVGL keinen
Getter dafür hat; ohne den Vergleich würde set_range das Diagramm bei jeder
Zustandsmeldung invalidieren.
- Die Charts füllen jetzt den Platz unterhalb der Zahlen (flex_grow 1,
min_height 90) statt als 64-px-Streifen mittig zu hängen.
Aufräumen nach der abgeschlossenen Fehlersuche:
- Herzschlag, [Zustand]- und [Touch]-Messzeilen entfernt.
- refr_monitor_install() hinter WS7_PERF_MONITOR (aus).
- scroll_ohne_nachlauf() gibt LV_OBJ_FLAG_SCROLL_MOMENTUM wieder frei.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019G95njDFkedFqXiz5sEaJ2
Der Nutzer hat es im Gegenlicht gesehen: Das Bild steht nach 446 ms fertig
da, nur die Beleuchtung kommt Sekunden später. Die gesamte Suche im
Zeichenablauf lief damit am falschen Ort - die Messungen dort waren alle
unauffällig, weil dort auch nichts war.
Der Referenz-Sketch (dsi-test.ino, enableBacklight) setzt 0xAB/0xAA zweimal
mit delay(100) dazwischen, ausdrücklich "sicherheitshalber Helligkeit noch
einmal übernehmen". jc_backlight_set() schrieb die Sequenz nur einmal.
- 0xAB/0xAA werden jetzt wiederholt, Pause über WS7_BACKLIGHT_LATCH_MS (20).
- 0xAD (Freigabe) nur noch beim ersten Aufruf statt bei jeder Änderung; der
Referenzcode setzt sie ebenfalls nur einmal, und sie erneut zu schreiben
stößt die Helligkeitsstufe der Bridge neu an.
- jc_backlight_set() meldet seine Dauer selbst; die doppelte Messung im .ino
entfällt.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Log zeigt zweimal hintereinander "rst:0x1 (POWERON)" und
"[Panel] Startgrund: 1", danach nichts mehr - Beleuchtung an, kein Bild.
Ursache: Der gewollte einmalige Neustart nach Kaltstart (WS7_COLD_BOOT_RESTART)
prüfte nur esp_reset_reason() == ESP_RST_POWERON. Der Kommentar nahm an, der
zweite Durchlauf melde einen Software-Reset. Tatsächlich meldet der Chip auch
nach esp_restart() wieder POWERON, die Bedingung greift erneut - Endlosschleife.
Der bootguard konnte nicht eingreifen, weil derselbe Zweig "early" jedes Mal
auf 0 zurücksetzt.
- Zusätzliches NVS-Flag "kaltneu" in bootguard: wird vor esp_restart() gesetzt
und beim zweiten Durchlauf erkannt und gelöscht. Unabhängig vom gemeldeten
Startgrund, damit die Schleife strukturell ausgeschlossen ist.
- Die Meldung lief über DBG_SERIAL (USB-CDC) und war im Monitor an der UART
nicht zu sehen - jetzt esp_rom_printf wie die übrigen Panel-Meldungen.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
Auswertung des letzten Logs (lv_tick lief 2728 ms hinter millis):
Tipp erkannt 49428, Rückfrage aufgebaut 49430, Bildaufbau fertig 49746.
Also 318 ms vom erkannten Tipp bis zum fertigen Bild - die gemessene Kette
ist schnell. Der Knopfdruck im Dialog liegt bei 55638 (Bereich 645..856,
374..426), die Antwort des S3 bei 59303, also 937 ms Rundlauf.
Die Verzögerung liegt damit VOR der Erkennung. Deshalb:
- ws7_touch_get_xy() meldet den ersten verworfenen Rohwert nach Ruhe mit
Koordinaten und zählt, wie viele bis zur akzeptierten Berührung anfallen.
- Alle Messzeilen auf millis() statt lv_tick_get(); die beiden Uhren
auseinanderzurechnen hat das Lesen unnötig erschwert.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
- dash_brew_mode() verteilt die flex_grow-Werte nicht mehr um. Die untere
Zeile bekam während des Bezugs 3 statt 2 und die Temperaturzeile 1 statt 3;
die kleinen Kacheln wurden dadurch enorm hoch und das Layout sprang.
- Die Messzeilen aus dem .ino liefen über Serial und damit über USB-CDC,
während der Monitor an der UART hängt - sie waren nie zu sehen. Jetzt
durchgängig esp_rom_printf wie die Panel-Meldungen.
- Alle Messzeilen tragen eine Zeitmarke in ms; ohne die sind die Lücken
nicht zu erkennen.
- onState() misst Ankunft der Zustandsmeldung, Wartezeit auf hal_lock() und
Dauer von ui_update(). standby_screen_cb() klammert wake_confirm_show()
ein. Das deckt beide Richtungen der gemeldeten Fünf-Sekunden-Verzögerung ab.
Das Einblenden der Standby-Uhr scheidet als Ursache aus: laut Messung 2 ms.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
Ursache gefunden. lv_draw_label.c legt pro Glyphe einen A8-Draw-Buf an:
box_w * LV_ROUND_UP(box_h, 32) Byte. Größte Ziffer des 360er-Fonts ist
190x247 -> 190*256 = 48 KB. Mit LV_DRAW_SW_DRAW_UNIT_CNT 2 sind zwei davon
gleichzeitig offen, also ~97 KB. Der LVGL-Pool (LV_MEM_SIZE 256 KB) hatte
laut Herzschlag nur 98068 Byte am Stück frei - es reichte knapp nicht.
LV_USE_ASSERT_MALLOC ist 1 und LV_ASSERT_HANDLER war "while(1);". Bei
fehlgeschlagener Allokation hält der LVGL-Task also stumm an: kein Panic,
kein Backtrace, Log bricht einfach ab. Genau das beobachtete Bild.
- font_buf_malloc/-free über lv_draw_buf_get_font_handlers(): Puffer ab
16 KB kommen per heap_caps_malloc aus dem PSRAM, kleinere weiter aus dem
LVGL-Pool (schneller; sonst würde jeder Text langsamer). Freigabe
unterscheidet über esp_ptr_external_ram().
- LV_ASSERT_HANDLER gibt jetzt eine Meldung aus, bevor er anhält.
Der interne RAM bleibt unangetastet - LV_MEM_SIZE zu erhöhen war keine
Option, der statische Speicher liegt bereits bei ~98 %.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
Beim Wechsel in den Standby bleibt das Display stehen: Bild bleibt auf der
alten Seite, keine Bedienung, auch der S3 weckt nicht mehr auf. Der Log
bricht nach dem letzten Bildaufbau ab, ohne Panic.
Statt zu raten, Messpunkte:
- Herzschlag alle 2 s aus dem Arduino-loop (freier Heap) und aus einem
lv_timer im LVGL-Task (lv_mem_monitor). Bleibt nur einer aus, ist klar,
welcher Task steht.
- ui_fade_in() der Standby-Uhr wird eingeklammert: "wird eingeblendet" /
"eingeblendet, N ms".
- hal_backlight() wird gemessen; über 50 ms wird die Dauer gemeldet.
Der Bridge-Schreibzugriff läuft über denselben I2C-Bus wie der Touch.
Außerdem entfernt: die LV_EVENT_INVALIDATE_AREA-Callbacks aus 1.9.5. Das
Event geht per lv_display_send_event an das Display, nicht an Objekte - die
Callbacks konnten nie feuern, ihr Ausbleiben war kein Beweis.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
- Der Darstellungsblock wandert aus build_info() in ein eigenes build_display()
mit neuer Seite PG_DISPLAY. Die Info-Seite zeigt nur noch Firmware-Stände und
Verbindungsdaten.
- clock_font() liefert für WS_PANEL_7H jetzt 180/270/360 statt 120/180/240. Für
JC_PANEL_43 bleiben die alten Stufen - 360 px passen nicht auf 480x480.
- Neue Fonts lv_font_clock_270/_360 (Maven Pro Regular, bpp 4, Range
32,45,0x30-0x3A). bpp 3 scheidet aus: lv_font_conv erlaubt das nur mit
Kompression, und die kostet beim Zeichnen genau das, was gerade eingespart wird.
- Alle fünf Uhr-Fonts sind deklariert; der Linker verwirft die je nach Panel
ungenutzten. Netto wächst die WS-Firmware um 196 KB.
Beide Panel-Varianten mit arduino-cli gegengebaut (PartitionScheme=custom,
passend zur partitions.csv mit zwei 6,5-MB-Slots).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NeFMr439WcLMdebE3kU7fS
Die festen Breiten aus 1.9.4 haben nicht gereicht. lv_label_set_text ruft
lv_obj_refresh_self_size(); ist eines der beiden Maße LV_SIZE_CONTENT, gilt
das Parent-Layout als dirty und der Container wird komplett invalidiert.
- tempField(): big und setp bekommen zusätzlich eine feste Höhe aus
lv_font_get_line_height().
- infoCell(): val ebenso, mit Platz für zwei Zeilen.
- g_clock: feste Breite/Höhe, rechtsbündig. Erklärt den Bereich
"x 6..57, y 2..41" (Menü-Knopf), der bei jedem Minutenwechsel durch das
Header-Relayout mit invalidiert wurde.
Zusätzlich eine gezielte Diagnose: LV_EVENT_INVALIDATE_AREA auf g_content
und der Dashboard-Seite meldet, wenn ein ganzer Container invalidiert wird -
damit ist "einzelnes Label" von "kompletter Bereich" zu unterscheiden.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Koordinaten haben den Verursacher benannt: Der invalidierte Bereich war
"x 0..1279, y 44..719" - der komplette Content-Container, bei jeder
Zustandsmeldung.
Grund: Die Wert-Labels hatten LV_SIZE_CONTENT. Ändert sich ihre Breite mit
dem Inhalt (92,4 °C -> 100,1 °C), löst LVGL ein Flex-Relayout der ganzen
Seite aus und invalidiert sie komplett. Change-checked Text allein reicht
also nicht - der Text darf beim Ändern auch die Breite nicht ändern.
tempField() und infoCell() setzen die Wert-Labels jetzt auf LV_PCT(100) mit
zentriertem Text. Optisch identisch, da die Werte ohnehin mittig standen.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Regression aus 1.8.7: Der deckende Drawer-Scrim verdeckte den
Seiteninhalt, der dahinter sichtbar bleiben soll. Zurück auf LV_OPA_50.
- ready_band_update() setzte Text, Textfarbe und Hintergrundfarbe des
Zustandsbands bei jeder Zustandsmeldung neu. Das Band spannt sich über die
volle Breite - allein dadurch wurde ein Streifen über den ganzen Bildschirm
ungültig. Jetzt über die change-checked Helfer.
- temp_progress_set() setzte Balkenwert und -farbe unbedingt; jetzt nur bei
echter Änderung.
- Das WLAN-Symbol ebenso.
- Die Messung gibt zusätzlich die Koordinaten der invalidierten Bereiche aus.
Die Fläche allein sagt nicht, welcher Teil der UI den Redraw auslöst.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die erweiterte Messung war eindeutig: "1 Bereich, 100 % der Fläche" - LVGL
zeichnete bei jeder Zustandsmeldung den kompletten Bildschirm neu, also
einmal pro Sekunde 240-300 ms lang. Kein Rendering-Tempoproblem, sondern
massiv zu viel Invalidierung.
lv_label_set_text invalidiert den Label-Bereich unbedingt, auch bei
identischem Text; lv_obj_set_style_text_color ebenso. Auf dem Dashboard
wurden pro Sekunde Werte quer über den Bildschirm gesetzt (Uhr oben,
Temperaturen Mitte, Bezugswerte unten) - LVGL joint die Bereiche, und die
Bounding-Box ist die ganze Fläche.
- Neue Helfer label_fmt_if_changed() und label_color_if_changed() neben dem
vorhandenen label_set_if_changed().
- Alle 13 zyklischen Textzuweisungen und alle 10 Farbzuweisungen in
ui_update darauf umgestellt.
Da sich Temperaturen selten um ein Zehntelgrad ändern und Sollwerte
praktisch nie, entfallen die meisten Neuzeichnungen ganz.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
WS7_DIRECT_FB hat die Bildaufbauzeit nicht verkürzt (weiterhin 240-300 ms)
und Bildfehler erzeugt - in denselben Speicher zu zeichnen, aus dem gerade
angezeigt wird, geht ohne zweiten Framebuffer nicht sauber. Zurück auf 0,
Schalter mit Begründung erhalten.
Damit ist belegt: Der Flaschenhals liegt nicht im Kopieren, sondern im
Rendern selbst. Offen ist, ob LVGL kleine Bereiche langsam zeichnet oder
jedes Mal die volle Fläche - zwei verschiedene Ursachen.
refr_start_cb summiert deshalb jetzt die nicht zusammengefassten
inv_areas und meldet Anzahl und Flächenanteil zusammen mit der Dauer.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Messung aus 1.8.8 hat es gezeigt: Jeder Bildaufbau kostete 240-300 ms,
dauerhaft, auch im Leerlauf. Die fünf Sekunden für den Aufweckdialog waren
rund zwanzig solcher Durchgänge - meine bisherigen Erklärungen (Fades,
Scrims) waren Symptome, nicht die Ursache.
Grund: zwei Durchgänge durch je 2,7 MB PSRAM pro Bild. LVGL rendert in einen
eigenen Draw-Buffer, esp_lcd_panel_draw_bitmap kopiert ihn danach komplett
in den Framebuffer.
WS7_DIRECT_FB holt den Framebuffer über esp_lcd_dpi_panel_get_frame_buffer
und übergibt ihn als LVGL-Draw-Buffer. Der IDF-Treiber erkennt das
(draw_buffer im Framebuffer-Bereich) und macht nur noch Cache-Writeback statt
Kopie; dazu LV_DISPLAY_RENDER_MODE_DIRECT, sodass nur geänderte Bereiche neu
gezeichnet werden.
Außerdem:
- Shot-Timer und Waage behalten während eines Bezugs die normale Schrift;
der Wechsel auf den fetten 96er ist entfernt.
- Größe der Standby-Uhr einstellbar (120/180/240 px, Info-Seite,
NVS ui/uhrgr). Wirkt sofort - sie hängt an einem einzigen Label.
- Die Knöpfe des Aufweckdialogs skalieren mit der Schriftgröße.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Aufweckdialog braucht weiterhin ~5 s. Zwei Erklärungsversuche lagen
daneben (Fade-Animationen, transparenter Scrim), also wird ab jetzt
gemessen statt geraten.
- refr_monitor_install() hängt sich über LV_EVENT_REFR_START/READY an die
Anzeige und meldet jeden Zeichenzyklus, der 200 ms überschreitet. Im
Normalbetrieb bleibt die Konsole still.
- Der Aufweckdialog berücksichtigt die Schriftgröße jetzt vollständig:
Knöpfe mit font_text() statt geerbter Grundschrift, Breite 150/210/280 je
Stufe. Bisher wirkten sie neben dem größeren Text verloren.
- Die große Standby-Uhr bleibt bewusst fest: Sie ist auf die Bildschirmhöhe
abgestimmt.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ
Vom Fingertipp auf die Standby-Uhr bis zum Dialog vergingen ~5 s mit
schwarzem Bildschirm. Ursache war der Scrim mit LV_OPA_70 über den ganzen
Bildschirm: Ein durchscheinender Vollbild-Layer zwingt LVGL zu einem
Zwischenpuffer und zum Mischen der gesamten Fläche - bei 1280x720 in 24 Bit
die teuerste Operation überhaupt.
- Wake-Scrim auf WS_PANEL_7H jetzt LV_OPA_COVER. Verloren geht nichts: Im
Standby liegt dahinter ohnehin nur Schwarz.
- Der Drawer-Scrim (LV_OPA_50) hat dasselbe Problem und ist ebenfalls
deckend, in 0x0d0d0d - auf dunklem Grund optisch praktisch identisch.
- Die JC-Panels behalten in beiden Fällen die Transparenz.
- Die Dialogkarte wächst mit der Schriftgröße (420 / 640 / 900 px), damit
der Text nicht an unglücklichen Stellen umbricht.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ
Die Uhrzeit kommt von der Hauptplatine und ist leer, solange dort keine
Zeitquelle synchronisiert ist. Bei einem erneuten Abgleich ist sie kurz weg,
und die Uhr verschwand für ein paar Sekunden - im Standby unruhig.
Der P4 merkt sich jetzt die zuletzt empfangene Zeit (Minuten seit
Mitternacht plus lv_tick zum Empfangszeitpunkt) und rechnet zwischen den
Meldungen selbst weiter. Sobald die S3 wieder eine Zeit schickt, gilt deren
Wert - der P4 stellt nichts richtig und ersetzt keine Zeitquelle, er
überbrückt nur die Lücke. Ohne je empfangene Zeit bleibt die Anzeige leer
wie bisher.
Gilt für die Kopfleisten-Uhr und die große Standby-Uhr; beide setzen den
Text jetzt über label_set_if_changed, sparen also unnötige Neuzeichnungen.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ
- Die ~2 s Verzögerung rund um den Standby lag nicht an der Helligkeit:
lv_obj_move_foreground(g_standbyScreen) lief bei JEDER Zustandsmeldung.
Das ordnet die Ebenen neu und lässt LVGL den ganzen Bildschirm neu
zeichnen - einmal pro Sekunde, 1280x720 in 24 Bit. Nach vorn geholt wird
die Uhr jetzt nur beim Einblenden.
- Der Aufweckdialog schließt sich nach 30 s ohne Auswahl selbst und wird wie
Abbrechen gewertet (lv_timer, repeat_count 1). Sonst bliebe das Display
hell stehen, weil der Dialog auf normale Helligkeit schaltet.
- Die Verlaufskurve hat keinen eigenen Hintergrund mehr. Die abgesetzte
Fläche war nur nötig, solange die Kurve vor dem ersten Messwert leer war -
seit sie beim aktuellen Wert startet, ist immer eine Linie da.
- Statistik: Bei fehlendem Gewicht stand ein En-Dash, den der Zeichensatz
nicht enthält - erschien als leeres Rechteck. Jetzt ASCII-Bindestrich.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ
- Standby-Uhr und Aufweckdialog kamen spürbar verzögert. Ursache waren die
Fade-Animationen: Eine Deckkraft-Animation ist bei einem Bildspeicher in
RGB888 das Teuerste überhaupt, weil pro Einzelbild die ganze Fläche unter
der Ebene neu gezeichnet und gemischt werden muss. UI_FADE_MS ist für
WS_PANEL_7H auf 0; ui_fade_in/ui_fade_out_hide zeigen bzw. verstecken dann
direkt. Die JC-Panels behalten die Animation.
- Beim Wechsel der Schriftgröße blitzte Blau auf. Das ist das Panel selbst -
ohne Videosignal zeigt es Blau, und der nötige Neustart reißt das Signal
ab. hal_backlight(0) vor esp_restart().
- Neue Einstellung "Temperaturzahl in der Zustandsfarbe" (Info-Seite,
Abschnitt Darstellung, NVS ui/tempcol, Vorgabe aus). Aus bleibt die Zahl
weiß; die Zustandsfarbe steckt dann allein im Balken. Warnungen bleiben
immer rot.
Beide Panel-Varianten mit arduino-cli gegengebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STPpZoK3ToDhrcniVqE6MJ