ESP32 Cheap Yellow Display (ESP32-2432S028) Home Assistant Touch Panel – LVGL UI + 3D Printed Desk / Under Desk / Wall / Flush Mounts
ESPHome powered Home Assistant control panel using the popular Cheap Yellow Display (ESP32-2432S028).
A 3D-printable enclosure with adjustable tilt for an ESP32 2.8" ILI9341 touchscreen, powered by ESPHome + LVGL and integrated with Home Assistant.
Includes ready-to-flash YAML configs for the ESP32-2432S028 (Cheap Yellow Display) and a standalone ILI9341 + external ESP32 wiring variant.
Multiple mounting options are supported:
- Desk Mount – for tabletop installation
- Under-Desk Mount – for installation underneath a desk or shelf
- Wall Mount – for wall installation (CYD version only)
- Flush Mount – for in-wall installation (EU electrical box compatible)
The enclosure can therefore be used as a compact Home Assistant control panel for desks, walls, or mounted underneath furniture.
The ESP32-2432S028 Cheap Yellow Display is transformed into a tiltable Home Assistant control panel powered by ESPHome and LVGL.
The goal of this project is to create a clean, wall- or desk-mounted smart control panel that integrates seamlessly with Home Assistant.
It features a modern LVGL-based UI, real-time state synchronization, and optional direct Home Assistant service calls.
The enclosure is designed for:
- Clean cable routing
- Adjustable viewing angle (±35° tilt)
- Minimal footprint
- Professional, integrated appearance
Two hardware variants are supported:
- ✅ ESP32-2432S028 (Cheap Yellow Display / CYD)
- ✅ Standalone ILI9341 + External ESP32 wiring variant
The ESP32-2432S028 integrates the ESP32, ILI9341 display, touchscreen controller, and backlight circuitry on a single board.
It is commonly known as the Cheap Yellow Display (CYD) in the maker community and is the easiest option for this project.
touch-display.mp4
Note: The video quality looks worse than in real life because the display refresh rate interferes with the camera frame rate when filming the screen. In reality the UI looks much smoother and cleaner.
This project uses ESPHome LVGL instead of a classic display lambda approach.
- UI rendered fully using LVGL widgets
- 4 configurable touch buttons
- Real-time state mirroring from Home Assistant
- Central
ui_refreshscript keeps UI synchronized - Optional direct Home Assistant service calls
- Action sensor for automation-based control
If DIRECT_ACTIONS is set to "true" (default):
- Touch publishes an action string
- AND directly calls a Home Assistant service
(default:light.toggle)
No Home Assistant automations required.
If DIRECT_ACTIONS is set to "false":
- Touch ONLY publishes an action string
- You implement behavior in Home Assistant automations
Trigger example:
Entity: sensor.smartdisplay_action
To: btn1_press
The UI contains a secondary overlay layer used for interactive controls.
When a tile is long-pressed:
- The overlay opens
- The control type is determined (brightness / percentage / cover position)
- Slider interaction updates Home Assistant
- Closing the overlay returns to the tile grid
This keeps the tile UI clean while still allowing detailed control.
- Home Assistant installed
- ESPHome Add-on installed
- ESPHome 2026.4+
- Home Assistant 2026.2+
- Basic ESPHome knowledge
- 3D printer access (optional)
This project was tested using:
- ESPHome 2026.2+
- Home Assistant 2026.2+
- ESP32-2432S028 (Cheap Yellow Display / CYD)
- ILI9341 + XPT2046 standalone wiring variant
Because this project uses:
homeassistant.action → light.toggle
You must allow the ESPHome device to perform Home Assistant service calls.
- Open Home Assistant
- Go to Settings
- Click Devices & Services
- Open the ESPHome integration
- Select your device
- Enable:
"Allow the device to perform Home Assistant actions"
Without this setting, direct control will not work.
- LVGL-based UI (lockscreen or tile layout depending on configuration)
- 2×3 configurable tile layout (home-like UI)
- Long-press per tile: value overlay (brightness / fan speed / cover position) or independent entity action
- Real-time state synchronization with Home Assistant
- Optional direct Home Assistant service calls
- Automation-based mode supported
- Adjustable 3D-printed enclosure
- Multiple mounting options: desk mount, under-desk mount, wall mount, and flush mount
- Hidden cable routing
- Works with CYD or external ESP32 wiring
| Part | Price | Comment |
|---|---|---|
| ESP32-2432S028 | 15$ | 2.8" ILI9341 with integrated ESP |
| 2x M4 3.5x16 screw (flathead) | 0.10$ | Screws to connect the mount case with the base |
Advantages:
- Single USB cable
- Clean installation
- No manual wiring
- Widely available under the name "Cheap Yellow Display"
| ESP32-2432S028 | PIN | Comment |
|---|---|---|
| LCD | ||
| clk_pin | GPIO14 | SPI LCD Clock |
| mosi_pin | GPIO13 | SPI LCD MOSI (sometimes also labeled as SDI) |
| miso_pin | GPIO12 | SPI LCD MISO (sometimes also labeled as SDO |
| cs_pin | GPIO15 | Display CS |
| dc_pin | GPIO2 | Display DC |
| Touchscreen | ||
| clk_pin | GPIO25 | SPI Touchscreen Clock |
| mosi_pin | GPIO32 | SPI Touchscreen MOSI (sometimes also labeled as DIN) |
| miso_pin | GPIO39 | SPI Touchscreen MISO (sometimes also labeled as DO) |
| cs_pin | GPIO33 | Touchscreen CS |
| interrupt_pin | GPIO36 | Touchscreen Interrupt |
| LED | ||
| ledc | GPIO21 | Backlight LED display |
| ledc | GPIO4 | Onboard LED (not used for this project) |
For the mount enclosure the side USB connector of the CYD is not used.
Instead the included power cable can be used.
The red and black wires provide 5V and GND and can easily be connected to an old USB-A cable.
Typical setup:
- Cut an old USB cable
- Connect 5V (red) and GND (black) to the CYD power cable
- Route the cable through the enclosure
- Solder or use small wire connectors
This keeps the enclosure compact and avoids having a visible or protruding USB connector on the side.
If the USB port was used directly, the enclosure would need to be wider or the connector would remain visible.
| Part | Price | Comment |
|---|---|---|
| 2.8" ILI9341 | 8$ | 2.8" ILI9341 |
| ESP32 Wroom 32D | 8$ | or some ESP32 |
| 2x M4 3.5x16 screw (flathead) | 0.10$ | Screws to connect the mount case with the base |
Requires manual wiring according to the YAML pin configuration.
Use the wiring table below, which shows how to put everything together.
| ILI9341 | PIN ESP32 | Comment |
|---|---|---|
| GND | GND | Ground |
| VCC | 3.3V | Power |
| LCD | ||
| SCK | GPIO18 | SPI LCD Clock |
| SDI (MOSI) | GPIO23 | SPI LCD MOSI (sometimes also labeled as SDI) |
| SDO (MISO) | GPIO19 | SPI LCD MISO (sometimes also labeled as SDO |
| CS | GPIO27 | Display CS |
| D/C | GPIO26 | Display DC |
| RESET | GPIO16 | Display Reset |
| Touchscreen | ||
| T_CLK | GPIO25 | SPI Touchscreen Clock |
| T_DO | GPIO35 | SPI Touchscreen MISO (sometimes also labeled as DO) |
| T_DIN | GPIO32 | SPI Touchscreen MOSI (sometimes also labeled as DIN) |
| T_CS | GPIO33 | Touchscreen CS |
| T_IRQ | GPIO34 | Touchscreen Interrupt |
| LED | ||
| ledc | GPIO4 | Backlight LED display |
- Open ESPHome in Home Assistant
- Create a new device
- Copy the appropriate YAML file
- Edit the USER CONFIG / substitutions section at the top of the YAML (entities, labels, icons)
- Copy
esphome/secrets.yaml.exampletosecrets.yamland fill in your credentials - Flash the device
Available YAML variants (pick one UI for your hardware):
esphome/home-like/cyd-2432s028/home-like.yaml– 2x3 “tiles” UI (wallpaper + tiles) — actively maintainedesphome/buttons/cyd-2432s028/buttons.yaml– lockscreen with 4 round buttons (simple / legacy)
esphome/home-like/ili9341-external-esp32/home-like.yaml– 2x3 “tiles” UI (wallpaper + tiles) — actively maintainedesphome/buttons/ili9341-external-esp32/buttons.yaml– lockscreen with 4 round buttons (simple / legacy)
Tip: The
home-like.yamlfile uses orientation-specific background images located inesphome/home-like/images/. For a full reference of all tile substitutions and copy-paste examples, seeesphome/home-like/TILE_CONFIGURATION.md. Two images are included:
smartdisplay_background.png— used for 0° (landscape) and 180° (landscape flipped)smartdisplay_background_90.png— used for 90° (portrait) and 270° (portrait flipped)The active image is selected via the
BG_IMAGEsubstitution in the ORIENTATION preset block.
- Material Design Icons font:
materialdesignicons-webfont.ttfis included in each UI variant'sfonts/folder (Apache 2.0 license, sourced from Templarian/MaterialDesign-Webfont).- If you change icons in the YAML, ensure the glyph list contains them.
- Background images (home-like UI):
esphome/home-like/images/smartdisplay_background.png— landscape (0° and 180°), included.esphome/home-like/images/smartdisplay_background_90.png— portrait (90° and 270°), included.- Selected automatically via the
BG_IMAGEsubstitution in the ORIENTATION preset block.
Your config choice defines the UI style:
- Buttons: BTN1..BTN4
- Action strings:
btn1_press..btn4_press - Default direct action (if
DIRECT_ACTIONS: "true"):light.toggleonBTN*_ENTITY
- Tiles: TILE1..TILE6
- Action strings:
tile1_press..tile6_press(short tap),tile1_long_press..tile6_long_press(long press) - Each tile can optionally call a Home Assistant service directly (e.g. light toggle, fan preset toggle, cover open/close or cover position).
- Per-tile OFF label is configurable via
TILE*_LABEL_OFF(e.g. "Off" / "Aus").
Each tile's long-press mode is configured via TILE*_LONGPRESS:
| Mode | Behavior |
|---|---|
slider |
Opens a value overlay (brightness / fan speed / cover position) |
action |
Fires a different HA entity than the short tap |
none |
Only publishes the tileN_long_press event, no direct action |
Slider mode — configure with TILE*_LONGPRESS_SLIDER and TILE*_LONGPRESS_OFF_VALUE:
| Tile Type | Overlay Control |
|---|---|
| light | Brightness slider |
| fan | Speed / percentage slider |
| cover | Position slider |
Action mode — configure with TILE*_LONGPRESS_ACTION, TILE*_LONGPRESS_ACTION_TYPE, and optionally TILE*_LONGPRESS_ACTION_SERVICE. The action entity can be a completely different entity than the short tap target — useful for e.g. triggering a scene or script on long press while toggling a light on short press.
In all modes, the tileN_long_press event is always published to sensor.smartdisplay_action so Home Assistant automations can react to it independently.
- Button pressed
- Action string published
- Home Assistant service called
- Entity state updated
- Mirrored back into ESPHome
- UI refreshed
- Button pressed
- Action string published
- Home Assistant automation triggers
- Automation controls device
- State mirrored back
For most setups, you only need to edit the USER CONFIG / substitutions section in the YAML.
You can also:
- Add more buttons / pages
- Change service calls (the default is
light.toggle) - Modify fonts and icon glyphs
- Adjust colors / theme
- Date localization can be adjusted in the ui_refresh script (days[] / months[] arrays).
- Adjust transforms for your panel
If touch alignment is wrong, ensure display.transform and touchscreen.transform
are identical (they must always match).
If the display stays completely white after updating ESPHome but the device still connects to Home Assistant, the cause is a breaking change in ESPHome 2026.4: the ili9xxx display platform was deprecated in favor of mipi_spi.
The YAML configs in this repo already use mipi_spi. If you are on an older ESPHome version (before 2026.4) and mipi_spi is not available yet, change the display platform back to ili9xxx and add color_palette: 8BIT:
display:
- platform: ili9xxx
model: ILI9341
color_palette: 8BIT
...Also re-add miso_pin to the LCD SPI bus:
spi:
- id: lcd
clk_pin: GPIO14 # or GPIO18 for the external ESP32 variant
mosi_pin: GPIO13 # or GPIO23
miso_pin: GPIO12 # or GPIO19 — add this back for older ESPHomeIf the display shows corrupted graphics, horizontal lines, or random pixels, the most common cause is a different display controller on your Cheap Yellow Display.
Most CYD boards use ILI9341, but some variants ship with ST7789 or ILI9342.
If the driver in ESPHome does not match the controller, the display output may look broken.
Try changing the display model in the YAML:
display:
- platform: mipi_spi
model: ILI9341Alternative models that may work depending on your board:
model: ST7789Vor
model: ILI9342Flashing with a different model is usually the fastest way to identify the correct controller.
If the UI appears rotated, mirrored, or upside down, use the built-in ORIENTATION preset block in the substitutions section at the top of home-like.yaml.
Four presets are provided and documented as comments — uncomment the one matching your desired orientation (0°, 90°, 180°, 270°) and comment out the others. Each preset sets the correct DISPLAY_SWAP_XY, DISPLAY_MIRROR_X/Y, TOUCH_SWAP_XY, TOUCH_MIRROR_X/Y, grid layout, and background image automatically.
Note: touch calibration values (
TOUCH_CAL_*) are device-specific. The portrait presets include approximate values that may need tuning after flashing.
If your board behaves differently from the presets, you can tune the transform values manually via the substitutions. The underlying parameters are:
transform:
swap_xy: true
mirror_x: true
mirror_y: trueDepending on the board variant, you may need to experiment with these values until the orientation matches your screen.
Make sure display.transform and touchscreen.transform always use the same values, otherwise touch input will be misaligned.
See the /3d_print folder for STL files and Fusion 360 source files.
Multiple mount options are available:
- Desk Mount – for tabletop installation
- Under-Desk Mount – for installation underneath a desk or shelf
- Wall Mount – for wall installation (CYD version only)
- Flush Mount – for in-wall installation (CYD version only, EU electrical box compatible)
Desk mount and Under-Desk mount use the same enclosure parts and adjustable tilt mechanism.
Print the main enclosure parts and choose one mount type depending on your setup.
Designed for:
- Desk mounting
- Under-desk mounting
- Wall mounting
- Flush mounting (EU electrical box compatible)
- Adjustable viewing angle
- Hidden cable routing
This is a hobby project and considered work-in-progress.
Feel free to fork, remix and improve it.
Looking for more cool projects using this display? Check out the LoctekMotion Touch Display GitHub repository! This awesome project takes the same 2.8" ILI9341 touchscreen setup and repurposes it—not for lights, but for controlling a height-adjustable Flexispot desk with ease. If you're into smart home automation and custom builds, it's definitely worth a look!















