Everything a user sees or reads is now English: both boards' labels, status replies and logs, the ESP Screens editor and Alerts cheatsheet, and the README and guides (docs/TILES.md, CALIBRATING.md, ACCEPTANCE.md and TROUBLESHOOTING.md replace the Dutch file names). Labels follow Home Assistant's own English names (Heat/Cool modes, Heating/Cooling actions, Away, Returning to dock, weather conditions), dates use English abbreviations and the top bar writes numbers the English way. Docs use HA 2026.9's menu names (Settings -> Apps, App store, Settings -> Tools). Unused legacy files (home-like.yaml, buttons.yaml, a.out) are removed. Firmware 0.2.34 names its entities in English. Home Assistant registers a renamed ESPHome entity under a new entity ID, so the inbox text.<screen>_tegelinstellingen becomes text.<screen>_tile_settings and the layout stored under the old ID would be lost. The manager now recognises the screen by its device, during a run or after a restart, and moves its layout and update history along; the Update button and the nightly round follow the screen through the rename. Screens that still run 0.2.33 or older keep working: both languages are matched. Main is the only release branch from now on. Tested on a Home Assistant Yellow (HA 2026.9.1) with both bench boards: see docs/TEST_RESULTS_0240.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.4 KiB
Historical investigation on a single panel. For a new screen, see README.md and the five-point calibration; don't reuse these measurements.
ESP32-2432S028: stable operation
Use home-like-2432s028.yaml for the connected 2.8-inch CYD with
ILI9341 and XPT2046. The Wi-Fi, API, and OTA secrets stay in secrets.yaml.
Operation
- Set
TILE_COUNTto the number of tiles in use (1–10). With six tiles or fewer, both page buttons and the page indicator disappear; higher tile numbers stay hidden. - Page 1 holds tiles 1–6; page 2 holds 7–10. Use the Previous and Next buttons at the bottom. Swiping is disabled.
- A short tap runs the tile's existing action. A long press opens the existing light, climate, or vacuum card, or the configured long-press action.
- Standby starts after ten minutes without touch (
AUTO_DIM_TIMEOUT: "600"). - The first tap on the dimmed screen wakes the screen.
- Contacts shorter than
TOUCH_MIN_PRESS_MS(60 ms on the CYD, 20 ms on the Guition) are ignored. One touch can produce at most one tile action; a movement greater thanTOUCH_MOVE_LIMIT_PX(56 px, about 1 cm, on the CYD; 0 on the Guition: no limit, LVGL decides and releasing inside the tile counts) relative to the settled first contact point cancels the tap; only the first contact counts; the same tile is protected against contact bounce for 600 ms. A rejected tap is logged with its reason (tagtouch). - The thermostat sends the rounded, clamped temperature it displays. A local temperature or mode choice gets three seconds to sync with HA. An active control press prevents automatic dimming.
- Pippa uses the real
vacuum.s8status, so docking, cleaning, pausing, and returning are distinguished. Missing HA states are shown asUnavailable.
Technical choices
ESPHome 2026.6.2 with ESP-IDF; no Arduino components are needed.
The display bus runs at 40 MHz, like ESPHome's standard CYD profile.
XPT2046 is polled every 20 ms without the GPIO36 interrupt. The pressure
threshold is 800, after a suspect corner reading at pressure 422. A local XPT2046
driver requires three consistent ADC samples for a new touch, ignores isolated
outliers, and waits for two pressure-free samples before release. This adds about
40–60 ms on touch and prevents an unstable first reading from being immediately
interpreted as a different button. The driver lives under components/. The stock
interrupt driver tries to enable an unavailable internal pull-up on that
input-only pin; the old firmware logged a GPIO error for this.
LVGL gets a 12% draw buffer. No scroll animations and no extra flash pulse after
each tap. Tile backgrounds are opaque. Updates within 100 ms are
coalesced; unchanged tile labels and colors are not redrawn.
UI initialization only runs after LVGL has started. The clock refreshes immediately
on time sync. Roboto is bundled locally in fonts/, including the OFL license.
The active layout is 320×240. The old, commented-out portrait presets are not adapted page layouts yet: with a different orientation, also reserve 34 pixels at the bottom for navigation and check the tile positions.
Building and flashing
esphome compile home-like-2432s028.yaml
esphome upload home-like-2432s028.yaml --device /dev/cu.usbserial-130
esphome logs home-like-2432s028.yaml --device /dev/cu.usbserial-130
Close any running serial log reader before flashing. The previous configuration
is stored locally in diagnostics/before-2432s028.yaml.bak; the corresponding previous
factory binary is in diagnostics/before-2432s028.factory.bin. These local backups
are not included in Git. You can roll back by restoring the backup as the configuration
and rebuilding/flashing; restore the old Arduino toolchain
if you build the old configuration.
Tests
clang++ -std=c++17 -Wall -Wextra -Werror tests/test_cyd_ui.cpp -o /tmp/test_cyd_ui
/tmp/test_cyd_ui
python3 tests/test_layout.py
clang++ -std=c++17 -Wall -Wextra -Werror tests/test_touch_filter.cpp -o /tmp/test_touch_filter
/tmp/test_touch_filter
The C++ test checks contact bounce, short noise pulses, consecutive tiles,
repetition within a single touch, millis() overflow, and temperature rounding.
The layout test checks overlap, screen bounds, space for navigation,
and the filter ahead of both handlers for all ten tiles.
With ESPHome's Python environment (with aioesphomeapi, PyYAML, and pyserial):
python diagnostics/capture_serial.py --reset --seconds 120 > diagnostics/runtime.log
python diagnostics/run_ui_test.py --host cyd-2432s028.local
The API test reads the encryption key internally from secrets.yaml and doesn't
print it. It switches pages ten times and draws the five overlays on each
round. It doesn't call any Home Assistant actions. Don't touch the screen during
these roughly 11 seconds. This is a rendering/memory test; it doesn't replace
a physical check of the touch calibration or a test of HA service effects.
Diagnostics logs free heap and the largest free memory block every 30 seconds.
DEBUG is useful temporarily for touch and connection diagnostics. For everyday
use, logger.level can go back to INFO once physical operation is confirmed good.
Touch diagnostics
python diagnostics/control_ui.py touch_diagnostics opens a separate screen
with four crosshairs. During this measurement, touches can't trigger a tile
action. Tap accurately, in order: top-left, top-right,
bottom-right, and bottom-left. The raw and normalized coordinates appear in
the serial logs with tag touch. Exit with
python diagnostics/control_ui.py end_touch_diagnostics. The crosshairs sit
at (20,20), (299,20), (299,219), and (20,219) for 320×240 landscape.
The current calibration (X 225–3800, Y 274–3609) is derived from the three repeated measurements at top-right and bottom-left on this physical board. The earlier top-left measurements were unstable and were deliberately not used, to avoid shifting the entire screen to the wrong position.
On top of that, set_raw_correction(...) in on_boot corrects the measured
skew. The fit uses the filtered corner medians (830,556), (544,3461),
(3410,3391), and (3492,372). After correction, the four medians land within five
pixels of their measurement target in the regression test. These are board-specific
coefficients; don't carry them over blindly to another panel. The raw= logs
still show the physical, filtered ADC readings.