ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display)
DC Utilities V5: MP3-Player
Bevor ihr mit diesem Artikel startet, solltet ihr euch zum Einstieg in die Materie zuerst ein wenig einlesen und die Hardware und das Pinout des TouchScreen-ESP32 ESP32-2432S028R-kennenlernen.
Außerdem solltet ihr euch eine Entwicklungsumgebung mit PlatformIO einrichten, wie in diesem Artikel besprochen. Danach solltet ihr noch den Artikel Programmierung des Displays mit der TFT_eSPI-Library lesen, in dem ihr lernt, wie wir etwas auf dem Display ausgeben.
Sowie den Artikel über die Programmierung des Touchscreen Digitizer XPT2046, der im Cheap Yellow Display steckt.
Damit wäre dann die Hardware-Ansteuerung von Display und Touchscreen bewerkstelligt. Nun kommt als Dialogsystem die LGVL Library obendrauf. In diesem Artikel erfahrt ihr, wie man diese für die weitere Verwendung einbindet und mit der Standard-LVGL-Demo (die, mit dem das Gerät ausgeliefert wurde) testet.
Im darauffolgenden Artikel haben wir dann gelernt, wie man LVGL-Dialoge entwirft und mittels Events steuert. Damit haben wir genügend gelernt, um unsere eigenen Anwendungen mit LVGL-Dialogen zu programmieren.
Doc Cool's Utilities V5
Im vorletzten Artikel habe ich die erste Version von Doc Cool's Utilities vorgestellt und die Idee, die dahinter steckt. Dies soll eine Sammlung von nützlichen Programmen sein, die über ein Menü aufgerufen werden sollen.
Da ich bemerkt habe, das es auch einige englischsprachige Leser gibt, versuche ich, die Dialog im Programm in (einfachem) Englisch zu halten, damit mehr Leute etwas davon haben, denn die fertige Firmware wird es wieder zum Download geben.
Außerdem spare ich mir, den kompletten Source-Code immer wieder zu wiederholen. Der steht ja schon in den vorhergehenden Artikeln. Ich werde also nur noch auf die neu hinzugekommenen Sachen eingehen. Das macht die ganzen Erklärungen kürzer und übersichtlicher.
Aus technischen Gründen, nämlich damit die WLAN-Antenne und evtl. weitere Antenne nicht von der Hand verdeckt werden und weil es der natürlicher Handhaltung am meisten entspricht, habe ich mich für ein Design der Dialoge im Portrait-Modus, also hochkant, entschieden.
Hardware: PC-Speaker
Dass und wie der Lautsprecher am besten um einen Widerstand um die 100 Ohm angeschlossen wird, habe ich bereits im letzten Artikel beschrieben. Da steht auch alles über die Audio-Library, die wir hier verwenden.Mein Cheap Yellow Display ist inzwischen in das selbst entworfene 3D-gedruckte Gehäuse V3 eingezogen. Der Lautsprecher hat nun eine Buchse im Gehäuse und lässt sich damit jetzt ein- und ausstecken.
Neues Utility: MP3-Player
Die ESP32-AudioI2S-Library kann nicht nur zu MP3- und anderen Streams im Internet Verbindung aufnehmen und sie abspielen. Nein, sie kann natürlich auch lokale Audio-Dateien wiedergeben. Das geht ganz einfach. Zum Beispiel mit der Zeile
audio.connecttoFS(SD, "/test.wav");
Eigentlich sollte die Library dabei folgende Formate beherrschen:
- .mp3: Verlustkomprimierte Audio-Dateien nach eine Erfindung des Fraunhofer IIS - Abspielen funktioniert sehr gut.
- .wav: Windows-Wave-Format, schon alt und verlustfrei, aber große Dateien - Führt manchmal zu Abstürzen beo großen Dateien
- .m4a: AAC-komprimiertes Audio-Format, verlustbehaftet mit guter Kompression - - Abspielen funktioniert gut
- .flac: verlustbehaftete Audio-Kompression - braucht viel Speicher und funktioniert nur selten
- .ogg/.vorbis: verlustbehaftete Audio-Kompression ähnlich MP3 - funktioniert leider nur selten
- .opus: verlustbehaftete Audio-Kompression ähnlich MP3 - funktioniert leider nur selten
Da .wav-Dateien aber Abstürze (das CYD führt dann einfach einen Reset durch) sehr unschön sind, werden mit dem MP-Player nur .MP3, .M4A und .AAC-Dateien gesucht und abgespielt.
Die Suche nach Dateien geschieht folgendermaßen: Es werden alle Dateien mit den entsprechenden Endungen unterhalb des Verzeichnisses /mp3 auf der SD-Karte gesucht. Findet die Suchroutine ein Unterverzeichnis, so wird dieses auch nach MP3-Dateien durchsucht. Da die Suchroutine rekursiv programmiert ist, darf im Unterverzeichnis wieder ein Unterverzeichnis sein und darin wiederum eines. Es ist also kein Problem, seine MP3-Ordner samt Interpreten- oder Album-Unterordnern (oder beides) nach /mp3 zu kopieren. Doch sollten es nicht mehr als ein paar Hundert sein, sonst wird die Sache zu langsam. Auch wenn schon die schnellere subdir.getNextFileName(&isDir)-Methode des SD-Filesystems benutzt wird.
Es wird immer im Wiederholungsmodus abgespielt, das heißt: ist ein Lied zuende, geht es mit dem nächsten weiter. Ist das letzte Lied zuende, geht es mit dem ersten wieder los. Man kann mit dem rechten Button zwischen Normal- und Zufallswiedergabe wechseln. Die Buttons zeigen immer an, was passieren wird, wenn man darauf klickt. Beim Start ist man im normalen Wiedergabemodus (1, 2, 3, 4, 5 ...). Das Symbol mit dem überkreuzten Pfeilen wechselt in den Zufallsmodus (z. B. 1, 5, 3, 4, 5, 2 ...). Das ist schön, wenn man bei vielen MP3s nicht immer dieselbe Reihenfolge hören will. Hörbücher etc. muss man natürlich der Reihe nach abspielen.
Ansonsten gibt es noch drei Knöpfe zum Pausieren und zum Sprung zum Vorherigen und Nächsten Lied.
Falls das Lied MP3-id3-Information (ID3-Data) enthält, fischt uns die Audio-Library heraus und gibt sie uns an die Funktion void audio_id3data(const char *info) weiter, wo wir sie dann auswerten können:
void audio_id3data(const char *info){ //id3 metadata
debug_print("id3data ");debug_println(info);
String tag = info;
if (tag.substring(0,7) == "Artist:") {
lv_label_set_text (lab_audio_artist, tag.substring(8).c_str());
} else if (tag.substring(0,15) == "OriginalArtist:") {
lv_label_set_text (lab_audio_artist, tag.substring(16).c_str());
} else if (tag.substring(0,6) == "Album:") {
lv_label_set_text (lab_audio_album, tag.substring(7).c_str());
} else if (tag.substring(0,6) == "Title:") {
lv_label_set_text (lab_audio_title, tag.substring(7).c_str());
} else if (tag.substring(0,5) == "Year:") {
lv_label_set_text (lab_audio_year, tag.substring(6).c_str());
}
}
Auch das Ende des Liedes wird einem mitgeteilt, wenn gewünscht:
void audio_eof_mp3(const char *info){ //end of file
debug_print("eof_mp3 ");debug_println(info);
// danach weiterspielen ohne file macht reset
// nächstes File
do_mp3_player_sel_file(-1);
}
Außer den MP3-Metadaten zeigt der MP3-Player noch das physische Verzeichnis und den Dateinamen auf der SD-Karte an und hat zwei Slider. Einen zur Einstellung der Lautstärke. Wird der ganz links auf Null gezogen, hält automatisch auch das Lied an.
Der zweite Slider zeigt die Position in der Wiedergabe an. Er startet links und wandert im Verlauf des Liedes ganz nach rechts, wo das Lied endet. Man kann den Slider verschieben, um im Lied vor- und zurückzuspulen oder an eine bestimmte Position zu springen. Sehr praktisch.
Unten schließt der Dialog wieder mit Statuszeile und Zurück-Button ab. In der Statuszeile werden auch alle weiteren Infos der Audio-Library ausgegeben. Meist geht das aber sehr schnell, so dass eigentlich nur die stehenbleibende Bitrate stehen bleibt zum Lesen.
Firmware Download via ESP Web Tools
Du möchtest die Firmware schon einmal ausprobieren, ohne die Entwicklungsumgebung zu installieren oder zu programmieren?
Kein Problem. Schließe einfach dein ESP32 an einen USB-Port deines PC an und klicke auf den deinem Gerät entsprechenden Button:
Demo und Video
Ich habe wieder ein kleine Demonstrations-Video gemacht, dass die neuen Dialoge in Aktion zeigt:Mein Fazit zu dieser Programmier-Episode
Da das Abspielen von MP3-Files mit der AudioI2S-Library so einfach ist, gab es da nicht allzuviel zu tun beziehungsweise zu lernen. Außer vielleicht die Callback-Routinen bedienen.Ein wenig wurde mein super ersten Eindruck von der Library allerdings getrübt. Ich hätte mir ein besseres Fehlermanagement gewünscht. Es muss ja eigentlich nicht gleich ein Reset geben, nur weil das Lied zuende ist und man audio.loop() dann ohne Lied aufruft. Da könnte man dann doch auch einfach eine Fehlermeldung ausgeben. Auch ist nicht gerade toll, dass es einen Reset bei so mancher meiner WAV-Dateien gibt, insbesondere, wenn diese länger waren.
Trotzdem ist das eine tolle Library, die mir viel Arbeit abnimmt. Und meckern ist ja auch nicht das probate Mittel zur Abhilfe. Entweder man meldet solche Fehlerchen dem Entwickler über Github, oder - insbesondere, wenn man merkt, dass dieser keine Zeit oder Lust mehr hat, was ich hier aber nicht glaube - man erstellt einen Fork und arbeitet selbst an einer bereinigten Version. Da mir wiederum die Zeit dafür ein wenig fehlt bzw. ich meine Prioritäten anders gesetzt habe und auch weil ich mit den kleinen Unzulänglichkeiten leben kann, lass ich das sein. Ich wollte diese Begebenheiten aber nicht verschweigen, damit ihr darauf achten und sie umschiffen könnt. Oder bitte nicht als Meckern missverstehen.
Ich werde noch ein wenig weiter mit der Library herum experimentieren. Mal schauen, was die noch so drauf hat...
Ansonsten war die Hauptsache, die ich diesmal dazu gelernt habe, der Umgang mit dem SD-Speicher. Da gibt es ewig viele Beispiele zu und die muss ich hier nicht wiederholen. Dadurch sie selbst einmal angewendet und angepasst zu haben lernt man aber natürlich mehr als einmal drüberfliegen und "achso geht das" zu sagen oder komplette Funktionen per copy and paste in den eigenen Code zu übernehmen.
Weitere Aussichten
Sobald der Bedarf entsteht, oder ich eine nette Idee für das nächste Utility habe, geht es mit dem nächsten Beispiel hier weiter. Dann werden Doc Cool's Utilities um ein weiteres Tool erweitert und es gibt wieder Erklärung und Anleitung, wie man das selbst machen kann.Quellen, Literaturverweise und weiterführende Links
(1) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Vorstellung Hardware und Pinout
(2) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Erste Schritte Programmierung der RGB LED
(3) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Programmierung des Displays mit der TFT_eSPI-Library
(4) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Programmierung des Touchscreen Digitizer XPT2046
(5) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Einbinden der LVGL Library
(6) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Dialoge entwerfen mit der LVGL Library
(7) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - LVGL-Dialog / Utilities: RGB-LED Color Changer
(8) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Utilities Test Display und Touch
(9) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Utility V3 Settings und WLAN-Scan
(10) LVGL-Dokumentation für Version 9.1
(2) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Erste Schritte Programmierung der RGB LED
(3) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Programmierung des Displays mit der TFT_eSPI-Library
(4) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Programmierung des Touchscreen Digitizer XPT2046
(5) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Einbinden der LVGL Library
(6) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Dialoge entwerfen mit der LVGL Library
(7) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - LVGL-Dialog / Utilities: RGB-LED Color Changer
(8) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Utilities Test Display und Touch
(9) ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display) - Utility V3 Settings und WLAN-Scan
(10) LVGL-Dokumentation für Version 9.1