In diesem Tutorial lernst du, wie du ein 2,8 Zoll 240×320 TFT ILI9341 Touch Display mit einem WEMOS Lolin32 lite (ESP32) unter Verwendung der TFT_eSPI Bibliothek steuerst.
Die Anleitungen und der Code funktionieren mit kleinen Anpassungen auch für andere ESP32-Boards und TFTs, solange das Display den ILI9341 Displaytreiber und den XPT2046 Touchcontroller verwendet.
Benötigte Teile
Du benötigst einen ESP32 und ein 2,8 Zoll TFT Touch Display mit einer Auflösung von 240×320 Pixeln und einem ILI9341 Displaytreiber-IC. Einige Kabel und ein Breadboard können ebenfalls nützlich sein.

2,8 Zoll TFT ILI9341 Touch Display

ESP32 lite

USB-Datenkabel

Dupont-Kabelset

Breadboard
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
2,8″ TFT ILI9341 Touch Display Modul
Es gibt einige Varianten und Klone dieses 2,8 Zoll Display-Moduls, die sich aber meist sehr ähneln und alle bzw. die meisten funktionieren sollten. Das TFT-Display hat eine Auflösung von 240×320 Pixeln mit 65K RGB-Farben und wird über SPI mit dem ILI9341 Displaytreiberchip gesteuert.
Zusätzlich verfügt das Display über einen resistiven Touchscreen mit einem XPT2046 Touchcontroller-IC. Außerdem gibt es auf der Rückseite einen MicroSD-Kartenslot, den du beispielsweise zum Speichern von Bildern nutzen kannst. Das Bild unten zeigt die Vorder- und Rückseite des Display-Moduls.

Das Display-Modul hat einen eingebauten Spannungsregler und kann mit 3,3V … 5V an VCC betrieben werden. Allerdings gibt es keinen Logikpegelwandler, was bedeutet, dass du nicht direkt ein Arduino Uno, das mit 5V Logik arbeitet, an die SPI-Schnittstelle des Moduls anschließen kannst, das mit 3,3V arbeitet!
Anschluss des TFT ILI9341 Display Moduls an Arduino
Wenn du das Display mit einem Arduino verwenden möchtest, benötigst du einen Pegelwandler. Du kannst Spannungsteiler oder einen richtigen level shifter module verwenden. Als Notlösung Techtonics wird empfohlen, 10k Widerstände auf die SPI-Leitungen zu setzen:

Das wird wahrscheinlich funktionieren (ich habe es nicht ausprobiert), aber die Verwendung eines richtigen level shifter module wäre eine zuverlässigere und sicherere Lösung. Alternativ kannst du einfach einen Mikrocontroller verwenden, der mit 3,3V Logik arbeitet, wie den ESP32, den wir hier verwenden.
Betrieb des TFT ILI9341 Touch Display Moduls mit 3,3V
Wenn du weißt, dass du das Display-Modul mit 3,3V betreiben wirst (VCC=3,3V), kannst du den Spannungsregler (U1) umgehen, indem du die Jumper-Pads mit der Bezeichnung J1 auf der Rückseite des Moduls schließt (lötst). Siehe Bild unten:

Das kann das Display potenziell stabiler laufen lassen, da du den Spannungsabfall des Reglers vermeidest, und es reduziert auch den Stromverbrauch minimal. Siehe das Schaltbild des Spannungsreglers unten und wie der J1 Jumper die Verbindung beeinflusst:

Ich habe J1 nicht geschlossen (offen gelassen wie es ist) und das Display funktionierte einwandfrei, aber falls du Stabilitätsprobleme hast, kannst du versuchen, J1 zu schließen.
Allerdings kannst du, sobald du J1 gelötet (geschlossen) hast, keine 5V mehr an VCC anlegen! Du musst 3,3V an VCC verwenden!
Pinbelegung des TFT ILI9341 Touch Display Moduls
Das Bild unten zeigt die Rückseite des Display-Moduls mit den Anschluss-Pins. Du siehst zwei Gruppen: die Pins für den Touchcontroller und die SPI-Pins für das Display darunter:

Die folgende Tabelle, entnommen aus lcdwiki, listet die einzelnen Pins und ihre Funktionen auf:
| Nummer | Pin-Bezeichnung | Beschreibung |
|---|---|---|
| 1 | VCC | 5V/3,3V Stromversorgung |
| 2 | GND | Masse |
| 3 | CS | LCD Chip-Select-Signal, Low-Level aktiviert |
| 4 | RESET | LCD Reset-Signal, Low-Level Reset |
| 5 | DC/RS | LCD Register-/Daten-Auswahl-Signal, High-Level: Register, Low-Level: Daten |
| 6 | SDI(MOSI) | SPI-Bus Schreib-Daten-Signal |
| 7 | SCK | SPI-Bus Taktsignal |
| 8 | LED | Hintergrundbeleuchtung, wenn nicht gesteuert, mit 3,3V verbinden |
| 9 | SDO(MISO) | SPI-Bus Lese-Daten-Signal, wenn du die Lese-Funktion nicht brauchst, nicht anschließen |
| 10 | T_CLK | Touch SPI Bus Taktsignal |
| 11 | T_CS | Touchscreen Chip-Select-Signal, Low-Level aktiviert |
| 12 | T_DIN | Touch SPI Bus Eingang |
| 13 | T_DO | Touch SPI Bus Ausgang |
| 14 | T_IRQ | Touchscreen Interrupt-Signal, Low-Level wenn Berührung erkannt |
Anschluss des TFT ILI9341 Touch Displays an ESP32
Das folgende Bild zeigt, wie das Touch Display Modul an einen WEMOS Lolin32 lite (ESP32) angeschlossen wird:

Es sind einige Verbindungen herzustellen, und die folgende Tabelle sollte helfen. Beachte, dass die SDI(MOSI) und SCK Leitungen der SPI-Schnittstelle zwischen dem Touch- und dem TFT-Display-Controller geteilt werden:
| ESP32 | TFT | Touch |
|---|---|---|
| 5 | CS | – |
| 4 | – | T_CS |
| 17 | RESET | – |
| 16 | DC | – |
| 23 | SDI(MOSI) | T_DIN |
| 18 | SCK | T_CLK |
| 19 | – | T_DO |
| 22 | LED | – |
Du könntest Pin 19 des ESP32 auch mit SDO(MISO) verbinden, aber da wir keine Daten vom TFT-Display-Controller lesen, brauchen wir das nicht, und es wurde berichtet, dass dies in manchen Fällen Probleme verursacht. Ich habe nicht Pin 19 mit SDO(MISO) verbunden und das Display funktionierte einwandfrei.
Beachte, dass wir auch T_IRQ des Display-Moduls unverbunden lassen. Dieser Pin signalisiert, ob eine Berührung auf dem Display erkannt wurde, und du könntest ihn beispielsweise verwenden, um den ESP32 aus dem Tiefschlaf zu wecken. In diesem Tutorial implementieren wir diese Funktion jedoch nicht.
Die Verkabelung ist recht komplex, und ich habe zwei Breadboards verbunden, um den ESP32 und das TFT-Display darauf zu platzieren. Die gute Nachricht ist, dass bis auf Masse (GND) alle Verbindungen auf einer Seite des ESP32 liegen, was die Verkabelung etwas vereinfacht. Das Bild unten zeigt meinen Aufbau:

Hintergrundbeleuchtungssteuerung für TFT ILI9341 Touch Display
Beachte, dass die Hintergrundbeleuchtungs-LED des Moduls über einen Transistor geschaltet wird und wir sie daher direkt über einen GPIO steuern können, in unserem Fall wird Pin 22 des ESP32 verwendet. Siehe das Schaltbild der LED-Steuerung unten:

Touchcontroller für TFT ILI9341 Touch Display
Wie bereits erwähnt, ist der Touchcontroller für das Display-Modul ein XPT2046. Das folgende Schaltbild zeigt, wie der Controller innerhalb des Display-Moduls angeschlossen ist.

SD-Karten-Sockel für TFT ILI9341 Touch Display
Schließlich verfügt das Display-Modul über einen SD-Karten-Sockel. Das Bild unten zeigt das Schaltbild für diesen SD-Karten-Sockel. Intern ist er nur mit VCC und GND verbunden.

Die SPI-Schnittstelle (SD_CS, SD_MOSI, SD_CLK) ist über externe Pins auf der Rückseite des Moduls zugänglich. Beachte aber, dass SD_MISO nicht verbunden ist:

Wir werden den SD-Karten-Sockel in diesem Tutorial jedoch nicht verwenden.
Code für TFT ILI9341 Touch Display mit TFT_eSPI Bibliothek
In diesem Abschnitt nutzen wir die TFT_eSPI library, um das Display und die Touch-Schnittstelle zu steuern. Um diese Bibliothek zu installieren, öffne den Library Manager, suche nach „TFT_eSPI“ und drücke „INSTALL“. Nach erfolgreicher Installation sollte es so aussehen:

Als nächstes müssen wir die korrekte Projektordnerstruktur anlegen. Öffne deine Arduino IDE und erstelle ein Projekt „tft_test“ und speichere es (Speichern unter …). Dadurch wird ein Ordner „tft_test“ mit der Datei „tft_test.ino“ darin erstellt. In diesem Ordner erstelle eine weitere Datei namens „tft_setup.h„. Dein Projektordner sollte dann so aussehen

Wenn du mehr über diese Einrichtung und weitere Optionen zur Konfiguration eines TFT-Displays für die TFT_eSPI Bibliothek erfahren möchtest, schau dir das How to configure TFT_eSPI Library for TFT display Tutorial an.
tft_setup.h für TFT ILI9341 Touch Display
Nachdem der Projektordner mit den zwei Dateien erstellt wurde, kopiere den folgenden Konfigurationscode für das TFT-Display in die tft_setup.h Datei:
// tft_setup.h // 2.8" TFT Touch Display // 240x 320, Driver: ILI9341 #define ILI9341_DRIVER //#define ILI9341_2_DRIVER #define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define TFT_RGB_ORDER TFT_BGR // WEMOLS Lolin32 lite #define TFT_CS 5 #define TFT_RST 17 #define TFT_DC 16 #define TFT_MOSI 23 // SDA // HW MOSI #define TFT_SCLK 18 // SCL // HW SCLK #define TFT_MISO 19 // HW MISO #define TFT_BL 22 // LED back-light #define TFT_BACKLIGHT_ON HIGH #define TOUCH_CS 4 #define TOUCH_CLK TFT_SCLK #define TOUCH_DIN TFT_MOSI #define TOUCH_DO TFT_MISO #define LOAD_GLCD #define LOAD_FONT2 #define LOAD_FONT4 #define LOAD_FONT6 #define LOAD_FONT7 #define LOAD_FONT8 #define LOAD_GFXFF #define SMOOTH_FONT #define SPI_FREQUENCY 27000000 #define SPI_READ_FREQUENCY 20000000 #define SPI_TOUCH_FREQUENCY 2500000
Der wichtigste Teil dieser Konfigurationsdatei ist die Auswahl des richtigen Displaytreibers. In unserem Fall ist das der ILI9341. Beachte, dass es eine alternative Definition gibt:
#define ILI9341_DRIVER //#define ILI9341_2_DRIVER
Wenn du Probleme mit deinem Display hast, versuche den ILI9341_2_DRIVER anstelle des ILI9341_DRIVER.
Wichtig sind auch die Konstanten für Breite und Höhe des Displays sowie die Reihenfolge der Farbkanäle.
#define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define TFT_RGB_ORDER TFT_BGR
Wenn dein Inhalt abgeschnitten erscheint oder die Farben falsch dargestellt werden, stelle sicher, dass du die Dimensionen (TFT_WIDTH, TFT_HEIGHT) und die TFT_RGB_ORDER korrekt eingestellt hast. Die TFT_RGB_ORDER kann TFT_BGR oder TFT_RGB sein.
Beachte, dass es auch eine Definition gibt, um Schwarz und Weiß zu invertieren (#define TFT_INVERSION_ON), falls du dieses Problem hast. Für alle möglichen Einstellungen siehe die User_Setup.h Datei.
Als nächstes folgen die Pin-Definitionen. Ich verwende einen WEMOS Lolin32 lite (ESP32) und die Pins für Hardware SPI sind (MOSI=23, MSIO=19, SCK=18):
#define TFT_CS 5 #define TFT_RST 17 #define TFT_DC 16 #define TFT_MOSI 23 // SDA // HW MOSI #define TFT_SCLK 18 // SCL // HW SCLK #define TFT_MISO 19 // HW MISO #define TFT_BL 22 // LED back-light #define TFT_BACKLIGHT_ON HIGH #define TOUCH_CS 4 #define TOUCH_CLK TFT_SCLK #define TOUCH_DIN TFT_MOSI #define TOUCH_DO TFT_MISO
Je nach Mikrocontroller können diese Pins unterschiedlich sein. Du solltest die Pins für Hardware SPI finden und verwenden, da dies eine schnellere Kommunikation und somit ein schnelleres Display ermöglicht. Die anderen Pins kannst du frei wählen.
Die Konstanten für die Schriftarten musst du normalerweise nicht ändern. Solltest du jedoch Speicherprobleme bekommen, kannst du ungenutzte Schriftarten aus der Liste entfernen.
#define LOAD_GLCD ... #define SMOOTH_FONT
Die Konstanten für SPI_FREQUENCY und SPI_TOUCH_FREQUENCY sind etwas kritisch. Sind sie zu hoch, siehst du verzerrte Inhalte und die Touch-Erkennung wird unzuverlässig. Die hier angegebenen Werte haben bei mir funktioniert, aber bei einem anderen Mikrocontroller oder Display musst du sie eventuell verringern.
#define SPI_FREQUENCY 27000000 #define SPI_READ_FREQUENCY 20000000 #define SPI_TOUCH_FREQUENCY 2500000
Testcode für TFT ILI9341 Touch Display
In diesem Abschnitt zeige ich dir einen Testcode, mit dem du das Display und die Touch-Erkennung ausprobieren kannst. Kopiere einfach den folgenden Code in die tft_test.ino Datei:
// tft_test.ino
#include "tft_setup.h"
#include "TFT_eSPI.h"
TFT_eSPI tft = TFT_eSPI();
uint16_t cal[5] = { 0, 0, 0, 0, 0 };
void calibrate_touch() {
if (!cal[1]) {
tft.fillScreen(TFT_BLACK);
tft.calibrateTouch(cal, TFT_YELLOW, TFT_BLACK, 20);
Serial.printf("cal[5] = {%d, %d, %d, %d, %d};\n",
cal[0], cal[1], cal[2], cal[3], cal[4]);
}
}
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
calibrate_touch();
tft.setTouch(cal);
tft.fillScreen(TFT_BLACK);
tft.setTextFont(1);
tft.setTextSize(2);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextDatum(CC_DATUM);
tft.drawString("Makerguides", TFT_HEIGHT / 2, TFT_WIDTH / 2);
}
void loop() {
uint16_t x, y;
if (tft.getTouch(&x, &y)) {
Serial.printf("%d %d\n", x, y);
tft.fillCircle(x, y, 2, TFT_YELLOW);
}
}
Der Code beginnt mit dem Einbinden der benötigten Bibliothek und der Konfigurationsdatei.
#include "tft_setup.h" #include "TFT_eSPI.h"
Als nächstes erstellen wir das TFT-Display-Objekt und ein Array, um die Kalibrierungsparameter für den Touchscreen zu speichern:
TFT_eSPI tft = TFT_eSPI();
uint16_t cal[5] = { 0, 0, 0, 0, 0 };
calibrate_touch Funktion
Anfangs sind die Kalibrierungsparameter auf Null gesetzt, aber wir füllen sie später. Die calibrate_touch() Funktion wird verwendet, um diese Kalibrierungsparameter abzurufen:
void calibrate_touch() {
if (!cal[1]) {
tft.fillScreen(TFT_BLACK);
tft.calibrateTouch(cal, TFT_YELLOW, TFT_BLACK, 20);
Serial.printf("cal[5] = {%d, %d, %d, %d, %d};\n",
cal[0], cal[1], cal[2], cal[3], cal[4]);
}
}
Wenn sie noch nicht gesetzt sind (!cal[1]), löscht die Funktion den Bildschirm und ruft dann tft.calibrateTouch() auf, die das cal Array füllt. Diese Funktion zeichnet Pfeile (in gelber Farbe mit schwarzem Hintergrund und einer Größe von 20 Pixeln) in die Ecken des Displays, und der Benutzer muss die Ecken berühren, um das Display zu kalibrieren. Mehr dazu später. Sobald wir die cal Parameter haben, geben wir sie im Serial Monitor aus.
setup Funktion
In der setup() Funktion initialisieren wir den Serial Monitor und den TFT-Bildschirm, kalibrieren den Touchscreen falls nötig und geben dann den Text „Makerguides“ auf dem Display aus:
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
calibrate_touch();
tft.setTouch(cal);
tft.fillScreen(TFT_BLACK);
...
tft.drawString("Makerguides", TFT_HEIGHT / 2, TFT_WIDTH / 2);
}
loop Funktion
In der loop() Funktion rufen wir getTouch auf, um zu prüfen, ob eine Berührung erkannt wurde. Falls ja, geben wir die Koordinaten der Berührung im Serial Monitor aus und zeichnen einen kleinen gelben Kreis an der Berührungsstelle:
void loop() {
uint16_t x, y;
if (tft.getTouch(&x, &y)) {
Serial.printf("%d %d\n", x, y);
tft.fillCircle(x, y, 2, TFT_YELLOW);
}
}
Hintergrundbeleuchtungssteuerung
Schließlich, wenn du die Hintergrundbeleuchtungs-LED des Displays ausschalten möchtest, um Strom zu sparen, wenn das Display nicht benutzt wird, kannst du den TFT_BL Pin auf LOW setzen:
pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, LOW); // Switch off Backlight
Ich nutze das in diesem Code nicht, aber es funktioniert. Das kann nützlich sein, um Strom zu sparen, wenn du den ESP32 in den Tiefschlaf versetzt und nur bei Berührung aufwecken möchtest.
Im nächsten Abschnitt lernen wir, wie man den Touchscreen kalibriert.
Kalibrierung des TFT ILI9341 Touch Displays
Wenn du den Code hochlädst und ausführst, startet das Display im Kalibrierungsmodus. Das ist nötig, um den Touchscreen zu kalibrieren, damit die tft.getTouch(&x, &y) Funktion die korrekten Bildschirmkoordinaten für eine Berührung zurückgibt.
Im Kalibrierungsmodus zeigt das Display zuerst einen gelben Pfeil in der linken oberen Ecke. Benutze den Stift und berühre das Display an der Ecke, auf die der Pfeil zeigt. Wenn du größere/kleinere Pfeile oder eine andere Farbe oder Hintergrund möchtest, kannst du die Parameter für die tft.calibrateTouch() Funktion ändern:
tft.calibrateTouch(cal, TFT_YELLOW, TFT_BLACK, 20);
Wenn die Berührung erfolgreich registriert wurde, zeigt das Display als nächstes einen Pfeil in der rechten oberen Ecke. Berühre diese Ecke und wiederhole den Vorgang, bis alle vier Ecken berührt wurden. Das Bild unten zeigt die vier Pfeile während der vier Schritte des Kalibrierungsprozesses:

Nach der vierten Berührung zeigt das Display den Text „Makerguides“ in der Mitte (ohne Pfeile):

Am wichtigsten ist, dass der Code die Kalibrierungsparameter cal im Serial Monitor ausgibt. Du solltest eine Ausgabe ähnlich der folgenden sehen:
cal[5] = {397, 3495, 294, 3495, 7};
Kopiere diese Werte und ersetze die Null-Kalibrierungsparameter für die cal Konstante (cal[5] = { 0, 0, 0, 0, 0 }) im tft_test.ino Sketch durch die Werte, die du im Serial Monitor abgelesen hast:
// tft_test.ino
...
uint16_t cal[5] = {397, 3495, 294, 3495, 7};
void calibrate_touch() {
...
Kompiliere und lade den Code dann erneut hoch.
Berührungen mit TFT ILI9341 Touch Display erkennen
Wenn die cal Parameter gesetzt sind, überspringt der Code den Kalibrierungsschritt, gibt direkt „Makerguides“ aus und ist bereit, Berührungseingaben zu erkennen. Benutze deinen Stift, und an der Berührungsstelle sollte ein gelber Punkt erscheinen. Unten ein Bild des Displays, auf dem ich mit Berührungseingaben herumspiele:

Wenn die gelben Punkte versetzt zu der Stelle erscheinen, an der du das Display berührt hast, ist die Kalibrierung falsch. Du kannst die Kalibrierung wiederholen, indem du die cal Parameter wieder auf Null setzt (cal[5] = { 0, 0, 0, 0, 0 }).
Beachte, dass der Serial Monitor die erkannten Berührungskoordinaten ausgibt, sobald die Kalibrierung abgeschlossen ist. Du kannst dies nutzen, um die Kalibrierung zu überprüfen oder um beispielsweise Buttons zu erstellen, die auf Berührung reagieren.
241 51 240 54 240 53 241 47 243 46 ...
Siehe das Digital Clock with CrowPanel 3.5″ ESP32 Display Tutorial für ein Beispiel.
Fazit
In diesem Tutorial hast du gelernt, wie du ein 2,8 Zoll 240×320 TFT ILI9341 Touch Display mit einem WEMOS Lolin32 lite (ESP32) unter Verwendung der TFT_eSPI Bibliothek steuerst.
Wenn du Schwierigkeiten mit der TFT_eSPI Bibliothek hast, könnte unser How to configure TFT_eSPI Library for TFT display helfen. Es gibt auch eine ausführliche Diskussion here zu Problemen mit diesem speziellen Display.
Solltest du ein anderes Display mit einem ST7735 Treiber-IC haben oder lernen wollen, wie man die Adafruit Bibliothek verwendet, könnte das Interface TFT ST7735 Display with ESP32 tutorial für dich nützlich sein.
Und für runde TFT-Displays schau dir das Digital Clock on CrowPanel 1.28″ Round Display Tutorial an.
Wenn du Kommentare hast, hinterlasse sie gerne im Kommentarbereich.
Viel Spaß beim Tüfteln ; )

