Skip to content

akuehlewind/ESPHome-touch-display-mount

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ESP32 Cheap Yellow Display (ESP32-2432S028) Home Assistant Touch Panel – LVGL UI + 3D Printed Desk / Under Desk / Wall / Flush Mounts

ESPHome Home Assistant LVGL Cheap Yellow Display

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.

Demo

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.


🆕 Architecture Overview (LVGL-Based UI)

This project uses ESPHome LVGL instead of a classic display lambda approach.

Core Concepts

  • UI rendered fully using LVGL widgets
  • 4 configurable touch buttons
  • Real-time state mirroring from Home Assistant
  • Central ui_refresh script keeps UI synchronized
  • Optional direct Home Assistant service calls
  • Action sensor for automation-based control

Two Control Modes

1️⃣ Direct Mode (Default – Plug & Play)

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.

2️⃣ Automation Mode

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

Overlay Control Layer

The UI contains a secondary overlay layer used for interactive controls.

When a tile is long-pressed:

  1. The overlay opens
  2. The control type is determined (brightness / percentage / cover position)
  3. Slider interaction updates Home Assistant
  4. Closing the overlay returns to the tile grid

This keeps the tile UI clean while still allowing detailed control.

⚙️ Requirements

  • Home Assistant installed
  • ESPHome Add-on installed
  • ESPHome 2026.4+
  • Home Assistant 2026.2+
  • Basic ESPHome knowledge
  • 3D printer access (optional)

🧪 Tested With

This project was tested using:

  • ESPHome 2026.2+
  • Home Assistant 2026.2+
  • ESP32-2432S028 (Cheap Yellow Display / CYD)
  • ILI9341 + XPT2046 standalone wiring variant

⚠️ IMPORTANT -- Enable "Actions" in Home Assistant

Because this project uses:

homeassistant.action → light.toggle

You must allow the ESPHome device to perform Home Assistant service calls.

How to enable:

  1. Open Home Assistant
  2. Go to Settings
  3. Click Devices & Services
  4. Open the ESPHome integration
  5. Select your device
  6. Enable:

"Allow the device to perform Home Assistant actions"

Without this setting, direct control will not work.


✨ Features

  • 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

📦 Hardware

Option A -- ESP32-2432S028 (Cheap Yellow Display Board -- Recommended)

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)

Power connection (CYD)

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:

  1. Cut an old USB cable
  2. Connect 5V (red) and GND (black) to the CYD power cable
  3. Route the cable through the enclosure
  4. 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.

⚠️ Important: The CYD often has multiple identical JST connectors, but they do not share the same pinout. Make sure to use the connector labeled VIN / 5V. Other connectors may be labeled 3.3V, and connecting 5V there can damage the board.

Option B -- Standalone Display + ESP32

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

🚀 Installation

  1. Open ESPHome in Home Assistant
  2. Create a new device
  3. Copy the appropriate YAML file
  4. Edit the USER CONFIG / substitutions section at the top of the YAML (entities, labels, icons)
  5. Copy esphome/secrets.yaml.example to secrets.yaml and fill in your credentials
  6. Flash the device

Available YAML variants (pick one UI for your hardware):

Cheap Yellow Display (ESP32-2432S028 / CYD)

  • esphome/home-like/cyd-2432s028/home-like.yaml – 2x3 “tiles” UI (wallpaper + tiles) — actively maintained
  • esphome/buttons/cyd-2432s028/buttons.yaml – lockscreen with 4 round buttons (simple / legacy)

External display wiring (any ESP32 + ILI9341 + XPT2046)

  • esphome/home-like/ili9341-external-esp32/home-like.yaml – 2x3 “tiles” UI (wallpaper + tiles) — actively maintained
  • esphome/buttons/ili9341-external-esp32/buttons.yaml – lockscreen with 4 round buttons (simple / legacy)

Tip: The home-like.yaml file uses orientation-specific background images located in esphome/home-like/images/. For a full reference of all tile substitutions and copy-paste examples, see esphome/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_IMAGE substitution in the ORIENTATION preset block.


Assets (required for the UI)

  • Material Design Icons font: materialdesignicons-webfont.ttf is included in each UI variant's fonts/ 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_IMAGE substitution in the ORIENTATION preset block.

⚙️ UI mapping (USER CONFIG)

Your config choice defines the UI style:

buttons.yaml (lockscreen like buttons)

  • Buttons: BTN1..BTN4
  • Action strings: btn1_press .. btn4_press
  • Default direct action (if DIRECT_ACTIONS: "true"): light.toggle on BTN*_ENTITY

home-like.yaml (tiles)

  • 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").

Long-Press Behavior

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.


🧠 System Flow

Direct Mode

  1. Button pressed
  2. Action string published
  3. Home Assistant service called
  4. Entity state updated
  5. Mirrored back into ESPHome
  6. UI refreshed

Automation Mode

  1. Button pressed
  2. Action string published
  3. Home Assistant automation triggers
  4. Automation controls device
  5. State mirrored back

🔧 Customization

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).


Troubleshooting

White screen after ESPHome update (2026.4+)

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 ESPHome

Corrupted / garbled display output

If 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: ILI9341

Alternative models that may work depending on your board:

model: ST7789V

or

model: ILI9342

Flashing with a different model is usually the fastest way to identify the correct controller.


Display rotated / mirrored

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: true

Depending 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.


🖨 3D Printing

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

⚠️ Disclaimer

This is a hobby project and considered work-in-progress.

Feel free to fork, remix and improve it.

Other

More projects

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!

About

ESP32 Cheap Yellow Display (ESP32-2432S028) Home Assistant Touch Panel – LVGL UI + 3D Printed Desk / Under Desk / Wall / Flush Mounts

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors