ESP32-2432S028 mit 2.8" Touchscreen (Cheap Yellow Display)
DC Utilities V4: Web-Radio
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 V4
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
Der PC-Speaker-Anschluss wurde zwar schon im Rahmen der Hardware-Vorstellung im ersten Artikel vorgestellt, aber heute wollen wir ein wenig genauer auf ihn eingehen, denn wir wir ihn heute für ein neues Utility, das Web-Radio benutzen.Aus dem Board befindet sich oben eine zweipolige mit "SPEAK" bezeichnete Buchse. Diese finde ich ein wenig nachteilig: Erstens geht sie vertikal nach oben ab, der Stecker steht damit also auch nach oben ab; das ist unschön. Und zweitens ist es der Formfaktor, der mich stört: hier muss nämlich ein fitzelig kleiner Stecker hinein. Glücklicherweise habe ich solch ein Kabel bei mir im Fundus gefunden und zwar war es ein Akku-Anschluss-Stecker. Leider wird der Stecker nicht mitgeliefert (der für seriell aber schon, und das ist noch wichtiger).
Der PC-Speaker-Ausgang hängt an einem TC8002D-Verstärker-Chip, der wiederum am I2S-Bus des Cheap Yellow Displays hängt. Hier liefert GPIO 26 des ESP32 das Signal für den TC8002D.
Da es nur einen Verstärker-Chip gibt, ist der Ausgang natürlich nur Mono, also nur für einen Lautsprecher. HiFi-Genuss ist also nicht zu erwarten. Wer das möchte sollte sich meinen Artikel "Kopfhöreranschluss für den Odroid-Go nachrüsten" durchlesen. der Odroid Go ist auch ein ESP32 und das von mir verwendete Modul CJMCU-1334 liefert einen kristallklaren, einwandfreien Stereo-Sound.
Wir wollen heute aber mit Mono und den eher bescheidenen Klangqualitäten des CYD vorlieb nehmen. Dazu müssen wir nicht mehr allzuviel tun. Nämlich nur einen Lautsprecher über einen Widerstand im Bereich von ein paar Hundert Ω anschließen. Am besten nimmt man ein Poti mit 1 kΩ. Das kann man dann von wenigen Ohm bis hoch zu einem Kilo-Ohm einstellen und so die Lautstärke regulieren.
Und das ist wichtig, denn das CYD mit Lautsprecher hört sich nur gut an, wenn es nicht zu laut und nicht zu leise eingestellt wird. Man kann zwar auch mit Software die Lautstärke einstellen, aber wegen des Klangs sollte man zuerst an der Hardware drehen.
Ich habe mir einen kleinen Adapter gebaut:
Das Mini-Kabel vom CYD führt in das 1kΩ-Trimm-Poti und dann zur einer "normalen" JST-Buchse mit 2.54 mm Pin-Abstand. Dafür kann ich mir nämlich die Kabel selbst crimpen und so unterschiedliche Lautsprecher ausprobieren, indem ich sie einfach anstecke.
Der Wert 1 kΩ hat sich für mich als ideal herausgestellt. Und die Bauform Trimm-Poti nimmt wenig Platz weg, ist günstig und verstellt sich nicht von selbst. Das wird einmal auf den verbauten Lautsprecher-Typ eingestellt und verschwindet dann im Gehäuse. Die eigentliche, weitere Lautstärkeregelung von "sehr leise" bis "laut, aber noch nicht zu übersteuert" kann dann per Software erfolgen.
Irgendwann habe ich mal ein paar supergünstige Lautsprecher-Kapseln gekauft.
Die sind klein und robust und nehmen nicht viel Platz weg. Die könnte man direkt im Gehäuse verbauen.
Der Klang ist nicht besonders toll, aber Sprache kann man gut verstehen.
Der Eigen-Widerstand der Kapseln ist relativ hoch, so dass man das Poti auf ein paar weniger Ohm einstellen muss.
Am andere Ende der Skala ist ein Lautsprecher, den ich mal aus einem Flachbild-Fernseher ausgebaut habe.
Dieser noch kompakte Lautsprecher, der ungefähr so breit ist wie das Cheap Yellow Display selbst, liefert einen sehr viel besseren Klang und ist durchaus auch für Musik geeignet.
Da es selbst weniger Widerstand hat, muss ich für die optimale Einstellung das Poti ein wenig verdrehen.
Obwohl es natürlich auch mit den Einstellungen für den Kapsel-Lautsprecher funktioniert.
Aber für den Sweet Spot braucht es dann doch ein bisschen Nach-Justage, die mit dem Trimmpoti sehr genau funktioniert.
Softwaretechnische Anpassungen
Nachdem jetzt hardwaretechnisch alles vorbereitet ist, geht es nun an die Software...Die wirklich sehr empfehlenswerte Library ESP32-audioI2S von schreibfaul1 nimmt uns in Sachen Audio, Web-Radio, MP3-Dekoding und so weiter die ganze Arbeit ab und ist wirklich kinderleicht zu handeln.
Wir benutzen Version 3.0 und müssen unsere platformio.ini entsprechend erweitern:
lib_deps =
bodmer/TFT_eSPI@2.5.43
nitek/XPT2046_Bitbang_Slim@2.0.0 ; https://github.com/TheNitek/XPT2046_Bitbang_Arduino_Library
lvgl/lvgl@9.1.0
https://github.com/schreibfaul1/ESP32-audioI2S.git#3.0.0
c:/users/admin/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: region `dram0_0_seg' overflowed by 14440 bytes
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
/*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/
//#define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/
//#define LV_MEM_SIZE (16 * 1024U) /*[bytes]*/
#define LV_MEM_SIZE (24 * 1024U) /*[bytes]*/
Danach ist die Compiler-Fehlermeldung mit dem RAM weg, allerdings folgt sogleich der nächste Fehler:
Linking .pio\build\cyd_v3\firmware.elf
Retrieving maximum program size .pio\build\cyd_v3\firmware.elf
Checking size .pio\build\cyd_v3\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
Error: The program size (1360621 bytes) is greater than maximum allowed (1310720 bytes)
RAM: [=== ] 27.4% (used 89864 bytes from 327680 bytes)
*** [checkprogsize] Explicit exit, status 1
Flash: [==========] 103.8% (used 1360621 bytes from 1310720 bytes)
Aber warum eigentlich nur 1280 KB Flash? Hat der ESP32 nicht 4 MB = 4096 KB Flash-Speicher !?
Hat er! Wir müssen PlatformIO bzw. dem Linker darin nur sagen, dass er ein anderes Speichermodell benutzen soll, wo mehr Flashspeicher für das Programm reserviert wird. Die betreffende Anweisung in der platformio.ini heißt:
[env]
platform = espressif32@6.5.0
board = esp32dev
framework = arduino
board_build.partitions = huge_app.csv
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x300000,
eeprom, data, 0x99, 0x310000,0x1000,
spiffs, data, spiffs, 0x311000,0xEF000,
Linking .pio\build\cyd_v3\firmware.elf
Retrieving maximum program size .pio\build\cyd_v3\firmware.elf
Checking size .pio\build\cyd_v3\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [=== ] 27.4% (used 89864 bytes from 327680 bytes)
Flash: [==== ] 43.3% (used 1360621 bytes from 3145728 bytes)
Neues Utility: Web Radio
Zuerst einmal möchte ich die Funktionen kurz im Gesamtheit erklären, bevor ich dann auf die Einzelelemente und deren Programmierung eingehe.
Zu Anfang wird eine Tabelle mit Web-Radio-Stationen und deren URLs gefüllt. Hier habe ich schon so etwa 20 meines Erachtens hörenswerte Stationen eingelistet.
Man muss einfach nur auf eine Station in der Tabelle klicken und meistens hört man dann den Radiosender innerhalb eines Sekundenbruchteils. Der Namen des Senders und der Titel des Liedes werden oben angezeigt. Unten in der Statusleiste erhält man weitere Informationen. Durch die Tabelle kann man mit Wischbewegungen wie vom Smartphone her gewohnt scrollen.
Man kann diese Liste aber auch selbst erweitern und auf SD Karte speichern. Da gibt man im Text-Feld die URL des Radiosenders an und klickt dann auf "connect". An Status, Sender und Titel und natürlich dem Umstand, ob man den Sender auch hört, erkennt man, ob die URL richtig ist. Dann klickt man auf das "add"-Symbol mit dem Pfeil nach unten. Das fügt die URL mit dem Sendernamen ans Ende der Liste an.
Die selbst erweiterte Liste kann man mit click auf "save" auf die SD Karte speichern. Beim nächsten Start wird die Stationsliste geladen und der eigene Sender ist dann dabei uns auswählbar. Will man die Senderliste eventuell neu sortieren oder gleich viele Sender hinzufügen, dann öffnet man die "/settings/webradio_stations.ini" auf dem PC im Editor und macht das dort, das ist einfacher.
Nun zu den Einzelheiten: Das Webradio zu laufen zu bekommen, ist dank der Library sehr einfach:
WiFi.begin(WLAN_SSID, WLAN_PASS);
audio.forceMono(true);
audio.setVolumeSteps(101); // 0...100
audio.setVolume(50);
audio.connecttohost("http://stream.radiobluebell.com:8000/bluebell_hi");
while (1) audio.loop();
Darum "kratzt" die Musik auch, wenn man Dinge in den Dialogen umstellt.
Die Audio-Library funktioniert übrigens auch nur mit ESP32-Varianten mit 2 oder mehr Core. Der ESP32-WROOM32 hat 2 Core, der neue ESP32-S3 auch, der neue ESP32-S2 aber zum Beispiel nicht. Siehe dazu auch meine Vergleichstabelle Die neuen espressif ESP32 Chip Varianten im Vergleich.
audio.forceMono(true); sorgt (denke ich) dafür, dass die Stero-Kanäle gemischt werden und damit über nur einen Lauftsprecher wiedergegeben werden.
Mit der Lautstärkeregelung habe ich es mir einfach gemacht. Denn mit audio.setVolumeSteps(101); stelle ich den Lautstärkenbereich auf 0 bis 100 ein. So kann ich direkt die Slider-Value benutzen, um die Lautstärke zu setzen. Es war nicht einfach, auf einem Bildschirm in Hochkant ein halbwegs intuitive Benutzeroberfläche zu kreieren, ohne scrollen zu müssen. Okay, durch die Senderliste muss man natürlich scrollen, aber die drei Lieblingssender kann man sofort antippen, wenn man sie an den Anfang der Liste stellt (.ini editieren).
Aus diesem Grund steht der Sendername auch ganz oben neben dem Logo und der Title ist einzeilig. Dieser scrollt normalerweise, wenn er zu lang ist. Da das Scrollen des Titels aber die Musikwiedergabe ein ganz klein wenig verschlechtert, sollte sie auch nach Klick auf das Feld still stehen und mit "..." abgekürzt werden.
Leider kann man LVGL-Labels kein Click-Event zuweisen, so dass ich ein wenig in die Trickkiste greifen musste:
while (Screen == "web_radio") { // wird zu "menu", wenn back geklickt
handleLVGL();
// da ich keinen Event auf ein label hängen kann, selbst abfragen
if (xptTouched()) {
xptPosition(&xptX,&xptY,&xptZ,&tftX,&tftY);
//if (tftX >= lv_obj_get_x(lab_audio_title) && tftX <= lv_obj_get_x(lab_audio_title) + lv_obj_get_width(lab_audio_title)) {
// if (tftY >= lv_obj_get_y(lab_audio_title) && tftY <= lv_obj_get_y(lab_audio_title) + lv_obj_get_height(lab_audio_title)) {
if (tftX >40 && tftY > 55 && tftY < 80) { // ist schneller
LV_LOG_USER ("firing evt_lab_audio_title_click()");
evt_lab_audio_title_click();
// warten bis wieder losgelassen
while (xptTouched()) audio.loop();
}
} // endif xptTouched
for (int i=0; i < 5; i++) if (audio.getVolume() > 0) audio.loop();
}
Das Umschalten zwischen scrollendem Label und "..."-Abkürzung war dann in dem "künstlichen" Event ein Leichtes:
void evt_lab_audio_title_click() { // No special events are sent by the Label. See the events of the Base object too.
// zwischen scrolling und ... umschalten
if (lv_label_get_long_mode(lab_audio_title) == LV_LABEL_LONG_SCROLL_CIRCULAR) {
lv_label_set_long_mode (lab_audio_title, LV_LABEL_LONG_DOT);
} else {
lv_label_set_long_mode (lab_audio_title, LV_LABEL_LONG_SCROLL_CIRCULAR);
}
}
Wie man Das Textfeld mit dem virtuellen Keyboard verknüpft, hatten wir auch schon. Aber diesmal bin ich auf einen kleinen Bug gestoßen, der vielleicht an dem knappen RAM liegt: die Tastatur schließt bei Fokusverlust aus dem Feld nicht immer. Darum habe ich jetzt die Taste mit dem OK-Haken unten rechts dazu hergenommen, die Tastatur zu schließen. Diesen also benutzen, wenn sich das Keyboard nicht auf normalem Weg schließen lassen will.
Die Knöpfe hatten wir auch schon mehrmals. Bitte dort nachlesen, wie die programmiert werden. Das Gleiche gilt auch für die Tabelle.
Mehr "Zauber" steckt eigentlich nicht hinter dem Web-Radio. Den Großteil der Arbeit nimmt einem die wirklich tolle Audio-Library ab. Meinen Dank an "schreibfaul1" an dieser Stelle.
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
Die Hürde mit dem limitierten RAM und Flash-Speicher zu nehmen, hat mich wieder eine Menge Allgemeines zum ESP32 lernen lassen.Die Befürchtungen zu einer grauenhaften Sound-Ausgabe, die ich beim Einlesen in die neue Hardware hatte und die HexeguitarDIY für seine CYD-Version noch beschrieb, scheinen nicht mehr zu gelten, zumindest fand ich die Sound-Ausgabe jetzt nicht so schlimm, als dass ich da meinen würde, zu riskieren, an den SMD-Widerständen herumlöten zu müssen.
Die Audio-Library ist toll. Da werde ich noch ein paar Features von ausprobieren, die wir dann sicher in der nächsten Version sehen.
Weitere Aussichten
Natürlich kann die Audio-Library nicht nur MP3-Streams aus dem Internet wiedergeben. Das geht natürlich auch mit lokalen Dateien auf der SD-Karte. Wie man einen MP3-Player für das CYD programmiert, zeige ich euch im nächsten Teil.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