The Sunton ESP32-2432S028R—universally known in the maker community as the "Cheap Yellow Display" (CYD)—is a 2.8-inch 320x240 TFT LCD bundled with an ESP32-WROOM-32. At roughly $18, it is the most cost-effective smart home kiosk available. However, its dual-SPI architecture (separate buses for the ILI9341 display and XPT2046 touch controller) and factory-rotated touch matrix cause endless configuration headaches. This guide provides the exact pin mappings, a decision framework for your UI stack, and a fully compilable ESPHome YAML baseline to get your dashboard running without the guesswork.
The Verdict: Which UI Stack Should You Use?
Before writing a single line of YAML, you must decide how to render your interface. The ESP32-WROOM-32 has 520KB of SRAM, which is tight for graphical interfaces. Use the decision tree below to lock in your approach.
| If your project requires... | Then choose... | Why? |
|---|---|---|
| Complex UI with sliders, custom fonts, and smooth animations | ESPHome lvgl component |
Hardware-accelerated rendering, manages memory efficiently via widgets. |
| Simple text, basic geometric gauges, and low RAM overhead | Native ili9xxx display painter |
Uses C++ lambdas, lower baseline memory footprint, no LVGL overhead. |
| Rapid prototyping without compiling YAML | Tasmota (Berry scripting) | Pre-compiled firmware, web-based UI builder, but less Home Assistant integration. |
lvgl component. The native display painter requires you to manually manage screen redraws and coordinate math, whereas LVGL handles widget invalidation automatically. The code block below targets the native ili9xxx driver for maximum baseline stability, but you can layer LVGL on top of this exact SPI configuration.
Hardware Spec Sheet & Exact Pin Mapping
The most common mistake when wiring the CYD is assuming the display and touch controller share the same SPI bus. They do not. The ILI9341 uses the ESP32's HSPI pins, while the XPT2046 touch controller is hardwired to a secondary SPI bus. If you attempt to share the clk and mosi pins across both components, the touch controller will hang the display during initialization.
Parts List
- Board: Sunton ESP32-2432S028R v1.1 (Ensure it is the WROOM-32 variant, not the S3)
- Power: 5V 2A USB-C power supply (Do not use standard 500mA PC USB ports; the backlight and Wi-Fi radio will cause brownouts)
- Enclosure: 3D printed snap-fit case (Search Printables for "CYD 2.8 inch enclosure")
PIN Mapping Table
| Component | Function | GPIO Pin | Notes / Constraints |
|---|---|---|---|
| Display (ILI9341) | SPI CLK | 14 | Display SPI Bus |
| SPI MOSI | 13 | Display SPI Bus | |
| SPI MISO | 12 | Display SPI Bus | |
| CS | 15 | Active Low | |
| DC (Data/Command) | 2 | Must be set as output | |
| Backlight | 21 | Active High (Must be turned ON in code) | |
| Touch (XPT2046) | SPI CLK | 25 | Touch SPI Bus (Separate!) |
| SPI MOSI | 32 | Touch SPI Bus | |
| SPI MISO | 39 | Touch SPI Bus (Input only pin) | |
| CS | 33 | Active Low | |
| IRQ (Interrupt) | 36 | Input only pin | |
| RGB LED | Red | 4 | Active Low |
| Green | 16 | Active Low | |
| Blue | 17 | Active Low |
Step-by-Step ESPHome Configuration
This YAML targets the ESP32-WROOM-32 (esp32dev) board variant. It initializes both SPI buses, configures the display with an 8-bit color palette to save RAM, and sets up the touch matrix with the correct axis swapping for the Sunton hardware.
- Create a new device in your ESPHome dashboard and name it
cyd-dashboard. - Replace the generated boilerplate with the complete YAML below.
- Update the
wifisection with your network credentials or use your ESPHome secrets file. - Flash via USB-C. Note: You must hold the 'BOOT' button on the back of the CYD while clicking 'Install' in ESPHome to enter download mode, as the board lacks an auto-reset circuit for the UART.
esphome:
name: cyd-dashboard
friendly_name: CYD Wall Dashboard
esp32:
board: esp32dev # Targets ESP32-WROOM-32
framework:
type: arduino
logger:
level: DEBUG
api:
encryption:
key: !secret api_key
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Fallback hotspot if Wi-Fi fails
ap:
ssid: "CYD-Fallback"
password: "fallback123"
# Define TWO separate SPI buses
spi:
- id: spi_display
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
- id: spi_touch
clk_pin: GPIO25
mosi_pin: GPIO32
miso_pin: GPIO39
# Backlight control
output:
- platform: ledc
pin: GPIO21
id: backlight_pwm
light:
- platform: monochromatic
output: backlight_pwm
name: "Display Backlight"
id: display_backlight
restore_mode: ALWAYS_ON
# Display configuration
display:
- platform: ili9xxx
model: ili9341
spi_id: spi_display
cs_pin: GPIO15
dc_pin: GPIO2
reset_pin: GPIO_NUM_NC # CYD has no hardware reset pin for the LCD
color_palette: 8BIT # Critical for ESP32 RAM management
update_interval: 1s
auto_clear_enabled: false
lambda: |-
it.fill(Color::BLACK);
it.printf(10, 10, id(my_font), Color::WHITE, "ESPHome CYD Online");
# Touchscreen configuration
touchscreen:
platform: xpt2046
spi_id: spi_touch
cs_pin: GPIO33
interrupt_pin: GPIO36
update_interval: 50ms
threshold: 400
calibration:
x_min: 300
x_max: 3800
y_min: 300
y_max: 3800
swap_x_y: true # Mandatory for Sunton 2.8" boards
on_touch:
then:
- logger.log: "Touch detected"
# Binary sensor for a virtual touch button
binary_sensor:
- platform: touchscreen
name: "Top Left Button"
x_min: 0
x_max: 100
y_min: 0
y_max: 100
on_press:
then:
- logger.log: "Virtual Button Pressed!"
- homeassistant.service:
service: light.toggle
data:
entity_id: light.living_room
font:
- file: "gfonts://Roboto"
id: my_font
size: 20
Troubleshooting: Blank Screens and Inverted Touch
When the CYD fails to operate correctly, it almost always stems from power delivery or SPI bus contention. Here is how to diagnose the two most common failure modes.
Symptom 1: Display is Blank or Pure White
Exact Error String: [E][ili9xxx:041] Display not responding to SPI or the logs show successful boot but the screen remains white.
The First Three Things to Check:
- Backlight Pin State: The screen might actually be rendering, but the backlight is off. Ensure GPIO21 is configured as an
outputand driven HIGH. In the YAML above, thelightcomponent withrestore_mode: ALWAYS_ONhandles this. - Power Supply Amperage: The Wi-Fi radio and LCD backlight combined draw ~600mA at peak. If powered by a standard PC USB port (500mA limit), the ESP32 will brownout during SPI initialization. Use a dedicated 5V/2A wall brick.
- Missing
reset_pinBypass: The CYD does not route a GPIO to the ILI9341 hardware reset pin. If you leavereset_pinblank or set it to a random GPIO, ESPHome will hang waiting for a hardware handshake. You must explicitly setreset_pin: GPIO_NUM_NC.
Symptom 2: Touch Axis is Inverted or Mirrored
Exact Error String / Symptom: Logs show [D][xpt2046:082] Touch pressed at (3900, 200) when you press the top-left corner (which should read ~300, 300).
Ranked Causes & Fixes:
- Missing
swap_x_y(Most Likely): The physical LCD matrix is mounted 90 degrees out of phase with the XPT2046 resistive layer. Addswap_x_y: trueto the touchscreen component. - Incorrect Calibration Bounds: Resistive touch controllers drift. If
swap_x_yis true but the cursor is still offset, adjustx_minandx_maxby ±200. Do not guess; enablelogger: level: VERY_VERBOSEto watch the raw ADC values as you press the corners. - SPI Bus Contention: If the touch works intermittently, ensure you haven't accidentally assigned the touch SPI pins (25, 32, 39) to the display SPI bus. They must be isolated.
Extending the Build: Adding I2C Sensors and Simplifying the UI
Once your baseline dashboard is stable, you will likely want to integrate local sensors or optimize the firmware for long-term kiosk deployment.
How to Extend: Adding I2C Sensors
The CYD features a 4-pin JST-PH 1.25mm connector on the back specifically for I2C expansion. The pinout is GND, 3.3V, SDA (GPIO27), SCL (GPIO22).
Warning: Never connect 5V I2C sensors directly to this header. The ESP32 GPIOs are strictly 3.3V tolerant. Use a logic level converter or stick to 3.3V native sensors like the SHT40 or BME280.
i2c:
sda: GPIO27
scl: GPIO22
scan: true
sensor:
- platform: sht4x
temperature:
name: "Local Temperature"
humidity:
name: "Local Humidity"
update_interval: 60s
How to Simplify: Stripping LVGL for Kiosk Mode
If you are building a dedicated, single-purpose gauge (e.g., a solar battery monitor) and find the ESP32 rebooting due to memory fragmentation, drop the LVGL or complex lambda stack entirely. Switch to ESPHome's display.page component. Pages only render when active, drastically reducing the loop time and RAM footprint. Set auto_clear_enabled: false in the display config and manually call it.fill(Color::BLACK) only when transitioning between pages to prevent screen flicker.
For authoritative wiring and component references, always consult the official ESPHome XPT2046 documentation and verify your specific board revision against the ESP32 CYD community repository, as Sunton occasionally revises the backlight and LDR pins on newer manufacturing runs.






