diag(P4): Messpunkte für den Stillstand beim Standby-Wechsel (1.9.7)
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
This commit is contained in:
co-authored by
Claude Opus 5
parent
06d9710b16
commit
0ec3d89973
@@ -1,3 +1,16 @@
|
|||||||
|
Version 1.9.7:
|
||||||
|
- Messpunkte für den Stillstand beim Wechsel in den Standby: Beide Abläufe - der Haupt- und
|
||||||
|
der Zeichenablauf - melden jetzt alle zwei Sekunden einen Herzschlag mit Speicherstand.
|
||||||
|
Bleibt nur einer von beiden aus, ist klar, welcher stehen bleibt.
|
||||||
|
- Das Einblenden der Standby-Uhr meldet Anfang und Ende mit Dauer. Bleibt die zweite Meldung
|
||||||
|
aus, hängt es genau dort.
|
||||||
|
- Jeder Helligkeitswechsel, der länger als 50 ms braucht, wird mit seiner Dauer gemeldet. Der
|
||||||
|
Schreibzugriff geht über denselben Bus wie der Touch - ein Verdacht für die bekannte
|
||||||
|
Verzögerung von ein bis zwei Sekunden.
|
||||||
|
- Die Rückmeldung aus 1.9.5, die einen komplett ungültigen Inhaltsbereich melden sollte, ist
|
||||||
|
wieder entfernt. Sie konnte nie auslösen: LVGL schickt diese Meldung an das Display, nicht
|
||||||
|
an einzelne Elemente. Ihr Ausbleiben war also kein Beweis.
|
||||||
|
|
||||||
Version 1.9.6:
|
Version 1.9.6:
|
||||||
- Die Darstellungseinstellungen haben einen eigenen Menüpunkt „Darstellung" bekommen. Sie
|
- Die Darstellungseinstellungen haben einen eigenen Menüpunkt „Darstellung" bekommen. Sie
|
||||||
standen bisher oben auf der Info-Seite, zwischen Sachen, mit denen sie nichts zu tun
|
standen bisher oben auf der Info-Seite, zwischen Sachen, mit denen sie nichts zu tun
|
||||||
|
|||||||
@@ -67,11 +67,25 @@ static void onState(const MachineState& st) {
|
|||||||
}
|
}
|
||||||
if (bl < 0) bl = 0; if (bl > 100) bl = 100;
|
if (bl < 0) bl = 0; if (bl > 100) bl = 100;
|
||||||
if (bl != s_lastBacklight) {
|
if (bl != s_lastBacklight) {
|
||||||
|
// Vermessen: Rund um jeden Helligkeitswechsel hing die Bedienung bisher ein bis
|
||||||
|
// zwei Sekunden. Der Schreibzugriff geht ueber denselben I2C-Bus wie der Touch.
|
||||||
|
uint32_t t0 = millis();
|
||||||
hal_backlight(bl);
|
hal_backlight(bl);
|
||||||
|
uint32_t dt = millis() - t0;
|
||||||
|
if (dt > 50) Serial.printf("[HAL] Helligkeit %d %% gesetzt, %u ms\n", bl, (unsigned)dt);
|
||||||
s_lastBacklight = bl;
|
s_lastBacklight = bl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Herzschlag aus dem Haupt-Ablauf. Zusammen mit dem Herzschlag aus dem Zeichen-Ablauf
|
||||||
|
// laesst sich unterscheiden, welcher der beiden stehen bleibt, wenn nichts mehr geht.
|
||||||
|
static void main_heartbeat() {
|
||||||
|
static uint32_t s_last = 0;
|
||||||
|
if (millis() - s_last < 2000) return;
|
||||||
|
s_last = millis();
|
||||||
|
Serial.printf("[Haupt] Herzschlag, freier Speicher %u Byte\n", (unsigned)ESP.getFreeHeap());
|
||||||
|
}
|
||||||
|
|
||||||
static void onAck(uint32_t id, bool ok, const String& message) {
|
static void onAck(uint32_t id, bool ok, const String& message) {
|
||||||
// Automatische/Heartbeat-Acks nicht als Toast zeigen (pong, Handshake, Listen-Refresh).
|
// Automatische/Heartbeat-Acks nicht als Toast zeigen (pong, Handshake, Listen-Refresh).
|
||||||
bool routine = ok && (message == "pong" || message == "hello" ||
|
bool routine = ok && (message == "pong" || message == "hello" ||
|
||||||
@@ -332,6 +346,7 @@ static unsigned long s_lastDbgMs = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
main_heartbeat();
|
||||||
g_client.loop(); // UART lesen, hello/heartbeat, state -> UI
|
g_client.loop(); // UART lesen, hello/heartbeat, state -> UI
|
||||||
hal_loop(); // realer Modus: leer; Stub-Modus: lv_timer_handler()
|
hal_loop(); // realer Modus: leer; Stub-Modus: lv_timer_handler()
|
||||||
|
|
||||||
|
|||||||
@@ -3565,12 +3565,10 @@ static void refr_ready_cb(lv_event_t*) {
|
|||||||
(int)g_refrArea[i].y1, (int)g_refrArea[i].y2);
|
(int)g_refrArea[i].y1, (int)g_refrArea[i].y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meldet, wenn ein ganzer Container ungueltig gemacht wird. Damit laesst sich unterscheiden,
|
static void ui_heartbeat_cb(lv_timer_t*) {
|
||||||
// ob eine einzelne Beschriftung den Bildaufbau ausloest oder ob gleich der komplette
|
lv_mem_monitor_t m; lv_mem_monitor(&m);
|
||||||
// Inhaltsbereich neu gezeichnet werden soll - zwei verschiedene Ursachen.
|
esp_rom_printf("[UI] Herzschlag, LVGL-Speicher frei %u von %u Byte, groesster Block %u\n",
|
||||||
static void inval_watch_cb(lv_event_t* e) {
|
(unsigned)m.free_size, (unsigned)m.total_size, (unsigned)m.free_biggest_size);
|
||||||
const char* name = (const char*)lv_event_get_user_data(e);
|
|
||||||
esp_rom_printf("[UI] %s wird komplett ungueltig\n", name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void refr_monitor_install() {
|
static void refr_monitor_install() {
|
||||||
@@ -3984,8 +3982,7 @@ void ui_init(ProtocolClient* client) {
|
|||||||
if (g_client) g_client->sendListProfiles();
|
if (g_client) g_client->sendListProfiles();
|
||||||
|
|
||||||
refr_monitor_install();
|
refr_monitor_install();
|
||||||
if (g_content) lv_obj_add_event_cb(g_content, inval_watch_cb, LV_EVENT_INVALIDATE_AREA, (void*)"Inhaltsbereich");
|
lv_timer_create(ui_heartbeat_cb, 2000, nullptr);
|
||||||
if (g_pages[PG_DASH]) lv_obj_add_event_cb(g_pages[PG_DASH], inval_watch_cb, LV_EVENT_INVALIDATE_AREA, (void*)"Dashboard-Seite");
|
|
||||||
g_uiReady = true;
|
g_uiReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4175,8 +4172,14 @@ void ui_update(const MachineState& st) {
|
|||||||
if (shouldShow) {
|
if (shouldShow) {
|
||||||
label_set_if_changed(g_standbyClock, zeit.length() ? zeit.c_str() : "--:--");
|
label_set_if_changed(g_standbyClock, zeit.length() ? zeit.c_str() : "--:--");
|
||||||
if (!g_standbyShown) {
|
if (!g_standbyShown) {
|
||||||
|
// Vermessen: Das Einblenden der Uhr ist der Moment, in dem das Display
|
||||||
|
// zuletzt stehen geblieben ist. Bleibt die zweite Zeile aus, haengt es hier.
|
||||||
|
esp_rom_printf("[UI] Standby-Uhr wird eingeblendet\n");
|
||||||
|
uint32_t t0 = lv_tick_get();
|
||||||
ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation
|
ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation
|
||||||
g_standbyShown = true;
|
g_standbyShown = true;
|
||||||
|
esp_rom_printf("[UI] Standby-Uhr eingeblendet, %u ms\n",
|
||||||
|
(unsigned)(lv_tick_get() - t0));
|
||||||
}
|
}
|
||||||
// Frueher wurde die Uhr hier bei JEDER Zustandsmeldung nach vorn geholt. Das
|
// Frueher wurde die Uhr hier bei JEDER Zustandsmeldung nach vorn geholt. Das
|
||||||
// ordnet die Ebenen neu und laesst LVGL den gesamten Bildschirm neu zeichnen -
|
// ordnet die Ebenen neu und laesst LVGL den gesamten Bildschirm neu zeichnen -
|
||||||
|
|||||||
Reference in New Issue
Block a user