UPDATE 12.02.26:
Das Gehäuse wurde optimiert. Die SD-Karte kann nun ohne Auseinanderschrauben entnommen und neu mit Videomaterial bestückt werden. Gleichzeitig gibt es nun ein kleines Sichtloch, um den aktuellen Ladezustand des TP 4056 Batterielademoduls anzuzeigen: ROT = Batterie lädt, GRÜN = Batterie geladen.
Nachdem mein erster Neffe vor Jahren mit seiner eigenen Phoniebox beglückt wurde, war es an der Zeit seinem jüngeren Bruder eine kleine Freude zu machen.
Mein Neffe ist ein waschechter Pufferküsser mit einer ausgeprägten Begeisterung für Züge, insbesondere für alte Dampflokomotiven. Da er regelmäßig sämtliche Bildschirme einnimmt um Videos von Schienenfahrzeugen zu konsumieren, habe ich mich ans Werk gesetzt und ihm ein kleines feines Gerät gebaut, mit dem er diese eigenständig schauen kann.
Initialer Funke für den Eigenbau war ein Video des Youtube Kanals thelastoutpostworkshop, das mir zufällig über den Weg lief:
Herausgekommen ist der LocoTV, ein kleiner Handheld im Hochkantformat, mit einem gedrucktem Gehäuse, einer Batterie und Ladeelektronik:

Der finale LocoTV
Hardware
Zentrale Rolle in diesem Projekt spielt das Cheap Yellow Display, kurz auch CYD genannt. Der Name ist etwas sonderbar, beschreibt aber anschaulich, worum es sich hierbei handelt: Es ist eine kompakte Displayplatine mit einer Auflösung von 320x240 Pixeln und Touch-Funktionalität mit diversen Zusatzkomponenten, bspw. einem Helligkeitssensor, einer LED und einem Micro SD-Kartenleser. Die Platine kommt in gelber Farbe daher. Angetrieben wird es durch einen ESP32 Microcontroller. Das Display ist in unzähligen Varianten erhältlich, die sich hauptsächlich in den Anschlüssen der Stromversorgung (Micro USB vs. USB-C), SPI-Taktung, aber auch in der eingesetzten Variante des ESP32 unterscheiden. Ich nutze für dieses Projekt die Version 2.0 des CYD mit USB-C Anschluss.
Die Materialkosten für die Hardware belaufen sich mit Versand auf ca. 30 €:
| Funktion | Bezeichnung | Kosten |
|---|---|---|
| Display | Cheap Yellow Display 2.8" 320x240 (ESP32-2432S028) | 8,29 € |
| Spannungswandler | MT3608 High Efficiency 1.2MHz 2A DC-DC Step Up Converter | 1,89 € |
| Power Button | Blue circle light, 16MM, Latching, 6V Wichtig ist, dass es sich um einen Button mit Rastfunktion (latching switch) und keinen Drucktaster (momentary switch) handelt. |
2,19 € |
| Batterielademodul | TP4056 1A Standalone Linear Li-lon Battery Charger with Thermal Regulation in SOP-8 | 1,39 € |
| Batterie | NCR18650B Pointed 18650 3400mAh 3.7V Li-ion | 5,69 € |
| Batteriehalterung | 18650 Battery Holder Case | 4,97 € |
| JST-Connector | JST 1.25mm MX1.25 4 Pin | 2,89 € |
| SD-Karte | Eine 8 GB SD-Karte flog bei mir noch rum. |
0,00 € |
Software
Wie bereits in der Einführung erwähnt, stammt der Code vom Autoren thelastoutpostworkshop. Das Repository esp32-2432S028_video_player ist bei Github verfügbar. Als Codebase für meinen Eigenbau habe ich jedoch den Fork cyd-video-player verwendet, da dieser Support für den Touchscreen ergänzt. Dies ermöglicht, mit einem kindgerechten Touch auf das Display, das nächste Video abzuspielen.
Alle meine Anpassungen sind im Repository schneekluth/locotv verfügbar:
Die benötigten Schritte zum Bezug der Software:
- Den Code als
ZIPDatei herunterladen und entpacken. - Den Ordnernamen von
locotv-maininlocotvumbenenen. - Ein Doppelklick auf die Datei
locotv.inoöffnet die Arduino IDE.
SD Karte vorbereiten
Im ersten Schritt muss die SD-Karte im FAT32-Dateisystem formatiert werden:
Anschließend in den heruntergeladenen Ordner locotv/ ins Verzeichnis SD Content/ wechseln. Darin befindet sich ein Ordner mjpeg mit Beispielvideos. Dieser Ordner muss auf die SD-Karte kopiert werden:
Die SD-Karte ist damit einsatzbereit und kann in den SD-Kartenleser vom Cheap Yellow Display gesteckt werden.
Das Cheap Yellow Display kann nun per USB mit dem Computer verbunden werden. Ab Werk begrüßt das Display den Nutzer mit einer Demo-Anwendung, mit der auch der Touchscreen ausprobiert werden kann.
Arduino IDE
Programmiert habe ich das Displayboard mit der Arduino IDE in Version 2.3.5. Dazu muss, sofern nicht bereits erfolgt, als erstes der ESP32 in der Arduino IDE als Board hinterlegt werden.
Dazu die Einstellungen der IDE mit CTRL+, aufrufen und auf den Button hinter dem Eingabefeld mit der Bezeichnung Additional board manager URLs klicken:
In das sich öffnende Textfeld muss die folgende URL eingetragen und anschließend mit OK bestätigt werden:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
Der ESP32 ist nun in allen gängigen Varianten mit der Arduino IDE nutzbar und steht im Board Manager zur Verfügung.
Board konfigurieren
Um den ESP32 als Board zuweisen zu können, muss zuerst der Board Manager unter Tools > Board > Board Manager… aufgerufen werden. Ins Suchfeld den Begriff esp32 eingeben und anschließen im Dropdown Menü die Version 3.2.0 auswählen und installieren:
Weiterführend muss als Microcontroller der Eintrag ESP32 Dev Module ausgewählt und der korrekte Port des USB-Anschluss zugewiesen werden:
Anschließend muss nur noch unter Tools > Upload Speed die Baudrate auf den Wert 115200 gesetzt werden und schon ist das Board programmierbereit.
Libraries installieren
Folgende Libraries müssen in den expliziten Version verwendet werden. Dazu, analog wie im Board Manager, in der Arduino IDE die jeweiligen Versionen im Library Manager unter Tools > Manage Libraries suchen und installieren:
| Library/Framework | Version |
|---|---|
| GFX Library for Arduino | 1.6.0 |
| JPGEGDEC | 1.8.2 |
Zusätzlich liegt in dem heruntergeladenen Ordner noch eine lokale Bibliothek TFT_Touch_v0.3.zip für die Touchscreen-Unterstützung bei. Diese muss in der Arduino IDE importiert werden. Dazu unter Sketch > Include Library > Import .ZIP Library… klicken und die Datei TFT_Touch_v0.3.zip auswählen.
Code Upload
Die Datei locotv.ino kann aus der Arduino IDE mit dem Shortcut CTRL+U kompiliert und auf das Cheap Yellow Display geladen werden:
Treten beim Kompilieren keine Fehler auf, sollten nach dem Upload die zuvor auf die SD-Karte kopierten Beispielvideos auf dem Display erscheinen. Durch berühren des Displays wird zum nächsten Video gewechselt.
Code Anpassungen
Das Cheap Yellow Display existiert in zigfachen Ausführungen, die sich nicht immer gleich verhalten. Ich habe für meine Version und mein Vorhaben insgesamt drei Änderungen am Code vorgenommen:
-
Die Farben des Displays invertieren:
vorhergfx->fillScreen(RGB565_BLACK); // gfx->invertDisplay(true); // on some cheap yellow models, display must be inverted Serial.printf("Screeen size Width=%d,Height=%d\n", gfx->width(), gfx->height());nachhergfx->fillScreen(RGB565_BLACK); gfx->invertDisplay(true); // on some cheap yellow models, display must be inverted Serial.printf("Screeen size Width=%d,Height=%d\n", gfx->width(), gfx->height()); -
Zusätzlich muss für meine gewählte Einbaurichtung im Gehäuse der Portraitmodus des Displays gespiegelt werden, indem die Werte
setRotation()undtouch.setRotation()angepasst werden:vorhergfx->setRotation(0); touch.setRotation(0);nachhergfx->setRotation(2); touch.setRotation(2); -
Das Display mit
80 Mhzstatt40 MhzTaktung per SPI betreiben:vorher// Some model of cheap Yellow display works only at 40Mhz //#define DISPLAY_SPI_SPEED 80000000L // 80MHz #define DISPLAY_SPI_SPEED 40000000L // 40MHznachher// Some model of cheap Yellow display works only at 40Mhz #define DISPLAY_SPI_SPEED 80000000L // 80MHz //#define DISPLAY_SPI_SPEED 40000000L // 40MHz
Eigene Videos erstellen
Ideale Quelle für Videos von Lokomotiven sind YouTube Shorts. Diese sind, dem spinösen Zeitgeist verschuldet, im Hochkantformat vorhanden und somit optimales Ausgangsmaterial, wenn das Display in dieser Ausrichtung betrieben wird.
Im Folgenden gilt es Videos herunterzuladen und ins Motion Jpeg Format Format zu konvertieren. Das Format MJPEG wird gewählt, da der ESP32 hardwareseitig die Funktion besitzt JPEG-Dateien zu Encoden und Decoden.
Für den Download und die Konvertierung der Videos nutze ich zwei Kommandozeilen-Tools:
Beide Tools können unter Windows 11 einfach über die Paketverwaltung winget installiert werden. Dazu das Terminal öffnen und den Einzeiler eintippen:
winget install yt-dlp.yt-dlp Gyan.FFmpegNach der Installation muss das Terminal geschlossen und erneut geöffnet werden.
Einzelkonvertierung
Als Beispiel für die einzelne Konvertierung eines Videos dient dieser Short. Seine URL lautet: https://www.youtube.com/shorts/cKKkR6O_jYQ.
Zum Herunterladen kann nun yt-dlp im Terminal verwendet werden:
cd ~\Desktop
yt-dlp "https://www.youtube.com/shorts/cKKkR6O_jYQ" -o testUnd schon befindet sich das Video mit dem Dateinamen test.webm auf dem Desktop.
Zur Konvertierung sind im Repository des ursprünglichen Autoren diverse ffmpeg Kommandos gelistet. Diese skalieren Videos jedoch nur auf die benötigte Bildschirmauflösung von 320x240 Pixel. Dies ist ein Problem, da YouTube Shorts in der Regel hochkant im Format 16:9 aufgenommen werden. Das Display besitzt jedoch ein Bildschirmverhältnis von 4:3. Ich habe das Kommando angepasst, dass mit ffmpeg im ersten Schritt ein Zoom in das Video und anschließend ein Zuschnitt auf die 320x240 Pixel erfolgt. Somit gehen in der Höhe zwar Teile des Videos verloren, jedoch entstehen so keine schwarzen Balken auf der linken und rechten Seite neben dem Video.
Das folgende optimierte Kommando wird zur Konvertierung der heruntergeladenen Datei test.webm in das mjpeg Format verwendet:
cd ~\Desktop
ffmpeg -y -i .\test.webm -pix_fmt yuvj420p -q:v 7 -vf "fps=24,crop=in_w:in_w*4/3:0:(in_h-in_w*4/3)/2,scale=240:-1:flags=lanczos" test.mjpegDie generierte Datei test.mjpeg liegt ebenfalls auf dem Desktop und kann so direkt auf die SD-Karte kopiert und auf dem Display abgespielt werden.
Batchkonvertierung
Da das einzelne Herunterladen und Konvertieren mühsam ist, macht es Sinn dies im Batch zu erledigen. Dazu in das Verzeichnis locotv/script wechseln. Darin liegen zwei Dateien:
./locotv/script
├── 00_convert.ps1
└── 00_videos.txtIn der Datei 00_videos.txt können nun zeilenweise Links zu YouTube Shorts mit einem Texteditor hinterlegt werden:
https://www.youtube.com/shorts/cKKkR6O_jYQ
https://www.youtube.com/shorts/S3O2S8ZE8ec
https://www.youtube.com/shorts/-1p6VCfEhfw
https://www.youtube.com/shorts/lFymosFJC1c
https://www.youtube.com/shorts/QhkMK151dy8
https://www.youtube.com/shorts/X2mo7eP74u4
https://www.youtube.com/shorts/tXyq57_Cvc0
https://www.youtube.com/shorts/Q2YHydMnHRQ
https://www.youtube.com/shorts/hI4E1KZAd84
https://www.youtube.com/shorts/Ou3pGGidRgM
https://www.youtube.com/shorts/nM4f9Vzdo4Y
https://www.youtube.com/shorts/6WNYhWgIdS4
https://www.youtube.com/shorts/ewbTSRsFC-0
https://www.youtube.com/shorts/af9Om_3LcQk
https://www.youtube.com/shorts/mKP9dpXhcx0
https://www.youtube.com/shorts/tfQvw7QjGa8Die Datei 00_convert.ps1 enthält den Code für die Konvertierung der Videos ins MJPEG-Format. Es liest zeilenweise den Inhalt der Datei 00_videos.txt ein, lädt die darin hinterlegten Videos herunter, konvertiert sie und löscht die Ursprungsdateien.
In diesem Ordner einen Rechtsklick machen und den Eintrag In Terminal öffnen auswählen:
Anschließend kann das Skript über diesen Befehl gestartet werden:
.\00_convert.ps1Das Skript 00_convert.ps1 macht im Detail folgendes in dieser Reihenfolge:
- Erstellt einen Ordner
locotv/script/mjpeg. - Lädt sämtliche Videos aus der Datei
00_videos.txtin den Ordnerlocotv/script/herunter. - Prüft mit ffprobe, ob das Video im Hochkant- oder Querformat aufgenommen wurde.
- Konvertiert das Video in MJPEG-Format. Für Hochkant- und Querformate werden unterschiedliche ffmpeg Kommandos angewandt, um keine schwarzen Balken in den Videos vorzufinden.
- Die konvertierten Dateien werden im Ordner
locotv/script/mjpegabgelegt. Ein Dateinamenpräfixportrait_(Hochkantformat) undlandscape_(Querformat) wird angewandt. - Die Ursprungsvideos werden gelöscht. Lediglich die konvertierten Videos bleiben erhalten.
Wer nicht regelmäßig mit PowerShell auf dem eigenen Computer arbeitet, muss in der Regel noch die notwendigen Rechte zur Ausführung von Skripten setzen:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSignedMAX_FILES anpassen
Der Wert
MAX_FILES scheint nur eine Rolle zu spielen, wenn mehr Videos auf der SD-Karte existieren, als in MAX_Files definiert ist. Der Wert kann beliebig hoch gesetzt werden und trotzdem starten die Videos erneut von vorne, wenn das letzte Video erreicht ist.
Der Arduino Code in der Datei locotv.ino hat per Default einen Counter, der nach jedem abgespielten Video um das Inkrement 1 erhöht wird. Die maximale Anzahl an abzuspielenden Videodateien ist leider hardgecoded und wird nicht dynamisch ermittelt. Standardmäßig steht der Wert bei 20 Dateien. Hat man mehr als 20 Dateien werden also trotzdem nur die ersten 20 Dateien abgespielt. Der Wert sollte also, gemäß der vorhandenen Anzahl an Videodateien auf der SD-Karte, angepasst werden:
#define MAX_FILES 20 // Maximum number of files, adjust as needed
Das vorgestellte PowerShell Skript zur Batch-Konvertierung mehrerer Videos ermittelt die Anzahl der Dateien und gibt diesen Wert, nach dem Konvertierungsvorgang, im Terminal aus:
Wichtig: Eine Anpassung des Codes erfordert stets auch einen neues Kompilieren und einen erneuten Upload über die Arduino IDE.
Gehäuse drucken
Ich habe in Autodesk Inventor ein simples Gehäuse, bestehend aus Ober- und Unterseite, entworfen. Die Gehäusehälften werden mittels Schrauben und passender Hülsenmuttern zusammengehalten. Die ermöglicht ein zukünftiges verschleißfreies Auseinanderbauen.
In der Unterseite finden Batteriehaltertung, Ladeelektronik und der Spannungswandler platz. In der oberen Gehäusehälfte sind das Display und der Ein-Aus-Schalter verbaut. Aussparungen für die SD-Karte und den USB-C Anschluss zum Laden der Batterie sind enthalten.
Verwendet wird das gröbste Druckprofil Draft im Cura Slicer mit einer Druckstärke von 0,3 mm auf meinem in die Jahre gekommenen Anycubic i3 Mega.
Die STL-Dateien der Gehäusehälften sind im Ordner locotv/stl zum Nachdrucken vorhanden.
Spannungswandler einstellen
Für diesen Schritt wird ein Multimeter benötigt. Als Vorbereitung für den Zusammenbau muss vorerst der Spannungswandler so eingestellt werden, dass bei 3,7 V Eingangsspannung eine Ausgangsspannung von 5 V erreicht wird, die das Display für seinen Betrieb erfordert. Dazu wird die Justierschraube auf dem MT3608 verwendet. Videos dazu gibt es im Weltnetz zu Hauf:
Die 18650er-Batterie in das Batteriegehäuse stecken, das rote Kabel an den VIN+ und das schwarze Kabel an den VIN- Kontakt anschließen. Das kann mit Krokodilsklemmen, geschickter Positionierung oder über ein temporäres Löten erfolgen. Anschließend das Multimeter auf Gleichstrommessung stellen und analog das rote Kabel des Multimeters an VOUT+ und das schwarze an VOUT- halten. Nun muss die Justierschraube des MT3608 so eingestellt werden, dass 5 V Ausgangsspannung auf dem Multimeter angezeigt wird:
Verdrahtung
Zusammenbau
Für den Zusammenbau des Gehäuses und der Verdrahtung der elektronischen Bauteile werden, neben Lötkolben und Kabelage, folgende Bauteile benötigt:
| Bauteil | Anzahl | Bezeichnung |
|---|---|---|
| M2x5 | 4 | Schrauben zur Befestigung des Displays an der oberen Gehäusehälfte. |
| M4 | 4 | Tellerkopfschrauben + Hülsenmutter, oft auch im Set als Möbelverbinder bezeichnet, mit Klemmweite von 34,2 mm zur Befestigung der oberen und unteren Gehäusehälfte. |
| Heißkleber | 1 | Zur Fixierung des Spannungsreglers, des Batteriehalters und der Ladeelektronik in der unteren Gehäusehälfte. |
Gehäuseoberseite
Im ersten Schritt wird das Display mit den M2x5 Schrauben befestigt. Es empfiehlt sich die Schrauben vorher ohne Display vorsichtig in die dafür vorgesehenen Löcher zu schrauben, um das Gewinde im PLA zu formen. Dabei immer wieder vor- und zurückschrauben, bis die benötigte Tiefe erreicht ist.
Im zweiten Schritt muss der JST-Connector auf einer Seite, direkt hinter dem Stecker, mit einem Seitenschneider abgetrennt werden. Von den vier verfügbaren Pins werden nur die beiden Äußeren in den Farben Rot und Grün verwendet. Die Mittleren können ebenfalls abgetrennt werden:
Der JST-Connector kann nun an dem vorhandenen Anschluss am Displayboard gesteckt werden.
Als finaler Schritt wird der Power Button eingesetzt. Den Feststellring habe ich aus Platzgründen entfallen lassen, da der Button auch ohne ihn gut fixiert platziert war. Theoretisch ist der Platz aber vorhanden, falls er beim Nachbau platziert werden muss.
Die Oberseite ist damit fertig bestückt und Einsatzbereit.
Gehäuseunterseite
Die Gehäuseunterseite ist anspruchsvoller. Ich habe zuerst alle Komponenten darin platziert und dann die Kabellängen markiert und zugeschnitten. Danach habe ich alle Bauteile wieder herausgeholt und zuerst alle Bauteile verlötet, die in der Unterseite platziert werden. Danach legt/stellt man die Vorderseite so nah es geht daneben und lässt für diese die Kabel länger, damit die Verbindungen nicht reißen, wenn das Gehäuse mal geöffnet werden muss:
Batterielademodul, Spannungswandler und die Batteriehalterung habe ich anschließend mit Heißkleber in der unteren Gehäusehälfte fixiert:

Klebeflächen in roter Farbmarkierung
Hochzeit
Nachdem beide Gehäusehälften montiert und verdrahtet sind, können sie zusammengefügt werden. Dabei darauf achten, dass die Kabel nicht zu sehr unter Spannung sind oder Schaden beim Schließvorgang nehmen.
Die beiden Gehäusehälften werden durch Hülsenmuttern und Schrauben der Gewindegröße M4 zusammengehalten. Das hat den Vorteil, dass nicht selber ins Druckmaterial geschraubt werden muss und eine zukünftige verschleißfreie Öffnung des Gehäuse gegeben ist. Hülsen- und Schraubenlänge kann variiert werden, solange die errechnete ideale Klemmweite von 34,2 mm erreicht wird:
Für meinen Eigenbau habe ich eine M4x18 Tellerkopfschraube und eine Hülsenmutter mit M4 Innengewinde einer Länge von 25 mm verwendet. Diese stammen aus einem IKEA Pax Schrank und haben bei IKEA die Teilenummern 100644 und 100402:
Resultat
Das Ergebnis ist ein kleines, neckische, portables Brikett, das auch in der Zukunft mit Videomaterial aller Art bespielt werden kann. Es dient nur dem Zweck der Videowiedergabe, hat keine nervige Sound-Ausgabe und der abgespielte Content liegt zu 100% in eigener Hand:
Betätigt man den Power-Button, rastet dieser ein, der LED-Ring des Buttons beginnt zu leuchten und ca. eine Sekunde später beginnt die Videowiedergabe:
Ist die Batterie einmal leer gesaugt, kann sie mit einem handelsüblichen USB-C Ladegerät wieder aufgeladen werden.
Neue Videos hinterlegen
Es wird notgedrungen immer wieder zu der Situation kommen, dass neue Videos auf der SD-Karte hinterlegt werden müssen. Da das CYD in zig Varianten existiert, ist der sicherste weg den JST-Connector, vor einem erneuten Code Upload zu trennen, bevor der USB-C anschluss mit dem Computer verbunden wird, um Voltage Backfeeding zu vermeiden.
Generell empfiehlt es sich den Wert für MAX_FILES relativ hoch, bspw. 300 anzusetzen, da so nur kein neuer Code Upload erfoderlich ist, wenn die reale anzahl der gespeicherten Video den Wert in der Variable MAX_FILES überschreitet.