

Ziele des Projekts
- Fotos von einem SD-Kartenleser laden und auf einem TFT anzeigen
- Beschreibung zum Foto anzeigen
Verwendete Hardware
Pinbelegung des TFT.Displays mit 480×320 Pixeln
Die Pins für den SD-Kartenleser (im Beispiel: SD-CS und SDO) müssen in der Pin-Leiste vorhanden sein:

Pinbelegung am ESP32-Wroom
SD_CS: 15 (SD-Kartenleser)
SDO (MISO): 19 (SD-Kartenleser)
LED: 5V
SCK: 18
SDI (MOSI): 23
LCD_RS (DC): 2
LCD_RST (RST): 4
LCD_CS (CS): 5
GND
VCC: 5V
Die Reihenfolge der Pins kann unterschiedlich sein. Achte auf die Beschriftung der Pins.
Fotos erstellen
Du benötigst eine Mini-SD-Karte, sie muss mit FAT-32 formatiert sein. Bei neu gekauften SD-Karten ist das in der Regel der Fall. Fotos dürfen maximal das Format von 480×320 Pixeln haben und müssen im Format bmp vorliegen. Du kannst beliebige Fotos skalieren und entsprechend abspeichern.
Ich verwende hierzu das Programm GIMP. Beachte die notwendigen Einstellungen beim Speichern des Bildes.

Natürlich darf das Bild auch kleiner als 480×320 Pixel sein. Bei der Funktion drawBMP kannst du die Startposition auf der x- und y-Achse festlegen.
Fotos zum Download
![]() | ![]() | ![]() | ![]() | ![]() |
koeln.bmp | overath_bahnhof.bmp | lindos.bmp | braunwald.bmp | dresden_frauenkirche.bmp |
![]() | ![]() | ![]() | ![]() | ![]() |
chartres.bmp | strand.bmp | berlin_olympia.bmp | uni_bonn.bmp | duenen.bmp |
![]() | ![]() | ![]() | ![]() | ![]() |
st_michelle.bmp | ijlst.bmp | monschau.bmp | gaios.bmp | koeln_deutz.bmp |
Sowohl das TFT-Display als auch der SD-Kartenleser verwenden den SPI-Bus. Jedes Gerät benötigt aber eigene Datenleitungen. Der ESP32-Wroom verfügt über zwei SPI-Busse, die gleichzeitig nutzbar sind.
Benötigte Bibliotheken


Die verwendete Bibliothek für das Display mit 480×320 Pixeln kann nicht über die Bibliotheksverwaltung installiert werden. Sie muss herunter geladen werden:
https://github.com/prenticedavid/Adafruit_ST7796S_kbv
und mit
Sketch -> Bibliothek einbinden -> zip-Bibliothek hinzufügen
installiert werden.
Das Programm
Bibliotheken einbinden und Variable definieren
Die SPI-Pins für das TFT-Display entsprechen der Standardkonfiguration VSPI und müssen nicht deklariert werden.
Für den SD-Kartenleser sind einige Parameter erforderlich:
- der Typ der SD-Karte (3)
- die Geschwindigkeit (SD_SCK_MHZ)
- Der Datenpin (CSPin)
Der Parameter Beschreibung entscheidet darüber, ob eine Beschreibung zum Foto angezeigt wird. Die Anzeige der Beschreibung nimmt einen kleinen Teil des Fotos weg.
#include "SdFat.h"
#include "Adafruit_ST7796S_kbv.h"
#include "Adafruit_ImageReader.h"
// ESP32-WROOM
#define TFT_CS 5
#define TFT_RST 4
#define TFT_DC 2
/*
SD VSPI Standard-Pins
CLK 18
MOSI 23
MISO 19
CS 5
*/
// Objekt tft der Bibliothek Adafruit_ST7796S_kbv erstellen
Adafruit_ST7796S_kbv tft = Adafruit_ST7796S_kbv(TFT_CS, TFT_DC, TFT_RST);
// Objekt SD der Bibliothek SdFat erstellen
SdFat SD;
// Objekt des Kartenlesers wird an das Dateisystem der SD-Karte übertragen
Adafruit_ImageReader reader(SD);
Adafruit_Image Bild;
// Farben
#define SCHWARZ 0x0000
#define WEISS 0xFFFF
#define BLAU 0x001F
// 3 = FAT32
#define SD_FAT_TYPE 3
// SPI-Geschwindigkeit
#define SPI_SPEED SD_SCK_MHZ(10)
// CSPin der SD-Karte
int CSPin = 15;
// Anzeigedauer
int Intervall = 6000;
bool Beschreibung = true;
Der setup-Teil
Der setup-Teil startet den SD-Kartenleser und das TFT-Display. Der erfolgreiche Start des SD-Kartenlesers wird im Seriellen Monitor und auf dem TFT-Display angezeigt.
void setup()
{
Serial.begin(9600);
// auf serielle Verbindung warten
while (!Serial);
delay(1000);
// TFT starten
tft.begin();
tft.invertDisplay(1);
// Rotation anpassen
tft.setRotation(3);
// schwarzer Hintergrund
tft.fillScreen(SCHWARZ);
tft.setTextSize(3);
tft.setTextColor(WEISS);
tft.setCursor(1, 20);
/*
SD-Karte mit Angabe des CSPins und der SPI-Geschwindigkeit starten
wenn die Intialisierung fehlschlägt
- keine SD-Karte vorhanden
- falsche Pinbelegung
-> es wird eine Fehlermeldung angezeigt
*/
if (!SD.begin(CSPin, SPI_SPEED))
{
tft.println("Start der SD-Karte");
tft.print("fehlgeschlagen!");
Serial.println("Start der SD-Karte fehlgeschlagen!");
}
else
{
Serial.println("SD-Karte gestartet");
tft.print("SD-Karte gestartet!");
}
delay(5000);
}
Der loop-Teil
Jedes Foto muss mit drawBMP an das TFT-Display (tft) mit den x- und y-Koordinaten des Startpunktes übergeben werden.
Je nach Zustand des Parameter Beschreibung (true/false) wird eine Information zum Foto angezeigt.
Die Umlaute müssen mit tft.write() und ⇒hexadezimalen Code definiert werden.
void loop()
{
reader.drawBMP("koeln.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.setCursor(10, 295);
tft.print("K");
// ö = 0x94
tft.write(0x94);
tft.println("ln Blick vom Messeturm");
}
delay(Intervall);
reader.drawBMP("duenen.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("D");
// ü = 0x81
tft.write(0x81);
tft.print("nen Ibiza");
}
delay(Intervall);
reader.drawBMP("overath_bahnhof.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Overath Bahnhof");
}
delay(Intervall);
reader.drawBMP("rathaus.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Rathaus Bergisch Gladbach");
}
delay(Intervall);
reader.drawBMP("dresden_frauenkirche.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Dresden Frauenkirche");
}
delay(Intervall);
reader.drawBMP("chartres.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Chartres Dom");
}
delay(Intervall);
reader.drawBMP("bonn_uni.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Bonn Uni");
}
delay(Intervall);
reader.drawBMP("braunwald.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Braunwald Schweiz");
}
delay(Intervall);
reader.drawBMP("koeln_deutz.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("K");
// ö = 0x94
tft.write(0x94);
tft.println("ln Deutz");
}
delay(Intervall);
reader.drawBMP("kloentaler_see.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Kl");
// ö = 0x94
tft.write(0x94);
tft.println("ntaler See Schweiz");
}
delay(Intervall);
reader.drawBMP("sevilla.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Sevilla Kathedrale");
}
delay(Intervall);
reader.drawBMP("st_michelle.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("St. Michelle Frankreich");
}
delay(Intervall);
reader.drawBMP("dresden_bruecke.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Dresden 'Blaues Wunder'");
}
delay(Intervall);
reader.drawBMP("lindos.bmp", tft, 0, 0);
if (Beschreibung)
{
tft.setCursor(10, 295);
tft.fillRect(1, 290, tft.width(), tft.height(), 0x0120);
tft.print("Lindos Rhodos");
}
delay(Intervall);
}
Quellen
Letzte Aktualisierung: