Difficulty: Intermediate | Time Required: 45 Minutes | Cost: ~$18 USD

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.
Concrete Pick: For 90% of smart home wall dashboards, choose the ESPHome 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 CLK14Display SPI Bus
SPI MOSI13Display SPI Bus
SPI MISO12Display SPI Bus
CS15Active Low
DC (Data/Command)2Must be set as output
Backlight21Active High (Must be turned ON in code)
Touch (XPT2046)SPI CLK25Touch SPI Bus (Separate!)
SPI MOSI32Touch SPI Bus
SPI MISO39Touch SPI Bus (Input only pin)
CS33Active Low
IRQ (Interrupt)36Input only pin
RGB LEDRed4Active Low
Green16Active Low
Blue17Active 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.

  1. Create a new device in your ESPHome dashboard and name it cyd-dashboard.
  2. Replace the generated boilerplate with the complete YAML below.
  3. Update the wifi section with your network credentials or use your ESPHome secrets file.
  4. 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:

  1. Backlight Pin State: The screen might actually be rendering, but the backlight is off. Ensure GPIO21 is configured as an output and driven HIGH. In the YAML above, the light component with restore_mode: ALWAYS_ON handles this.
  2. 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.
  3. Missing reset_pin Bypass: The CYD does not route a GPIO to the ILI9341 hardware reset pin. If you leave reset_pin blank or set it to a random GPIO, ESPHome will hang waiting for a hardware handshake. You must explicitly set reset_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:

  1. Missing swap_x_y (Most Likely): The physical LCD matrix is mounted 90 degrees out of phase with the XPT2046 resistive layer. Add swap_x_y: true to the touchscreen component.
  2. Incorrect Calibration Bounds: Resistive touch controllers drift. If swap_x_y is true but the cursor is still offset, adjust x_min and x_max by ±200. Do not guess; enable logger: level: VERY_VERBOSE to watch the raw ADC values as you press the corners.
  3. 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.