KundenkontoAccountTikTok

Wand-Dashboard für 20 €: Home Assistant Touch-Panel mit dem Cheap Yellow Display (ESPHome-Guide 2026)

20. September 2026

Ein Touch-Panel an der Wand, das Licht schaltet, die Temperatur zeigt und dein Home Assistant steuert – für 15–22 €. Klingt nach Bastel-Wochenende? Ist es nicht: Das Cheap Yellow Display (CYD) ist ein fertiges Board mit ESP32, 2,8-Zoll-Touchscreen und USB-Anschluss. Kein Löten, kein Verkabeln. Du flashst einmal ESPHome drauf, kopierst meine Konfiguration, trägst deine Entitäten ein – fertig.

In diesem Guide bauen wir Schritt für Schritt ein Wand-Dashboard mit Uhr, Temperatur, zwei Lichtschaltern und „Alles aus“, das sich nachts automatisch dimmt. Die Konfiguration ist auf dem aktuellen ESPHome getestet (2026.6) – inklusive der Stolperfallen, die seit ESPHome 2026.4 viele Anleitungen im Netz kaputt gemacht haben.

Was du brauchst

  • ESP32-2432S028R „Cheap Yellow Display“ – 2,8″, 320×240, resistiver Touch. Bei Amazon ca. 20–22 € (schnell da), bei AliExpress ab ca. 12 € (2–3 Wochen). Achte beim Kauf auf genau diese Bezeichnung.
  • USB-Netzteil 5 V / 1 A + Micro-USB-Kabel (bei der neuen Revision auch USB-C). Ein altes Handy-Netzteil reicht.
  • Home Assistant mit dem ESPHome Device Builder (Add-on) – oder ESPHome auf einem anderen Rechner.
  • Einen Rechner mit Chrome oder Edge zum ersten Flashen per USB.
  • Optional: ein 3D-gedrucktes Gehäuse (Tisch, Wand oder Unterputz – dazu unten mehr).
Das Board für diesen Guide

Das ESP32-2432S028R – ESP32, 2,8″-Touchscreen, Lichtsensor, RGB-LED und microSD auf einer Platine. Genau das Board, für das die Konfiguration unten geschrieben ist. Achte auf die Modellnummer; die 3,5″-Variante hat andere Pins.

* Affiliate-Link · Preis kann abweichen
Günstiger mit Geduld: AliExpress

Dasselbe Board direkt aus China – meist deutlich günstiger, dafür 2–3 Wochen Lieferzeit. Achte darauf, die Variante mit Touch („Touch“/„Resistive“) und die 2,8″-Größe zu wählen; Netzteil und Kabel sind meist nicht dabei.

* Affiliate-Link · Preis kann abweichen
Welche Version? Es gibt zwei Revisionen: die klassische mit einem Micro-USB-Port und eine neuere mit zwei Ports (Micro-USB + USB-C). Beide funktionieren mit diesem Guide. Bei manchen Zwei-Port-Boards sitzt ein anderer Display-Controller (ST7789 statt ILI9341) – falls dein Bild nach dem Flashen verzerrt ist, steht die Lösung unten bei „Fehlerbehebung“.

Schritt 1: ESPHome vorbereiten

  1. In Home Assistant: Einstellungen → Add-ons → Add-on Store → „ESPHome Device Builder“ installieren und starten (Haken bei „In der Seitenleiste anzeigen“).
  2. ESPHome öffnen → „+ New Device“ → Name wanddisplay → Gerätetyp ESP32 → Anlegen. Ein Basisgerät wird erstellt.
  3. Falls noch nicht vorhanden: In ESPHome oben rechts über das Menü „Secrets“ öffnen und deine WLAN-Daten eintragen:
wifi_ssid: "DeinWLAN"
wifi_password: "DeinPasswort"

Schritt 2: Die Konfiguration

Öffne das neue Gerät in ESPHome mit „Edit“, lösche den gesamten Inhalt und füge diese Konfiguration ein. Anpassen musst du nur den Block substitutions ganz oben – deine Entitäten und Beschriftungen. Alles andere kann bleiben.

substitutions:
  name: wanddisplay
  friendly_name: Wand-Dashboard
  # ---- Hier deine Entitäten eintragen ----
  licht_1: light.wohnzimmer
  licht_1_name: "Wohnzimmer"
  licht_2: light.kueche
  licht_2_name: "Küche"
  temp_sensor: sensor.wohnzimmer_temperatur
  alles_aus: script.alles_aus

esphome:
  name: ${name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:

api:

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "${friendly_name} Setup"

captive_portal:

time:
  - platform: homeassistant
    id: ha_time
    on_time_sync:
      - script.execute: update_time

# ---- Zwei SPI-Busse: Display und Touch ----
spi:
  - id: lcd
    clk_pin: GPIO14
    mosi_pin: GPIO13
  - id: touch_bus
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

# ---- Hintergrundbeleuchtung + RGB-LED ----
output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm
  - platform: ledc
    pin: GPIO4
    id: led_red
    inverted: true
  - platform: ledc
    pin: GPIO16
    id: led_green
    inverted: true
  - platform: ledc
    pin: GPIO17
    id: led_blue
    inverted: true

light:
  - platform: monochromatic
    output: backlight_pwm
    id: backlight
    name: "Display-Helligkeit"
    restore_mode: ALWAYS_ON
  - platform: rgb
    name: "Status-LED"
    id: status_led
    red: led_red
    green: led_green
    blue: led_blue
    restore_mode: ALWAYS_OFF

# ---- Sensoren ----
sensor:
  # Lichtsensor auf der Platine: dimmt das Display nachts
  - platform: adc
    pin: GPIO34
    id: ldr
    name: "Umgebungslicht"
    attenuation: 12db
    update_interval: 10s
    filters:
      - sliding_window_moving_average:
          window_size: 3
          send_every: 1
    on_value:
      then:
        - light.turn_on:
            id: backlight
            brightness: !lambda |-
              // Schwelle an dein Board anpassen: Im Log (Sensor "Umgebungslicht")
              // den Wert bei Dunkelheit und bei Licht notieren. Je nach Revision
              // steigt ODER faellt die Spannung bei Dunkelheit - dann "<" statt ">".
              return x > 2.6 ? 0.25 : 1.0;
  # Temperatur aus Home Assistant
  - platform: homeassistant
    id: temp
    entity_id: ${temp_sensor}
    on_value:
      then:
        - lvgl.label.update:
            id: lbl_temp
            text: !lambda 'return str_sprintf("%.1f °C", x);'

# ---- Lichtzustand aus Home Assistant spiegeln ----
binary_sensor:
  - platform: homeassistant
    id: licht_1_state
    entity_id: ${licht_1}
    on_state:
      then:
        - lvgl.widget.update:
            id: btn_licht_1
            state:
              checked: !lambda 'return x;'
  - platform: homeassistant
    id: licht_2_state
    entity_id: ${licht_2}
    on_state:
      then:
        - lvgl.widget.update:
            id: btn_licht_2
            state:
              checked: !lambda 'return x;'

script:
  - id: update_time
    then:
      - lvgl.label.update:
          id: lbl_time
          text: !lambda |-
            auto t = id(ha_time).now();
            if (!t.is_valid()) return std::string("--:--");
            return t.strftime("%H:%M");

interval:
  - interval: 30s
    then:
      - script.execute: update_time

# ---- Touch ----
touchscreen:
  platform: xpt2046
  id: ts_touch
  spi_id: touch_bus
  cs_pin: 33
  interrupt_pin: 36
  update_interval: 50ms
  threshold: 400
  calibration:
    x_min: 280
    x_max: 3860
    y_min: 340
    y_max: 3860
  transform:
    swap_xy: false
    mirror_x: true
    mirror_y: false

# ---- Display (ESPHome 2026.4+: mipi_spi, Drehung macht LVGL) ----
display:
  - platform: mipi_spi
    id: my_display
    spi_id: lcd
    model: ILI9341
    cs_pin: 15
    dc_pin: 2
    invert_colors: false
    update_interval: never
    auto_clear_enabled: false
    dimensions:
      width: 240
      height: 320

# ---- Oberfläche ----
lvgl:
  displays:
    - my_display
  touchscreens:
    - touchscreen_id: ts_touch
  rotation: 90
  theme:
    label:
      text_color: 0xE6EDF3
    button:
      bg_color: 0x12171F
      border_color: 0x242E3A
      border_width: 1
      radius: 14
      text_color: 0xE6EDF3
      checked:
        bg_color: 0x22D3EE
        text_color: 0x05141A
  pages:
    - id: main
      bg_color: 0x0A0E14
      widgets:
        - label:
            id: lbl_time
            align: TOP_LEFT
            x: 14
            y: 12
            text_font: montserrat_28
            text: "--:--"
        - label:
            id: lbl_temp
            align: TOP_RIGHT
            x: -14
            y: 16
            text_font: montserrat_20
            text_color: 0x22D3EE
            text: "-- °C"
        - button:
            id: btn_licht_1
            align: BOTTOM_LEFT
            x: 14
            y: -64
            width: 140
            height: 64
            checkable: true
            widgets:
              - label:
                  align: CENTER
                  text: "${licht_1_name}"
            on_click:
              - homeassistant.action:
                  action: light.toggle
                  data:
                    entity_id: ${licht_1}
        - button:
            id: btn_licht_2
            align: BOTTOM_RIGHT
            x: -14
            y: -64
            width: 140
            height: 64
            checkable: true
            widgets:
              - label:
                  align: CENTER
                  text: "${licht_2_name}"
            on_click:
              - homeassistant.action:
                  action: light.toggle
                  data:
                    entity_id: ${licht_2}
        - button:
            align: BOTTOM_MID
            y: -8
            width: 292
            height: 44
            widgets:
              - label:
                  align: CENTER
                  text: "Alles aus"
            on_click:
              - homeassistant.action:
                  action: script.turn_on
                  data:
                    entity_id: ${alles_aus}

Was passiert hier? Zwei SPI-Busse (Display und Touch sind getrennt verdrahtet), die Hintergrundbeleuchtung hängt an GPIO21 und wird über den Lichtsensor (GPIO34) automatisch gedimmt (Schwelle einmal ans eigene Board anpassen, siehe Fehlerbehebung), die RGB-LED ist als Licht in Home Assistant verfügbar (für Statusanzeigen). Die Oberfläche macht LVGL: Uhr oben links, Temperatur oben rechts, zwei Lichtbuttons, die ihren Zustand live aus Home Assistant spiegeln, und ein Sammelbutton. Alle Tastendrücke rufen direkt Home-Assistant-Aktionen auf – ohne eine einzige Automation.

Schritt 3: Flashen

  1. CYD per USB an den Rechner anschließen, an dem du ESPHome im Browser (Chrome/Edge) geöffnet hast. Windows-Nutzer: Falls kein COM-Port auftaucht, den CH340-Treiber installieren.
  2. In ESPHome beim Gerät auf „Install“ → „Plug into this computer“ → den seriellen Port auswählen. ESPHome kompiliert (beim ersten Mal 3–8 Minuten) und flasht.
  3. Danach startet das Board neu, verbindet sich mit deinem WLAN und Home Assistant meldet unter Einstellungen → Geräte & Dienste ein neues ESPHome-Gerät zum Hinzufügen. Alle weiteren Updates laufen ab jetzt drahtlos (OTA).

Schritt 4: Aktionen erlauben (wichtig!)

Standardmäßig darf ein ESPHome-Gerät in Home Assistant nichts schalten. Ohne diesen Haken reagieren die Buttons nicht:

  1. Einstellungen → Geräte & Dienste → ESPHome
  2. Bei „Wand-Dashboard“ auf „Konfigurieren“
  3. Haken bei „Dem Gerät erlauben, Home-Assistant-Aktionen auszuführen“ setzen

Schritt 5: Anpassen

Alles Wichtige steht im substitutions-Block. Willst du mehr, sind das die typischen Erweiterungen:

  • Andere Gerätetypen: Statt light.toggle geht jede Aktion – switch.toggle für Steckdosen, cover.toggle für Rollläden, scene.turn_on für Szenen. Beim Zustand-Spiegeln dann den passenden binary_sensor bzw. die Entität anpassen.
  • Mehr Buttons: Einen button-Block kopieren, id, Position (align/x/y) und Entität ändern. Bei mehr als vier Buttons lohnt eine zweite Seite (pages) mit Wischgeste – das zeige ich in einem Folge-Guide.
  • Icons statt Text: LVGL kann Material-Design-Icons als Schrift einbinden (materialdesignicons-webfont.ttf in den ESPHome-Ordner legen und als font mit den gewünschten Glyphen laden). Für den Start reicht Text.
  • Display nachts ganz aus: Im on_value des Lichtsensors brightness: 0.0 statt 0.25 – Touch weckt es dann nicht automatisch; dafür einen on_touch im touchscreen-Block mit light.turn_on ergänzen.

Gehäuse & Montage

Nackt sieht das Board nach Bastelkeller aus. Auf MakerWorld gibt es ein hervorragendes CC0-Gehäuse (also frei nutzbar) genau für dieses Board – mit Tischständer, Wandhalter, Unter-Tisch-Halter und Unterputz-Rahmen für die 68er-Dose, jeweils mit Schwenkgelenk und versteckter Kabelführung: Home Assistant Desk Mount CYD (akuehlewind). Druckzeit ca. 3,5 h mit dem „Optimized“-Profil.

Vorsicht beim Stromanschluss: Wer das Board im Gehäuse über die kleinen JST-Stecker versorgt (statt per USB), muss den Stecker mit VIN/5V nehmen. Auf der Platine gibt es baugleiche Stecker mit 3,3 V – 5 V dort zerstören das Board. Im Zweifel: USB nutzen.

Für die Wandmontage neben einem Lichtschalter ist der Unterputz-Rahmen die eleganteste Lösung; das USB-Netzteil verschwindet dann in einer tiefen Dose (Elektronikdose, ≥ 40 mm). 230 V bleibt Sache des Elektrikers.

Stromversorgung

Ein einfaches 5-V-USB-Netzteil reicht – das Display zieht unter 1 W. Für den Unterputz-Einbau nimmst du ein möglichst flaches Netzteil, das in die tiefe Dose passt, oder ein 5-V-Hutschienen-/Einbau-Netzteil vom Elektriker.

* Affiliate-Link · Preis kann abweichen

Fehlerbehebung

  • Weißer Bildschirm, aber Gerät ist online: Du nutzt eine alte Anleitung mit platform: ili9xxx auf ESPHome 2026.4 oder neuer – dieser Treiber wurde durch mipi_spi ersetzt. Meine Konfiguration oben ist bereits richtig. Umgekehrt: Auf ESPHome vor 2026.4 gibt es mipi_spi noch nicht – dann platform: ili9xxx, color_palette: 8BIT und beim lcd-SPI zusätzlich miso_pin: GPIO12, sowie rotation: 90 aus dem lvgl-Block entfernen und stattdessen im display ein transform: swap_xy: true mit dimensions: 320×240 setzen. Oder einfach ESPHome aktualisieren.
  • Verzerrte Farben, Streifen, Pixelsalat: Anderer Display-Controller. Im display-Block model: ST7789V (oder ILI9342) probieren – mehr als das eine Wort ändert sich nicht.
  • Touch trifft daneben oder ist gespiegelt: Im touchscreen-Block mirror_x/mirror_y/swap_xy variieren. Wenn es nur um wenige Millimeter geht, die calibration-Werte anpassen: Die Rohwerte siehst du im ESPHome-Log, wenn du die Ecken antippst.
  • Bild steht auf dem Kopf: rotation: 90 im lvgl-Block auf 270 ändern (USB-Buchse dann auf der anderen Seite).
  • Buttons tun nichts: Schritt 4 vergessen – „Home-Assistant-Aktionen erlauben“.
  • Uhr zeigt „–:–„: Zeit kommt aus Home Assistant; kurz nach dem Start dauert der Abgleich ein paar Sekunden. Bleibt es leer, ist die API-Verbindung nicht da (Gerät in HA hinzugefügt?).
  • Kein COM-Port beim Flashen: CH340-Treiber (Windows) oder ein anderes USB-Kabel – viele Ladekabel haben keine Datenleitungen.
  • Display dimmt am Tag oder bleibt nachts hell: Der Lichtsensor ist je nach Board-Revision unterschiedlich beschaltet. Hand über den Sensor (kleines Bauteil neben dem Display) und im ESPHome-Log den Wert von Umgebungslicht vergleichen: Liegt der Wert bei Dunkelheit höher, passt x > 2.6 – liegt er niedriger, drehe den Vergleich auf x < 0.8 (Zahl aus dem Log). Die Schwelle in die Mitte zwischen beide Messwerte legen.

Häufige Fragen

Geht das auch mit dem 3,5″-Modell (ESP32-3248S035)? Ja, aber mit anderen Pins und anderem Controller (ST7796). Die Struktur bleibt gleich, die Werte nicht – das wird ein eigener Guide.

Kapazitiver Touch? Das Standard-CYD hat resistiven Touch (drücken statt streicheln). Die „C“-Varianten mit kapazitivem Touch brauchen einen anderen Touch-Block (gt911 über I²C).

Kann das Display Kameras oder Grafiken zeigen? Bilder und Icons ja (LVGL image-Widget), Video-Streams nein – dafür ist der ESP32 zu schwach.

Wie viel Strom zieht das? Etwa 0,6 W bei voller Helligkeit, gedimmt unter 0,4 W – rund 1,50 € im Jahr.

Fazit

Für rund 20 € und eine halbe Stunde bekommst du ein Touch-Panel, das genau das tut, was du brauchst – ohne App, ohne Cloud, ohne Abo. Die Konfiguration oben ist die Basis; von hier aus wächst das Ding mit dir: mehr Buttons, Icons, zweite Seite, Rollläden, Szenen. Und mit dem Unterputz-Rahmen sieht es aus, als hätte es der Elektriker eingebaut.

Wer noch ganz am Anfang steht: Mein Home-Assistant-Starter-Guide bringt dich bis zur ersten Automation. Und wenn du dein ganzes Haus planen willst, hilft der neue Smart-Home-Planer – Raum für Raum mit Geräteliste und Preisen.

A touch panel on the wall that switches your lights, shows the temperature and controls your Home Assistant – for €15–22. Sounds like a weekend of tinkering? It isn’t: the Cheap Yellow Display (CYD) is a ready-made board with an ESP32, a 2.8-inch touchscreen and a USB port. No soldering, no wiring. You flash ESPHome onto it once, copy my config, fill in your entities – done.

In this guide we’ll build, step by step, a wall dashboard with a clock, temperature, two light switches and an „All off“ button that dims itself automatically at night. The config is tested on the current ESPHome (2026.6) – including the pitfalls that have broken a lot of the guides out there since ESPHome 2026.4.

What you need

  • ESP32-2432S028R „Cheap Yellow Display“ – 2.8″, 320×240, resistive touch. Around €20–22 on Amazon (arrives fast), from about €12 on AliExpress (2–3 weeks). Make sure you buy exactly this model.
  • 5 V / 1 A USB power supply + micro-USB cable (USB-C on the newer revision). An old phone charger will do.
  • Home Assistant with the ESPHome Device Builder (add-on) – or ESPHome on another computer.
  • A computer with Chrome or Edge for the first flash over USB.
  • Optional: a 3D-printed case (desk, wall or flush-mount – more on that below).
The board for this guide

The ESP32-2432S028R – ESP32, 2.8″ touchscreen, light sensor, RGB LED and microSD on one board. Exactly the board the configuration below is written for. Check the model number; the 3.5″ version has different pins.

* Affiliate-Link · Preis kann abweichen
Cheaper if you can wait: AliExpress

The same board straight from China – usually much cheaper, but with 2–3 weeks delivery. Make sure to pick the version with touch („Touch“/“Resistive“) and the 2.8″ size; power supply and cable are usually not included.

* Affiliate-Link · Preis kann abweichen
Which version? There are two revisions: the classic one with one micro-USB port and a newer one with two ports (micro-USB + USB-C). Both work with this guide. Some two-port boards use a different display controller (ST7789 instead of ILI9341) – if your image is garbled after flashing, the fix is below under „Troubleshooting“.

Step 1: Prepare ESPHome

  1. In Home Assistant: Settings → Add-ons → Add-on Store → install and start „ESPHome Device Builder“ (tick „Show in sidebar“).
  2. Open ESPHome → „+ New Device“ → name it wanddisplay → device type ESP32 → create. A basic device is set up.
  3. If you haven’t already: open „Secrets“ from the menu at the top right in ESPHome and enter your Wi-Fi credentials:
wifi_ssid: "DeinWLAN"
wifi_password: "DeinPasswort"

Step 2: The configuration

Open the new device in ESPHome with „Edit“, delete everything in it and paste in this config. The only thing you need to change is the substitutions block at the very top – your entities and labels. Everything else can stay as it is.

substitutions:
  name: wanddisplay
  friendly_name: Wand-Dashboard
  # ---- Hier deine Entitäten eintragen ----
  licht_1: light.wohnzimmer
  licht_1_name: "Wohnzimmer"
  licht_2: light.kueche
  licht_2_name: "Küche"
  temp_sensor: sensor.wohnzimmer_temperatur
  alles_aus: script.alles_aus

esphome:
  name: ${name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:

api:

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "${friendly_name} Setup"

captive_portal:

time:
  - platform: homeassistant
    id: ha_time
    on_time_sync:
      - script.execute: update_time

# ---- Zwei SPI-Busse: Display und Touch ----
spi:
  - id: lcd
    clk_pin: GPIO14
    mosi_pin: GPIO13
  - id: touch_bus
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

# ---- Hintergrundbeleuchtung + RGB-LED ----
output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm
  - platform: ledc
    pin: GPIO4
    id: led_red
    inverted: true
  - platform: ledc
    pin: GPIO16
    id: led_green
    inverted: true
  - platform: ledc
    pin: GPIO17
    id: led_blue
    inverted: true

light:
  - platform: monochromatic
    output: backlight_pwm
    id: backlight
    name: "Display-Helligkeit"
    restore_mode: ALWAYS_ON
  - platform: rgb
    name: "Status-LED"
    id: status_led
    red: led_red
    green: led_green
    blue: led_blue
    restore_mode: ALWAYS_OFF

# ---- Sensoren ----
sensor:
  # Lichtsensor auf der Platine: dimmt das Display nachts
  - platform: adc
    pin: GPIO34
    id: ldr
    name: "Umgebungslicht"
    attenuation: 12db
    update_interval: 10s
    filters:
      - sliding_window_moving_average:
          window_size: 3
          send_every: 1
    on_value:
      then:
        - light.turn_on:
            id: backlight
            brightness: !lambda |-
              // Schwelle an dein Board anpassen: Im Log (Sensor "Umgebungslicht")
              // den Wert bei Dunkelheit und bei Licht notieren. Je nach Revision
              // steigt ODER faellt die Spannung bei Dunkelheit - dann "<" statt ">".
              return x > 2.6 ? 0.25 : 1.0;
  # Temperatur aus Home Assistant
  - platform: homeassistant
    id: temp
    entity_id: ${temp_sensor}
    on_value:
      then:
        - lvgl.label.update:
            id: lbl_temp
            text: !lambda 'return str_sprintf("%.1f °C", x);'

# ---- Lichtzustand aus Home Assistant spiegeln ----
binary_sensor:
  - platform: homeassistant
    id: licht_1_state
    entity_id: ${licht_1}
    on_state:
      then:
        - lvgl.widget.update:
            id: btn_licht_1
            state:
              checked: !lambda 'return x;'
  - platform: homeassistant
    id: licht_2_state
    entity_id: ${licht_2}
    on_state:
      then:
        - lvgl.widget.update:
            id: btn_licht_2
            state:
              checked: !lambda 'return x;'

script:
  - id: update_time
    then:
      - lvgl.label.update:
          id: lbl_time
          text: !lambda |-
            auto t = id(ha_time).now();
            if (!t.is_valid()) return std::string("--:--");
            return t.strftime("%H:%M");

interval:
  - interval: 30s
    then:
      - script.execute: update_time

# ---- Touch ----
touchscreen:
  platform: xpt2046
  id: ts_touch
  spi_id: touch_bus
  cs_pin: 33
  interrupt_pin: 36
  update_interval: 50ms
  threshold: 400
  calibration:
    x_min: 280
    x_max: 3860
    y_min: 340
    y_max: 3860
  transform:
    swap_xy: false
    mirror_x: true
    mirror_y: false

# ---- Display (ESPHome 2026.4+: mipi_spi, Drehung macht LVGL) ----
display:
  - platform: mipi_spi
    id: my_display
    spi_id: lcd
    model: ILI9341
    cs_pin: 15
    dc_pin: 2
    invert_colors: false
    update_interval: never
    auto_clear_enabled: false
    dimensions:
      width: 240
      height: 320

# ---- Oberfläche ----
lvgl:
  displays:
    - my_display
  touchscreens:
    - touchscreen_id: ts_touch
  rotation: 90
  theme:
    label:
      text_color: 0xE6EDF3
    button:
      bg_color: 0x12171F
      border_color: 0x242E3A
      border_width: 1
      radius: 14
      text_color: 0xE6EDF3
      checked:
        bg_color: 0x22D3EE
        text_color: 0x05141A
  pages:
    - id: main
      bg_color: 0x0A0E14
      widgets:
        - label:
            id: lbl_time
            align: TOP_LEFT
            x: 14
            y: 12
            text_font: montserrat_28
            text: "--:--"
        - label:
            id: lbl_temp
            align: TOP_RIGHT
            x: -14
            y: 16
            text_font: montserrat_20
            text_color: 0x22D3EE
            text: "-- °C"
        - button:
            id: btn_licht_1
            align: BOTTOM_LEFT
            x: 14
            y: -64
            width: 140
            height: 64
            checkable: true
            widgets:
              - label:
                  align: CENTER
                  text: "${licht_1_name}"
            on_click:
              - homeassistant.action:
                  action: light.toggle
                  data:
                    entity_id: ${licht_1}
        - button:
            id: btn_licht_2
            align: BOTTOM_RIGHT
            x: -14
            y: -64
            width: 140
            height: 64
            checkable: true
            widgets:
              - label:
                  align: CENTER
                  text: "${licht_2_name}"
            on_click:
              - homeassistant.action:
                  action: light.toggle
                  data:
                    entity_id: ${licht_2}
        - button:
            align: BOTTOM_MID
            y: -8
            width: 292
            height: 44
            widgets:
              - label:
                  align: CENTER
                  text: "Alles aus"
            on_click:
              - homeassistant.action:
                  action: script.turn_on
                  data:
                    entity_id: ${alles_aus}

What’s going on here? Two SPI buses (display and touch are wired separately), the backlight sits on GPIO21 and is dimmed automatically by the light sensor (GPIO34) (adjust the threshold to your own board once, see Troubleshooting), and the RGB LED shows up as a light in Home Assistant (handy for status indicators). LVGL handles the UI: clock top left, temperature top right, two light buttons that mirror their state live from Home Assistant, and an all-in-one button. Every button press calls Home Assistant actions directly – without a single automation.

Step 3: Flashing

  1. Connect the CYD via USB to the computer where you have ESPHome open in the browser (Chrome/Edge). Windows users: if no COM port shows up, install the CH340 driver.
  2. In ESPHome, click „Install“ on the device → „Plug into this computer“ → select the serial port. ESPHome compiles (3–8 minutes the first time) and flashes.
  3. The board then reboots, connects to your Wi-Fi, and Home Assistant shows a new ESPHome device ready to add under Settings → Devices & services. From now on, all further updates happen wirelessly (OTA).

Step 4: Allow actions (important!)

By default, an ESPHome device isn’t allowed to switch anything in Home Assistant. Without this checkbox, the buttons won’t do anything:

  1. Settings → Devices & services → ESPHome
  2. Click „Configure“ on „Wand-Dashboard“
  3. Tick „Allow the device to perform Home Assistant actions“

Step 5: Customize

Everything important lives in the substitutions block. If you want more, these are the typical extensions:

  • Other device types: Instead of light.toggle you can use any action – switch.toggle for smart plugs, cover.toggle for blinds, scene.turn_on for scenes. For state mirroring, adjust the matching binary_sensor or entity accordingly.
  • More buttons: Copy a button block and change the id, position (align/x/y) and entity. With more than four buttons, a second page (pages) with a swipe gesture makes sense – I’ll show that in a follow-up guide.
  • Icons instead of text: LVGL can embed Material Design Icons as a font (put materialdesignicons-webfont.ttf in the ESPHome folder and load it as a font with the glyphs you want). Text is fine to start with.
  • Display completely off at night: In the light sensor’s on_value, use brightness: 0.0 instead of 0.25 – touch won’t wake it automatically then; add an on_touch with light.turn_on to the touchscreen block for that.

Case & mounting

Bare, the board looks like something out of a hobby basement. On MakerWorld there’s an excellent CC0 case (so free to use) made for exactly this board – with a desk stand, wall mount, under-desk mount and a flush-mount frame for a standard 68 mm wall box, each with a swivel joint and hidden cable routing: Home Assistant Desk Mount CYD (akuehlewind). Print time is about 3.5 h with the „Optimized“ profile.

Careful with the power connection: If you power the board inside the case via the small JST connectors (instead of USB), you have to use the connector marked VIN/5V. The board also has identical-looking connectors carrying 3.3 V – 5 V on those will kill the board. When in doubt: use USB.

For wall mounting next to a light switch, the flush-mount frame is the most elegant solution; the USB power supply then disappears into a deep wall box (electronics box, ≥ 40 mm). Anything involving 230 V is a job for an electrician.

Power supply

A simple 5 V USB power supply is enough – the display draws less than 1 W. For flush mounting, use the flattest power supply you can find that fits a deep wall box, or a 5 V DIN-rail/built-in power supply from an electrician.

* Affiliate-Link · Preis kann abweichen

Troubleshooting

  • White screen, but the device is online: You’re using an old guide with platform: ili9xxx on ESPHome 2026.4 or newer – that driver has been replaced by mipi_spi. My config above is already correct. The other way round: ESPHome before 2026.4 doesn’t have mipi_spi yet – in that case use platform: ili9xxx, color_palette: 8BIT and additionally miso_pin: GPIO12 on the lcd SPI, remove rotation: 90 from the lvgl block and instead set transform: swap_xy: true with dimensions: 320×240 in the display. Or just update ESPHome.
  • Distorted colors, stripes, pixel garbage: Different display controller. Try model: ST7789V (or ILI9342) in the display block – nothing changes except that one word.
  • Touch is off target or mirrored: Play with mirror_x/mirror_y/swap_xy in the touchscreen block. If it’s only off by a few millimeters, adjust the calibration values: you’ll see the raw values in the ESPHome log when you tap the corners.
  • Image is upside down: Change rotation: 90 in the lvgl block to 270 (the USB port will then be on the other side).
  • Buttons do nothing: You skipped step 4 – „Allow Home Assistant actions“.
  • Clock shows „–:–„: The time comes from Home Assistant; right after startup, syncing takes a few seconds. If it stays empty, the API connection isn’t there (did you add the device in HA?).
  • No COM port when flashing: CH340 driver (Windows) or a different USB cable – a lot of charging cables don’t have data lines.
  • Display dims during the day or stays bright at night: The light sensor is wired differently depending on the board revision. Put your hand over the sensor (small component next to the display) and compare the value of Umgebungslicht in the ESPHome log: if the value is higher in the dark, x > 2.6 is right – if it’s lower, flip the comparison to x < 0.8 (number from the log). Put the threshold halfway between the two readings.

FAQ

Does this work with the 3.5″ model (ESP32-3248S035) too? Yes, but with different pins and a different controller (ST7796). The structure stays the same, the values don’t – that’ll get its own guide.

Capacitive touch? The standard CYD has resistive touch (press rather than swipe). The „C“ variants with capacitive touch need a different touch block (gt911 via I²C).

Can the display show cameras or graphics? Images and icons yes (LVGL image widget), video streams no – the ESP32 is too weak for that.

How much power does it draw? About 0.6 W at full brightness, under 0.4 W dimmed – roughly €1.50 a year.

Conclusion

For around €20 and half an hour, you get a touch panel that does exactly what you need – no app, no cloud, no subscription. The config above is the foundation; from here the thing grows with you: more buttons, icons, a second page, blinds, scenes. And with the flush-mount frame, it looks like the electrician put it in.

Just getting started? My Home Assistant starter guide takes you all the way to your first automation. And if you want to plan your whole house, the new Smart Home Planner helps – room by room, with a device list and prices.

Das könnte dich auch interessieren