
Wenn du das Waveshare ESP32-S3-Touch-LCD-1.47 das erste Mal in der Hand hast, ist die Erwartung oft: „Ich kopiere einfach ein paar PNGs drauf und dann zeigt das Display die an.“ So funktioniert Embedded leider nicht ganz. Das Board kann richtig schicke Oberflächen – Waveshare sagt sogar explizit, dass es LVGL „smooth“ laufen lässt – aber du musst deine Grafiken so aufbereiten, dass ein Mikrocontroller sie effizient aus Speicher oder Dateisystem ziehen kann. Und genau da entscheidet sich, ob es frustig wird oder ob du nach einer Stunde schon Menüs, Icons und Touch-Buttons auf dem Display hast.
Die gute Nachricht zuerst, weil du genau danach gefragt hast: Du brauchst keine SD-Karte, um „Grafiken“ zu machen. Eine SD/TF-Karte ist nur eine Option, wenn du Bilder später leicht austauschen willst oder sehr viele/ große Assets hast. Das Board hat zwar einen TF-Kartenslot, aber „nativ“ kannst du Grafiken auch komplett ohne Karte darstellen – entweder als gezeichnete Elemente (Text, Linien, Flächen) oder als eingebettete Bilddaten im Flash.
Was du da eigentlich vor dir hast (und warum das wichtig ist)
Das Touch-1.47er basiert auf dem ESP32-S3R8, hat PSRAM und ordentlich Flash, ein 172×320 IPS Touch-Display und spricht Display/Touch über SPI bzw. I2C. Das klingt nach Datenblatt-Blabla, ist aber praktisch: PSRAM macht LVGL erst angenehm, und 172×320 ist klein genug, dass du mit sauberen Buffern und kompakten Bildformaten sehr flüssige UIs bauen kannst.
Warum du in der Arduino IDE am besten mit den Waveshare-Demos startest
Du kannst theoretisch alles „selbst“ verdrahten: Display-Init, Backlight, Touch-Controller, LVGL Display-Driver, Flush-Callback, Tick-Timer, Touch-Read… das geht, kostet aber Zeit und ist die klassische Black-Screen-Falle.
Waveshare hat für genau dein Board eine Wiki-Seite mit Arduino-Kapitel und fertigen Beispielen – darunter GFX HelloWorld, LVGL v8, LVGL Image und SD/TF-Tests. Das ist Gold wert, weil dort nicht nur Beispiel-Code liegt, sondern auch das korrekte Zusammenspiel aus Board-Settings, Treiber-Libs und LVGL-Version.
Ein Detail, das viele unterschätzen: Waveshare nennt konkret Anforderungen wie „esp32 by Espressif Systems ≥ 3.0.0“ und in den Arduino-Infos taucht LVGL v8.4.0 auf. Wenn du wild Versions-Mix machst, bricht es gern an Stellen, die sich wie Magie anfühlen („compiliert, aber Display bleibt schwarz“ oder „lvgl.h fehlt“).
„Grafiken“ heißt beim ESP32 drei verschiedene Dinge
Bevor du dich festlegst, hilft ein sauberer Begriff:
-
Grafik zeichnen (Primitives): Text, Linien, Rechtecke, Kreise, Füllflächen – das ist „nativ“ im Sinne von: du rechnest Pixel und schickst sie ans Display. Dafür brauchst du keine Bilddateien.
-
Bilder anzeigen (Assets): Icons, Logos, Hintergründe. Die müssen irgendwo liegen: im Flash als C-Array oder als Datei (LittleFS/SD).
-
UI bauen (Widgets): Buttons, Listen, Slider, Animationen, Touch-Events. Das ist LVGL-Territorium.
Auf deinem Board sind alle drei Wege sinnvoll – je nachdem, wie „UI-lastig“ dein Projekt ist.
Weg 1: Ohne LVGL – sofort sichtbare Ergebnisse mit der GFX-Library
Wenn du einfach nur schnell etwas aufs Display bekommen willst, nimm den Ansatz aus dem Waveshare-Demo „01_gfx_helloworld“: Das Beispiel nutzt eine Arduino-GFX-Library, um das Display anzusteuern und Text auszugeben. Damit kannst du dann auch sofort eigene Sachen zeichnen: Statusanzeigen, Messwerte, Balken, simple Menüs. Das ist der schnellste Weg zu „es lebt“.
Das ist aber kein „modernes UI-Framework“. Sobald du Buttons, Layouts, Screens, Themes oder saubere Touch-Interaktion willst, wirst du praktisch automatisch bei LVGL landen.
Weg 2: LVGL in der Arduino IDE – und Bilder ohne SD (im Flash)
Das ist in der Praxis der sweet spot: Du baust dein UI mit LVGL und packst deine Icons/Logos als Daten direkt in die Firmware. Dann hat dein Projekt keine Dateisystem-Abhängigkeiten, startet schnell und ist robust.
Der typische Ablauf ist:
Du nimmst ein PNG/JPG/BMP auf dem PC und wandelst es mit dem LVGL Image Converter in ein LVGL-kompatibles Format um. Das Tool kann dir entweder C-Dateien (Arrays) oder Binärdaten erzeugen, die LVGL als Bildquelle versteht.
Danach legst du die erzeugte Datei in dein Arduino-Projekt, und in LVGL sieht das Anzeigen dann ungefähr so aus:
LV_IMG_DECLARE(my_logo); // kommt aus der konvertierten .c Datei
lv_obj_t *img = lv_img_create(lv_scr_act());
lv_img_set_src(img, &my_logo);
lv_center(img);
Wichtig ist dabei weniger der Code als die Entscheidung beim Konvertieren: Für kleine Displays nimmst du oft ein Format, das gut zu RGB565-Displays passt (weniger RAM/Flash als „volle“ 32-bit Varianten). Das ist genau die Art Entscheidung, die später darüber entscheidet, ob dein UI butterweich läuft oder ruckelt.
Der Nachteil ist klar: Wenn du das Logo ändern willst, musst du neu flashen. Für ein „fertiges“ Gerät ist das meistens völlig ok.
Weg 3: Bilder als Dateien – ohne SD, aber mit Dateisystem im Flash (LittleFS)
Wenn du Bilder später austauschen willst, aber keine SD-Karte verwenden möchtest, kannst du ein Dateisystem im internen Flash nutzen. In der Arduino-Welt ist LittleFS dafür der gängige Weg (SPIFFS wird seit Jahren als „deprecated“ behandelt, LittleFS ist die empfohlene Richtung). ([Arduino Dokumentation][3])
Das Prinzip ist simpel: Du legst Dateien (z. B. logo.bin oder je nach Setup auch logo.png) in einen „data“-Ordner, lädst sie in die Flash-Partition und lässt deine Software die Assets von dort laden. Das ist mehr Setup als „alles im Code“, aber du bekommst eine Art Mittelweg: Firmware bleibt gleich, Assets können sich ändern.
Ob du PNG/JPG direkt aus LittleFS laden willst, hängt dann wieder von Decodern ab – viele nehmen deshalb auch hier gern LVGL-Binärassets, weil das auf dem Mikrocontroller weniger Stress macht.
Weg 4: SD/TF – optional, praktisch, aber mehr bewegliche Teile
Das Board hat einen TF-Kartenslot, und Waveshare hat dafür sogar eigene SD/TF-Demos. SD lohnt sich dann, wenn du viele Assets hast (z. B. mehrere Screens mit großen Hintergründen) oder wenn du Bilder/Dateien „wie auf einem USB-Stick“ austauschen willst.
Der Preis ist Komplexität: FAT32, Kartenerkennung, Dateipfade, Decoder, Timing – alles machbar, aber eben mehr Stellen, an denen du dir Fehler einfangen kannst.
Arduino IDE: die häufigste Stolperfalle ist nicht der Code, sondern die Library-Installation
Ein Klassiker beim Nachbauen der Waveshare-Beispiele ist: Du öffnest ein Demo, drückst Compile, und es fliegt dir um die Ohren, weil lvgl.h „nicht gefunden“ wird. In einer Arduino-Forum-Diskussion zu genau diesen 1.47"-Boards wird als pragmatische Lösung beschrieben, die Libraries aus dem Waveshare-Demo-ZIP zu nehmen und sie als ZIP-Library in die Arduino IDE zu installieren (statt irgendeine LVGL-Version aus dem Library Manager zu ziehen). Das ist nicht „schön“, aber oft der schnellste Weg zu einem funktionierenden Build.
Auch bei den Board-Einstellungen wird gern etwas übersehen: USB CDC „on boot“, passende Flash/Partition/PSRAM-Einstellungen – das sind genau die Dinge, die in Community-Anleitungen rund um diese Boards immer wieder auftauchen, weil sonst Upload/Serial oder Speicher knapp wird.
Wenn du einmal ein funktionierendes Demo hast, ist der Rest plötzlich entspannt: Dann fängst du an, Screens zu bauen, Buttons zu platzieren, Touch-Events zu verdrahten und deine Grafiken Stück für Stück einzubauen.
Ein kleines mentales Modell, das dir Zeit spart
Wenn du „nativ Grafiken“ sagst, meinst du meistens eins von zwei Dingen:
- „Ich will eine Oberfläche zeichnen“ → dann reichen dir oft GFX-Primitives oder LVGL ohne Bilder (Labels, Buttons, Styles).
- „Ich will echte Bilddateien anzeigen“ → dann musst du entscheiden, wo sie liegen (Flash eingebettet / LittleFS / SD) und in welchem Format du sie am liebsten verarbeitest (konvertiert vs. PNG/JPG mit Decoder).
Auf dem Waveshare ESP32-S3 1.47" Touch ist der pragmatische Einstieg fast immer: Waveshare-LVGL-Demo zum Laufen bringen → erstes eigenes Screen-Layout → erstes Icon als LVGL-Asset im Flash. SD-Karte hebst du dir auf, wenn du wirklich einen Grund hast.
Kommentare