ESP32 mit TFT Display und Touch Funktion

In der Bastler- und Maker-Szene werden oft nur einfache Display- und Touch-Lösungen benötigt. Doch dieses günstigste Entwicklungsboard ESP32-2432S028 mit großen Display das in der Maker-Szene auch als Cheap Yellow Display (CYD) bekannt ist und es gibt weitere mit unterschiedlichen ESP32 Varianten und Displaygrößen.

Es basiert auf einem ESP32-WROOM-Modul mit 4 MB Flash, das auf einer auffällig gelben Platine sitzt. Verbaut ist ein 2,8-Zoll Touchdisplay mit 320 × 240 Pixeln, das sich ideal für einfache grafische Benutzeroberflächen eignet.

Das Cheap Yellow Display Board ist wie folgt ausgestattet:

  • Resistiver Touchscreen mit ILI9341-TFT & XPT2046-Touch
  • microSD-Kartenslot
  • LDR (Helligkeitssensor)
  • RGB-LED (GPIO-Pins: 4, 16, 17)
  • Lautsprecheranschluss
  • Boot-Taster
  • JST-Anschlüsse (1,25 mm, für Sensoren/Peripherie)
  • USB (Micro-USB und/oder USB-C) zur Stromversorgung & Programmierung
  • WLAN/Bluetooth

Detaillierte Hersteller Informationen habe ich nicht gefunden, dennoch gibt es eine Vielzahl von deckungsgleichen Dokumenten die bei der Umsetzung hilfreich sind.

Weitere Details: https://randomnerdtutorials.com/



Projektübersicht: LED Steuerung & Temperaturanzeige

Für den einfachen Einstieg wird in diesem Projekt ein DHT22-Temperatursensor angeschlossen, dessen Messwerte direkt auf dem Display angezeigt werden.
Zusätzlich soll die integrierte RGB-LED über das Touchdisplay ein- und ausgeschaltet werden können.

Hardware:

ESP32-2432S028R
DHT11/DHT22 Sensor (Für Temperatur-/Feuchtigkeits-Messung)

ACHTUNG: Ich habe hier die Resistive Version des Boards vor mir liegen.
Zu erkennen an dem letzten R in der Typenbezeichnung: ESP32-2432S028R
Diese Version hat ein Touchscreen das den XPT2046-Chip nutzt, über SPI-Kommunikation (Serial Peripheral Interface).
Es gibt noch eine C-Version (Kapazitiv) die den GT911-Chip für die Touch nutzt über I2C-Bus (TAMC_GT911-Bibliothek)

Also nicht verwechseln


Entwicklungsumgebung:

  • Hier die Klassische Methode mit Arduino IDE.

    Direkte Programmierung mit TFT_eSPI & TouchScreen.h. in drei Schritten:
    • Erst einmal testen ob das Display Text ausgeben kann.
    • Dann ob ein DHT22 anschlossen werden kann und der Temperaturwert auf dem Display erscheint.
    • Und als letztes, ob ein Botton als Schaltfläche zum schalten den RGB – LED funktioniert.

Benötigte Bibliothek installieren

Nun muss die Datei User_Setup.h der gerade installierten Bibliothek TFT_eSPI für das CYD angepasst werden:

1. Richtige Pin-Zuweisungen für SPI und Touchscreen:

TFT_MISO 12
TFT_MOSI 13
TFT_SCLK 14
TFT_CS 15
TFT_DC 2
TFT_RST -1
TOUCH_CS 33

2. Aktiviere den passenden Display-Treiber: #define ILI9341_2_DRIVER und deaktiviere andere Display-Treiber

3. Richtige Displaygröße: TFT_WIDTH 240, TFT_HEIGHT 320

Also das sollte dann in der User_Setup.h drin stehen, die im Ordner C:\ordner deiner sketche\libraries\TFT_eSPI\ zufinden ist:

// Konfiguration für das ESP32-2432S028 (Cheap Yellow Display - CYD)
#define USER_SETUP_INFO "User_Setup_CYD"

// 1. Treiber und Display-Auflösung
#define ILI9341_2_DRIVER
#define TFT_WIDTH  240
#define TFT_HEIGHT 320

// 2. Pin-Belegung
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15  // Chip Select
#define TFT_DC   2   // Data Command
#define TFT_RST  -1  // Reset (wird direkt vom ESP32 gesteuert)

#define TFT_BL   21  // Backlight (Hintergrundbeleuchtung)
#define TFT_BACKLIGHT_ON HIGH

#define TOUCH_CS 33  // Chip Select für den Touchscreen

// 3. Schriftarten (Fonts) laden
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT

// 4. Geschwindigkeiten für die serielle Peripherieschnittstelle (SPI - Serial Peripheral Interface)
#define SPI_FREQUENCY  55000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000

// 5. Weitere Optionen
#define USE_HSPI_PORT

Einfache Display Text Ausgabe

Arduino Sketch:

#include <TFT_eSPI.h> // Eine Bibliothek zur Ansteuerung von TFT-Displays (Thin-Film-Transistor)
// Kann über den Bibliotheksmanager installiert werden (Suche nach "TFT_eSPI")
// https://github.com/Bodmer/TFT_eSPI

TFT_eSPI tft = TFT_eSPI(); // Initialisiert das TFT-Display-Objekt

void setup() {
  // WICHTIG für das CYD: Hintergrundbeleuchtung aktivieren
  pinMode(21, OUTPUT);
  digitalWrite(21, HIGH);

  // Startet das TFT-Display
  tft.init();
  tft.setRotation(1); // Setzt das Display ins Querformat (320 x 240 Bildpunkte)
  
  // Löscht den Bildschirm (setzt alles auf Schwarz)
  tft.fillScreen(TFT_BLACK);

  // 1. Einen zweifarbigen Rahmen um den gesamten Bildschirm zeichnen
  // drawRect(x, y, breite, höhe, farbe)
  tft.drawRect(0, 0, 320, 240, TFT_CYAN);
  tft.drawRect(2, 2, 316, 236, TFT_BLUE);

  // 2. Begrüßung in mittlerer Schrift (Font 4) und Gelb
  tft.setTextColor(TFT_YELLOW, TFT_BLACK); 
  // drawCentreString platziert den Text exakt in der Mitte der X-Achse (bei 320 Pixeln Breite ist das 160)
  tft.drawCentreString("Hallo Bastler & Tueftler!", 160, 20, 4); 

  // 3. Eine dekorative rote Trennlinie zeichnen
  // drawLine(start_x, start_y, ende_x, ende_y, farbe)
  tft.drawLine(20, 60, 300, 60, TFT_RED);

  // 4. Normaler Text (Font 2) in Weiß
  tft.setTextColor(TFT_WHITE, TFT_BLACK); 
  tft.drawCentreString("Willkommen auf", 160, 80, 2);

  // 5. Der Blog-Name hervorgehoben in leuchtendem Grün
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  // Mit Sonderzeichen wie Klammern oder Pfeilen kann man den Text optisch einrahmen
  tft.drawCentreString(">>> prilchen.de <<<", 160, 110, 4);

  // 6. Ein kleiner Status-Text (Font 2) in Orange
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.drawCentreString("Hardware-Test bestanden! [OK]", 160, 160, 2);
  
  // 7. Ein paar grafische Spielereien: Gefüllte Kreise
  // fillCircle(x, y, radius, farbe)
  tft.fillCircle(60, 210, 10, TFT_MAGENTA);
  tft.fillCircle(160, 210, 10, TFT_CYAN);
  tft.fillCircle(260, 210, 10, TFT_YELLOW);
}

void loop() {
  // Der Hauptcode, der wiederholt ausgeführt wird.
  // Hier bleibt es erstmal leer, da sich unser Bildausschnitt nicht verändert.
}

Als Board wählst du ESP32 Dev Module und beim Upload die Boot Taste drücken.

Der Text ist zu sehen, aber erst mal nicht spannend.




Nun mal was auslesen und steuern:

DHT11 anschießen, Temperaturwert auf dem Display erscheint und die LED schalten

Benötigte Bibliothek:
TFT_eSPI
XPT2046_Touchscreen

Verdrahtung:

Beiliegendes 4 adriges Adapterkabel nehmen und an Anschluss IO2:4P1.25mm anklemmen.
Ein DHT11 an Plus an Rot, Minus an Schwarz und Daten an Gelb anschließen. Blaues Kabel bleibt frei.

Arduino Sketch:

#include <TFT_eSPI.h>                  // Bibliothek für das TFT-Display (Thin-Film-Transistor)
#include <XPT2046_Touchscreen.h>       // Bibliothek für den Touchscreen
#include <DHT.h>                       // Bibliothek für den DHT11-Sensor (Digital Humidity and Temperature)

// DHT11 Sensor Setup
#define DHTPIN 27
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Touchscreen Setup
#define TOUCH_CS 33
#define TOUCH_IRQ 36
#define TOUCH_CLK 25
#define TOUCH_MISO 39
#define TOUCH_MOSI 32

SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);

// TFT-Display Setup
TFT_eSPI tft = TFT_eSPI();

// GPIO-Pins (General Purpose Input/Output) der verbauten RGB-LED (Red, Green, Blue)
// Hinweis: Diese LEDs leuchten, wenn der Pin auf LOW (0 Volt) geschaltet wird (aktiv-low)
#define LED_R 4
#define LED_G 16
#define LED_B 17

bool ledState = false; // Speichert, ob die LED gerade an oder aus ist
unsigned long lastSensorUpdate = 0; // Merker für die Zeitsteuerung

void setup() {
  Serial.begin(115200);
  dht.begin();

  // WICHTIG: Hintergrundbeleuchtung des CYD einschalten
  pinMode(21, OUTPUT);
  digitalWrite(21, HIGH);

  // Touchscreen initialisieren
  touchscreenSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, TOUCH_CS);
  ts.begin(touchscreenSPI);
  ts.setRotation(1); // Querformat

  // LED-Pins (Light Emitting Diode) als Ausgang setzen
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);
  updateLED(); // Schaltet die LED beim Start sicher aus

  // Display initialisieren
  tft.init();
  tft.setRotation(1); // Querformat (320 x 240 Bildpunkte)
  tft.fillScreen(TFT_BLACK);

  // --- Grafisches Grundgerüst zeichnen (wird nur 1x im Setup gemacht) ---
  
  // 1. Kopfzeile mit abgerundeten Ecken
  // fillRoundRect(x, y, breite, höhe, radius, farbe)
  tft.fillRoundRect(10, 10, 300, 40, 8, TFT_DARKCYAN);
  tft.setTextColor(TFT_WHITE, TFT_DARKCYAN); 
  tft.drawCentreString("Prilchen.de - Sensor-Station", 160, 20, 2); // Zentriert mit Font 2

  // 2. Optische Rahmen für die Messwerte
  tft.drawRoundRect(10, 60, 300, 100, 8, TFT_DARKGREY);
  
  // 3. Feste Beschriftungen (werden nicht mehr überschrieben)
  tft.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
  tft.drawString("Temperatur:", 25, 75, 2);
  tft.drawString("Luftfeuchte:", 25, 115, 2);

  // 4. Den Button (Schaltfläche) zum ersten Mal zeichnen
  drawButton();
}

void loop() {
  unsigned long currentMillis = millis();

  // Temperaturanzeige alle 2000 ms (2 Sekunden) aktualisieren
  // Der DHT11 ist recht langsam, 2 Sekunden Pause sind ideal
  if (currentMillis - lastSensorUpdate >= 2000) {
    lastSensorUpdate = currentMillis;

    float temp = dht.readTemperature();
    float hum = dht.readHumidity();

    // Wir setzen TextPadding (Hintergrund-Füllung), um flimmerfrei zu überschreiben.
    // Die Bibliothek füllt automatisch 80 Bildpunkte Breite in der Hintergrundfarbe.
    tft.setTextPadding(80); 

    // Temperatur in Gelb anzeigen
    tft.setTextColor(TFT_YELLOW, TFT_BLACK);
    String tempStr = String(temp, 1) + " C"; // Kommazahl auf 1 Stelle runden
    tft.drawString(tempStr, 180, 70, 4); 

    // Feuchtigkeit in Hellblau anzeigen
    tft.setTextColor(TFT_CYAN, TFT_BLACK);
    String humStr = String(hum, 1) + " %";
    tft.drawString(humStr, 180, 110, 4); 
    
    tft.setTextPadding(0); // Padding wieder ausschalten, damit andere Texte nicht gestört werden
  }

  // Touchscreen auswerten
  if (ts.tirqTouched() && ts.touched()) {
    TS_Point p = ts.getPoint();

    // Koordinaten an das Display-Raster (320x240) anpassen
    int x = map(p.x, 200, 3700, 0, 320);
    int y = map(p.y, 240, 3800, 0, 240);

    // Entprellung: Nur alle 300 Millisekunden einen Touch-Druck zulassen
    static unsigned long lastTouch = 0;
    
    // Prüfen, ob der Touch innerhalb unseres gezeichneten Buttons lag
    if (x >= 80 && x <= 240 && y >= 170 && y <= 230 && millis() - lastTouch > 300) {
      lastTouch = millis();
      ledState = !ledState; // Zustand umkehren (aus AN wird AUS und umgekehrt)
      updateLED();          // LED hardwareseitig schalten
      drawButton();         // Button auf dem Display neu zeichnen
    }
  }
}

// Funktion, um die Schaltfläche optisch ansprechend zu zeichnen
void drawButton() {
  // Wenn LED an ist -> Roter Button ("Ausschalten"). Wenn LED aus ist -> Grüner Button ("Einschalten").
  uint16_t buttonColor = ledState ? TFT_RED : TFT_DARKGREEN;
  
  // Einen großen, abgerundeten Button zeichnen
  tft.fillRoundRect(80, 175, 160, 50, 10, buttonColor);
  
  // Einen weißen Rand als "Highlight" hinzufügen
  tft.drawRoundRect(80, 175, 160, 50, 10, TFT_WHITE);

  // Text zentriert auf dem Button platzieren
  tft.setTextColor(TFT_WHITE, buttonColor);
  if (ledState) {
    tft.drawCentreString("LED AUS", 160, 190, 4);
  } else {
    tft.drawCentreString("LED AN", 160, 190, 4);
  }
}

// Funktion, um die Hardware-LED zu steuern
void updateLED() {
  if (ledState) {
    // LED einschalten (Wir nutzen hier als Beispiel nur die rote LED)
    digitalWrite(LED_R, LOW);   // LOW bedeutet bei dieser LED: AN
    digitalWrite(LED_G, HIGH);  // HIGH bedeutet: AUS
    digitalWrite(LED_B, HIGH);
  } else {
    // Alle Farbkanäle ausschalten
    digitalWrite(LED_R, HIGH);  
    digitalWrite(LED_G, HIGH);
    digitalWrite(LED_B, HIGH);
  }
}

Ergebnis:

Temperaturwerte werden aktuell angezeigt und LED auf der Rückseite lässt sich per Touch auf dem Display schalten.


Andere Varianten von CYD:

Wer einen der größeren Varianten der CYD vorliegen hat, wie zum Beispiel den ESP32-3248S035R, muss nicht viel an den Beispielen ändern.

  1. Anpassungen in der User_Setup.h (TFT_eSPI Bibliothek)
    Damit das Display überhaupt etwas anzeigt, müsst ihr in der Konfigurationsdatei der Display-Bibliothek (User_Setup.h) folgende Änderungen vornehmen:

Display-Treiber: Das 2,8-Zoll-Board (ESP32-2432S028) nutzt meist den ILI9341-Treiber. Das 3,5-Zoll-Board nutzt den ST7796.

Auflösung: Die Auflösung ändert sich von 240 x 320 auf 320 x 480 Pixel.

Hintergrundbeleuchtung (Backlight): Der Pin für das Backlight (TFT_BL) wechselt von Pin 21 auf Pin 27.

2. Anpassung der Koordinaten im Sketch:

Da das Display 320×480 Pixel statt 240×320 Pixel hat, müsst ihr in ihren eigenen Sketches die x- und y-Koordinaten anpassen. Wenn ihr im alten Code beispielsweise einen Button bei y = 300 platziert haben, klebte dieser am unteren Rand. Beim 3,5-Zoll-Display hängt er nun in der Luft, weil der Bildschirm noch 180 Pixel weiter nach unten geht.


Übersicht weiterer Umsetzungsmöglichkeiten

MethodeBeschreibungFür wen geeignet
Arduino IDE (manuell)Direkte Programmierung mit TFT_eSPI & TouchScreen.hFortgeschrittene Bastler
EEZ StudioVisuelle GUI-Erstellung mit automatischer Code-GenerierungEinsteiger & GUI-Fans
LVGL mit Arduino IDEProfessionelle GUI mit Widgets, Animationen, ThemesFortgeschrittene Entwickler
Adafruit GFXAlternative Display-Library, einfacher aber weniger performantMinimalisten & Lernende
VS Code mit PlatformIOModerne Entwicklungsumgebung mit besserem ProjektmanagementProfis & Power-User
Web-basierte Toolsz. B. ESP Web Tools für OTA-Upload & GUI-EditorSchnelle Tests & Updates

Vorschau:

Es wird ein Teil 2 geben, in dem ich zeige wie ich mit dem kostenlose GUI Erstellungstool EEZ Studio an einem ESP32-3248S035 eine Wetterstation erstelle mit passendem 3D Druck Gehäuse.

,
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzerkomfort bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst und hilft uns zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.