Der Aufweck-Dialog am Touch-Display wird zur Auswahl: "Womit aufwecken?" mit
"Espresso" (heizt normal auf) und "Cold Extraction (Wasser bleibt kalt)". Damit
lässt sich bei jedem Aufwecken neu entscheiden, ohne vorher die Web-UI zu bedienen.
Bei der kalten Variante wird der Modus scharf geschaltet, bevor der Standby endet —
der Wasserkreis heizt also gar nicht erst an.
Abschaltbar über die neue Einstellung "Abfrage beim Aufwecken" (EEPROM 982), zu
finden auf /Cold-Extraction und auf der Cold-Extraction-Seite des Displays. Ist sie
aus, erscheint wieder der bisherige Dialog. Ohne angeschlossenes Display oder bei
nicht freigeschalteter Funktion hat sie keine Wirkung. Neues Feld cxAskOnWake im
State und in saveBrew.
Dazu: Die Meldungstexte der kalten Extraktion sind jetzt mit echten Umlauten
geschrieben ("nicht möglich" statt "nicht moeglich"). Für das OLED übersetzt die
neue Hilfsfunktion oledUmlauts() sie beim Rendern nach CP437 — dort hätte UTF-8
sonst zwei Fehlzeichen je Umlaut ergeben, weshalb die Texte ursprünglich
transliteriert waren. Web-UI und Touch-Display stellen UTF-8 direkt dar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JC4880P443C-I-W — Touch-Display-Firmware (ESP32-P4)
Client-Firmware für das Guition-Smart-Display JC4880P443C-I-W, die als UART-Touch-Bedienung für die Dual-PID-Siebträgersteuerung dient.
Die Hauptplatine (ESP32-S3, Dual_PID_FastHeatUp.ino) bleibt die Steuerzentrale
inkl. WLAN/Webinterface. Dieses Display ist ein reiner UART-Client: es empfängt den
Zustand und sendet Bedienkommandos. Protokoll: siehe
../Doku/JC-Display_UART-Protokoll.md.
Hardware (laut Vendor-Paket im Ordner JC4880P443C_I_W/)
| Komponente | Bauteil / Pin |
|---|---|
| Haupt-MCU (UI) | ESP32-P4 |
| WLAN/BT (hier ungenutzt) | ESP32-C6 |
| Display | ST7701, 480×800 IPS, MIPI-DSI |
| Touch | GT911, I²C SDA=GPIO7 / SCL=GPIO8 |
| Backlight | GPIO23 (LEDC-PWM) · LCD-Reset GPIO5 |
| Freie Expansion-IO (JP1) | GPIO 52/51/50/49/35/34/33/32/31/30/29/28, ES_I2C, +3V3/+5V/GND |
Verkabelung zur Hauptplatine (UART, gekreuzt)
Pins aus dem Expand-IO-Header JP1 (Schaltplan JC4880P443C_I_W/5-Schematic/4_USB&IO.png):
S3 GPIO43 (TX) ----> P4 GPIO31 (RX) (DISPLAY_UART_RX_PIN)
S3 GPIO44 (RX) <---- P4 GPIO33 (TX) (DISPLAY_UART_TX_PIN)
S3 GND ------ P4 GND
Die rechte JP1-Spalte (
C6_U01TXD/C6_I10RXD/…) gehört zum ESP32-C6 — nicht verwenden. 3,3-V-Logik beidseitig → keine Pegelwandlung nötig.
Projektstruktur (eigener Code)
| Datei | Zweck |
|---|---|
JC_Display_Firmware.ino |
setup()/loop(), verdrahtet die Module |
config.h |
Pins, UART, Protokoll-Parameter |
machine_state.h |
Spiegel des state-Objekts der S3 |
protocol_client.h/.cpp |
UART-Protokoll: hello/state/ack/profiles/… + Heartbeat |
ui.h/.cpp |
LVGL-Dashboard (hardwareunabhängig) |
display_hal.h/.cpp |
LVGL-/UI-Verdrahtung + Lock-Wrapper |
board_bringup.c |
esp_lcd-Hardware-Bringup (C; nur bei JC_USE_REAL_PANEL=1) |
Abhängigkeiten
- Arduino-ESP32 ≥ 3.1 (mit ESP32-P4-Support), Board: ESP32P4 Dev Module, PSRAM aktiviert.
- LVGL 9.x +
lv_conf.h. Tipp: dielv_conf.haus dem Vendor-Beispiel (JC4880P443C_I_W/1-Demo/arduino_examples/lvgl_v9_sw_rotation/lv_conf.h) übernehmen undLV_FONT_MONTSERRAT_40aktivieren (große Temperaturanzeige). - ArduinoJson 7.x.
Zwei Betriebsmodi (JC_USE_REAL_PANEL in display_hal.h)
0 = Stub-Modus (Standard)
Kompiliert ohne Display-Treiber (eigenes Minimal-LVGL, rendert ins Leere). Ideal, um
Protokoll/UART/Logik am Schreibtisch zu testen (Debug über USB-CDC Serial). Läuft auf
jedem ESP32 mit LVGL+ArduinoJson.
1 = echte Hardware (Hersteller-BSP)
display_hal.cpp baut auf der erprobten Hersteller-Portierung auf. Dazu folgende
Dateien aus JC4880P443C_I_W/1-Demo/arduino_examples/lvgl_v9_sw_rotation/ in diesen
Sketch-Ordner kopieren:
pins_config.h
lvgl_port_v9.h
lvgl_port_v9.c
src/lcd/ (komplett: esp_lcd_st7701*.c/.h, st7701_lcd.*)
src/touch/ (komplett: esp_lcd_touch*.c/.h, gt911_touch.*)
Der Init-Ablauf (MIPI-DSI-PHY-LDO, ST7701, GT911, LEDC-Backlight, lvgl_port_init) ist
1:1 aus dem Vendor-Beispiel lvgl_sw_rotation.c übernommen — nur der Demo-Aufruf
(lv_demo_widgets()) wurde durch ui_init() ersetzt.
Wichtig: Im realen Modus läuft LVGL in einem eigenen FreeRTOS-Task. UI-Zugriffe aus
der Arduino-loop() (z. B. ui_update bei jedem state-Push) sind daher in
hal_lock()/hal_unlock() (= lvgl_port_lock/unlock) gekapselt — ist in der .ino
bereits umgesetzt.
Ausrichtung
Das Vendor-Beispiel nutzt 90° (Querformat 800×480). Das hiesige Dashboard ist für
Hochformat 480×800 ausgelegt → in pins_config.h
EXAMPLE_LVGL_PORT_ROTATION_DEGREE_ auf 0 setzen (oder das UI-Layout in ui.cpp auf
Querformat anpassen).
Status
Fertig & hardwareunabhängig:
- Vollständiger UART-Protokoll-Client (v2): hello-Handshake, state-Parsing, ack/error, Profile, Heartbeat, Link-Timeout.
- Dashboard: Live-Temperaturen Wasser/Dampf (ist/soll), Duty-Balken, Status-Banner
(Farbe nach
statusKey), Verbindungs- & WLAN-Anzeige, Bezugs-Timer, Bedien-Buttons. - Senden für
setPid,startAutotune/stopAutotune,getProfileDetailsvorhanden.
Board-Bringup: auf die konkreten JC-Pins/Treiber gesetzt (ST7701/GT911, Backlight,
I²C) — sobald die BSP-Dateien kopiert und JC_USE_REAL_PANEL=1 gesetzt ist, lauffähig.
Noch offen (UI-Ausbau): weitere Screens — Einstellungen (Brew/Service/Sensor), Profil-Auswahl/-Editor, PID/AutoTune-Bedienung.
Inbetriebnahme / Fehlersuche (Lessons learned)
- Stromversorgung: Jedes Board eigene Versorgung. Zwischen P4 und S3 nur GND + TX + RX — kein 3V3/5V! Den S3 nicht über den 3V3-Header des Displays speisen (reicht nicht / Regler-Rückspeisung).
- Pins nach Silkscreen: Die UART-Pads am Board nach Aufdruck
GPIO50/GPIO51identifizieren, nicht nach Header-Pin-Nummern. - S3-Seite: muss mit
TOUCH_UART_ENABLED 1geflasht sein und laufen. DaSerial(Debug) und der Touch-UART beide auf GPIO43/44 liegen, ggf. „USB CDC On Boot: Enabled" verwenden, damit der Debug-Port nicht die UART-Pins blockiert.
Diagnose-Schalter (in config.h)
SHOW_DEBUG_OVERLAY 1→ blendet unten ein grünes Panel ein: gesendetehello, empfangene Bytes/Zeilen, Parse-Fehler, letzte Rohzeile, Link-Status.UART_SELFTEST_INTERNAL_LOOPBACK 1→ legt TX chip-intern auf RX (ohne Draht/Pins). Läuft „RX byte" hoch, sind Firmware+UART ok → Problem liegt an Pins/Verkabelung. Nach dem Test wieder auf 0!