Compare commits

...
Author SHA1 Message Date
raw-designsandClaude Opus 5 5df6c20171 fix(P4): Endlose Neustartschleife nach Kaltstart (1.9.11)
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
2026-09-03 15:08:40 +02:00
thomas 7d7893cf08 Merge pull request 'diag(P4): Touch-Rohwerte vermessen, einheitliche Zeitbasis (1.9.10)' (#79) from diag/touch-rohwerte-und-zeitbasis into main 2026-09-03 13:52:10 +02:00
raw-designsandClaude Opus 5 db707ffd8c diag(P4): Touch-Rohwerte vermessen, einheitliche Zeitbasis (1.9.10)
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
2026-09-03 13:51:48 +02:00
thomas 9eb386095d Merge pull request 'fix(P4): Kachelhöhe beim Bezug halten, Messzeilen mit Zeitmarke (1.9.9)' (#78) from fix/kachelhoehe-und-zeitmarken into main 2026-09-03 13:38:36 +02:00
4 changed files with 68 additions and 18 deletions
+21
View File
@@ -1,3 +1,24 @@
Version 1.9.11:
- Endlose Startschleife behoben: Beleuchtung an, nie ein Bild. Der P4 startet sich nach dem
Einschalten absichtlich einmal neu, weil das Panel sonst schwarz bleibt. Die Absicherung
dagegen verließ sich darauf, dass der zweite Start kein Kaltstart mehr ist - der Chip
meldet aber auch nach dem selbst ausgelösten Neustart wieder einen Kaltstart. Damit griff
die Bedingung erneut, endlos.
- Der Neustart wird jetzt vermerkt und beim zweiten Durchlauf erkannt, unabhängig davon, was
der Chip als Startgrund meldet. Beim nächsten echten Einschalten erfolgt wieder genau ein
Neustart.
- Die Meldung über diesen Neustart lief bisher über die USB-Verbindung und war im seriellen
Monitor nicht zu sehen - deshalb war von der Schleife nichts zu erkennen. Sie läuft jetzt
denselben Weg wie die übrigen Panel-Meldungen.
Version 1.9.10:
- Alle Messzeilen laufen jetzt auf derselben Uhr. Die des Zeichenablaufs startete später als
die des Hauptablaufs; die Zeiten ließen sich nur mit Umrechnung vergleichen.
- Der Touch meldet jetzt, wenn er Rohwerte verwirft, weil sie außerhalb des gültigen
Bereichs liegen, und nennt bei jeder erkannten Berührung, wie viele vorher verworfen
wurden. Eine Berührung, deren Rohwerte lange verworfen werden, sieht von außen genauso aus
wie ein Display, das nicht reagiert - das war bisher nicht zu unterscheiden.
Version 1.9.9:
- Die kleinen Kacheln unten im Dashboard behalten beim Bezug ihre Höhe. Bisher bekam die
untere Zeile während des Bezugs deutlich mehr Platz - die Kacheln wurden enorm hoch und
+28 -11
View File
@@ -336,19 +336,36 @@ void setup() {
// nicht (siehe WS7_DSI_RESTART).
//
// Deshalb startet der P4 sich nach einem Kaltstart genau einmal selbst neu, nachdem
// der erste Hochlauf durch ist. Beim zweiten Durchlauf ist der Startgrund kein
// Kaltstart mehr, die Bedingung greift also nicht erneut - eine Schleife ist
// ausgeschlossen. Kostet rund drei Sekunden, aber nur beim Einschalten.
// der erste Hochlauf durch ist. Kostet rund drei Sekunden, aber nur beim Einschalten.
//
// Frueher stuetzte sich die Absicherung dagegen allein auf den Startgrund: Beim zweiten
// Durchlauf sei es kein Kaltstart mehr, eine Schleife also ausgeschlossen. Das stimmt
// nicht - der Chip meldet auch nach dem selbst ausgeloesten Neustart wieder einen
// Kaltstart, und dann startet er endlos neu. Genau das ist aufgetreten: Beleuchtung an,
// nie ein Bild. Deshalb wird jetzt zusaetzlich vermerkt, dass der Neustart schon
// stattgefunden hat; darauf ist Verlass, unabhaengig vom gemeldeten Startgrund.
#if (JC_PANEL_TYPE == WS_PANEL_7H) && WS7_COLD_BOOT_RESTART
if (esp_reset_reason() == ESP_RST_POWERON) {
// Der Fruehstart-Zaehler wurde oben bereits erhoeht. Diesen gewollten Neustart
// darf er nicht mitzaehlen, sonst laeuft die Absturzsicherung nach ein paar
// Einschaltvorgaengen in den Update-Modus.
{ Preferences p; p.begin("bootguard", false); p.putUShort("early", 0); p.end(); }
DBG_SERIAL.println(F("[Panel] Kaltstart - einmaliger Neustart fuer das Displaypanel"));
DBG_SERIAL.flush();
delay(50);
esp_restart();
Preferences p;
p.begin("bootguard", false);
bool schonNeugestartet = p.getUChar("kaltneu", 0) != 0;
if (schonNeugestartet) {
// Zweiter Durchlauf: Vermerk loeschen, damit beim naechsten echten Einschalten
// wieder genau ein Neustart erfolgt.
p.putUChar("kaltneu", 0);
p.end();
esp_rom_printf("[Panel] Neustart bereits erfolgt - Hochlauf wird fortgesetzt\n");
} else {
p.putUChar("kaltneu", 1);
// Der Fruehstart-Zaehler wurde oben bereits erhoeht. Diesen gewollten Neustart
// darf er nicht mitzaehlen, sonst laeuft die Absturzsicherung nach ein paar
// Einschaltvorgaengen in den Update-Modus.
p.putUShort("early", 0);
p.end();
esp_rom_printf("[Panel] Kaltstart - einmaliger Neustart fuer das Displaypanel\n");
delay(50);
esp_restart();
}
}
#endif
g_client.begin(); // UART starten, hello folgt automatisch in loop()
+13 -1
View File
@@ -310,14 +310,26 @@ static bool ws7_touch_get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y
bool got = s_touch_get_xy_orig(tp, x, y, strength, point_num, max_point_num);
int64_t now = esp_timer_get_time();
// Unplausible Rohwerte gelten als Aussetzer, nicht als Beruehrung.
// Unplausible Rohwerte gelten als Aussetzer, nicht als Beruehrung. Wie viele davon
// anfallen, war bisher nirgends zu sehen - eine Beruehrung, deren Rohwerte lange
// verworfen werden, sieht von aussen wie ein Display aus, das nicht reagiert.
static uint32_t s_verworfen = 0;
if (got && *point_num > 0 &&
(x[0] > WS7_TOUCH_RAW_X_MAX || y[0] > WS7_TOUCH_RAW_Y_MAX)) {
if (s_verworfen == 0)
esp_rom_printf("[Touch] %u ms: Rohwert verworfen (x %u, y %u liegen ausserhalb)\n",
(unsigned)(now / 1000), (unsigned)x[0], (unsigned)y[0]);
s_verworfen++;
got = false;
*point_num = 0;
}
if (got && *point_num > 0) {
if (!s_touch_down)
esp_rom_printf("[Touch] %u ms: Beruehrung erkannt bei x %u, y %u; %u Rohwerte vorher verworfen\n",
(unsigned)(now / 1000), (unsigned)x[0], (unsigned)y[0],
(unsigned)s_verworfen);
s_verworfen = 0;
s_touch_last_x = x[0];
s_touch_last_y = y[0];
s_touch_last_us = now;
+6 -6
View File
@@ -932,11 +932,11 @@ static bool wake_choice_offered() {
}
static void standby_screen_cb(lv_event_t*) { // Tipp auf Standby-Uhr -> nachfragen
// Vermessen: Vom Tippen bis zur sichtbaren Rueckfrage vergehen rund fuenf Sekunden.
uint32_t t0 = lv_tick_get();
uint32_t t0 = millis();
esp_rom_printf("[Touch] %u ms: Tipp auf die Standby-Uhr erkannt\n", (unsigned)t0);
wake_confirm_show();
esp_rom_printf("[Touch] %u ms: Rueckfrage aufgebaut, brauchte %u ms\n",
(unsigned)lv_tick_get(), (unsigned)(lv_tick_get() - t0));
(unsigned)millis(), (unsigned)(millis() - t0));
}
static void wake_cancel() { // Abbrechen -> zurueck in die Standby-Helligkeit
wake_timeout_stop();
@@ -3563,7 +3563,7 @@ static void refr_ready_cb(lv_event_t*) {
uint32_t d = lv_tick_get() - g_refrStart;
if (d < REFR_WARN_MS) return;
unsigned pct = (unsigned)((uint64_t)g_refrPixels * 100ULL / ((uint64_t)LCD_H_RES * LCD_V_RES));
esp_rom_printf("[UI] %u ms: Bildaufbau %u ms, %u Bereiche, %u %% der Flaeche\n", (unsigned)lv_tick_get(),
esp_rom_printf("[UI] %u ms: Bildaufbau %u ms, %u Bereiche, %u %% der Flaeche\n", (unsigned)millis(),
(unsigned)d, (unsigned)g_refrAreas, pct);
// Lage der Bereiche mit ausgeben. Erst daran ist zu erkennen, WELCHER Teil der
// Oberflaeche das Neuzeichnen ausloest - die Groesse allein sagt das nicht.
@@ -3576,7 +3576,7 @@ static void refr_ready_cb(lv_event_t*) {
static void ui_heartbeat_cb(lv_timer_t*) {
lv_mem_monitor_t m; lv_mem_monitor(&m);
esp_rom_printf("[UI] %u ms: Herzschlag, LVGL-Speicher frei %u von %u Byte, groesster Block %u\n",
(unsigned)lv_tick_get(), (unsigned)m.free_size, (unsigned)m.total_size,
(unsigned)millis(), (unsigned)m.free_size, (unsigned)m.total_size,
(unsigned)m.free_biggest_size);
}
@@ -4220,11 +4220,11 @@ void ui_update(const MachineState& st) {
// 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();
uint32_t t0 = millis();
ui_fade_in(g_standbyScreen, UI_FADE_MS); // Einschlaf-Animation
g_standbyShown = true;
esp_rom_printf("[UI] Standby-Uhr eingeblendet, %u ms\n",
(unsigned)(lv_tick_get() - t0));
(unsigned)(millis() - t0));
}
// Frueher wurde die Uhr hier bei JEDER Zustandsmeldung nach vorn geholt. Das
// ordnet die Ebenen neu und laesst LVGL den gesamten Bildschirm neu zeichnen -