Ohne aktive und verbundene Waage greifen weder das Zielgewicht noch die Stillstands-Erkennung — der Bezug endet dann erst nach der maximalen Bezugsdauer, die damit faktisch zur Dosierung wird. Bisher passierte diese Degradierung stillschweigend. Die Funktion bleibt ohne Waage bewusst nutzbar (Zeitsteuerung als Rückfallebene), damit ein kurzzeitig abgemeldeter HX711 die kalte Extraktion nicht komplett blockiert. Angezeigt wird der Zustand jetzt an vier Stellen: dauerhafter Warnhinweis auf /Brew-Control (Zielgewicht-Feld zusätzlich als "nur mit Waage wirksam" beschriftet), Hinweiszeile unter dem Dashboard-Schalter, Statustext "Cold Extraction bereit (ohne Waage: Zeitsteuerung)" und eine einmalige Meldung beim Aktivieren. P4: Statuszeile zeigt "ohne Waage, Ende nach Zeit" in Warnfarbe statt des blauen Normalhinweises; Erklärzeile am Schalter und Parameter-Anzeige auf der Brew-Seite ergänzen den Hinweis und nennen bei aktivem Modus ohne Waage die Zeit statt des Zielgewichts. Neuer cxNotice-Code 4 (additiv, Protokoll bleibt v2). 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!