Olimex ESP32-ADF

Ich lese schon länger mit, möchte mich nun mal konstruktiv (hoffentlich! :wink: einbringen.
Vor kurzem habe ich einen ESP32-ADF von Olimex erhalten. Details dazu gibt es hier. Die doku die verlinkt ist aber nicht aktuell. Im Github Repo unter Hardware gibt es das KiCad projekt für die v3, die enthält noch µSD-Reader und einige Änderungen bei den GPIOs.

Für PlatformIO gibt es (wie es aussieht) keinen Treiber für den ES8388, mit der ESP_IDF und ESP_ADF funktionieren unter VSCode die Samples bisher Problemlos. Ich hatte aber noch nicht viel Gelegenheit, das Board auf Herz und Nieren zu testen.

Ich möchte jedenfalls noch den DeepSleep-Stromverbrauch messen. Ich habe zwar keine allzugrossen hoffnungen dass der sich im µA-Bereich befinden wird, aber sicher ist sicher…

Ansonsten fehlt für einen ESPuino nur noch der RIFD-Reader sowie einige Buttons. Es sind ja 8 IOs über den eigenen UEXT-Konnector nach aussen geführt. Sollte sich also ausgehen, wenn auch nur mit alternativer Bedienung.

Da ESPuino ja auf PlatformIO setzt wird compilieren bzw. forken/mergen schwierig sein. Wobei beim Refactoring ja gerade auf einiges von der ESP-IDF zurückgegriffen wird. PIO bietet zwar viel Vorteile, ich denk aber dass Speicherverbrauch und Performance mit der ESP_IDF sicher besser gesteuert werden kann.

Ich werde mal versuchen, MP3s mit Lauterstärkeregelung und Weiter/Pause etc. von der µSD-Karte zum laufen zu kriegen. Das sollte aufgrund der Beispiele nicht allzu schwer sein, wenn mal Zeit dafür bleibt. Dann kann ich mehr über dieses Board berichten.

Man kann beim ESP-IDF auch Arduino als eine Komponente benutzen und dann auf das volle ESP-IDF zurückgreifen. Der Arduino Core basiert auch auf dem ESP-IDF, allerdings sind die verwendeten Komponenten schon vorausgewählt. Die Ressourcen lassen sich auch bei Arduino gut verwalten. Man kann aber auch mit PIO direkt das ESP-IDF verwenden.

Hallo tuniii, das ist mir bekannt, aber für das ESP-ADF funktioniert das nicht mit der aktuellen Version. Das ESP_ADF ist ja wieder eine Erweierung des ESP-IDF…

Ich hab zwar schon länger kein C mehr programmiert, aber was ich so an Code gesehen habe schreckt mich nicht wirklich ab. Vielleicht habe ich aber auch noch nicht die relevanten Stellen gesehen :wink:

Ich denke mir halt wenn das Board kompatibel ist mit der ESP_IDF/ESP_ADF ist macht es für mich wenig Sinn noch auf PIO zu setzen. Einzig der RFC522 oder so wäre da relevant. Und der ist ja nicht wirklich high-tech. (Zumindest haben die Treiber die ich gesehen habe keine 1000 LoC)

PIO wäre aber sicher Fein, wenn es ohne viel Aufwand compilieren würde.

Also mit der ESP_IDF und ESP_ADF funktionieren mit etwas gefrickel auch die Beispiele.
Der audio-Codec läuft, WLAN und dergleichen und inzwischen hab ich auch den uSD-Reader über SPI zum laufen gebracht. MP3s werden klaglos abgespielt.

Was ich noch nicht geprüft habe ist die Kopfhörerumschaltung, bisher habe ich nur die 2x 3W-Lautsprecher probiert.

Der nächste Schritt ist dann der RFID-Reader, aber da habe ich zum Thema SPI nichts gutes gelesen. Freie IOs sind ja mangelware…

SPI und RC522 ist kein problem, das hatte ich mit dem I2C-Hack einiger Platinen verwechselt… :wink:

Der RC522 funktioniert auch via SPI, mit bis zu 10MHz stabil, soweit ich das sagen kann. Mir diesem Treiber GitHub - abobija/esp-idf-rc522: C library for interfacing ESP32 with MFRC522 RFID card reader, packaged as ESP-IDF component funktioniert das mit ESP_IDF, nur wird hier der SPI mit Halb-Duplex angesprochen. Davon kann ich im Datenblatt vom RC522 aber nichts entdecken. Kann mir hier wer Hinweise geben? Klarerweise wird SPI mit PlatformIO völlig anders gehandelt, aber vielleicht weiss ja der eine oder andere Rat?

Die ESP_IDF und der darunterliegende SPI_Master unterstützt Halb-Duplex nur ohne DMA. Und ohne DMA funktioniert der SD-Reader nicht.

Also, auch wenn ich hier mit dieser Hardware und Software alleine auf weiter Flur bin, schreib ich doch hier noch mal was rein, wer weiss wers mal gebrauchen kann.

Der RC522 läuft nun auch mit regulärem SPI (also ohne HALF-DUPLEX), da waren nur kleine Anpassungen nötig. Nun funzt grundsätzlich der RC522 und auch der Cardreader am selben SPI-Bus mit DMA.

Nun kommt es aber zu I/O Fehlern beim Zugriff auf die Sd-Karte, ich denke dass der RFID-Reader da wohl dazwischenpfuscht. Ich denke Speicherfehler könnte es auch noch geben, ich prüfe noch ob alle mallocs auch DMA-Freundlich sind…

Ich schau mir grade das Handling im Espuino an, da wird der RFID-Task an einen Core gepinnt, und mit Priorität 1 gefahren. Hier hatte ich das aus dem Repo von oben mit Prio 4.

edit: Ja mit Prio 1 gibts deutlich weniger Aussetzer mehr. Denke das Verhalten kann man noch weiter optimieren, bzw. dem Puffer für den Codec erhöhen, damit es hier zu keinen Kollisionen am Bus kommt.

Frage: Kann man den RC522 so programmieren, dass er bei einer Karte selbständig einen Interrupt auslöst? Dan könnte man sich ja das ganze Polling hier sparen…?

Ja könnte man. Braucht halt einen Pin mehr. Bei Tonuino wird das auch gemacht soweit ich weiß.
Was ich allerdings nicht verstehe ist das, was du mit Prio meinst. Der RC522 läuft doch gar nicht mehr im Task!? Nur der PN5180 ist noch drin, weil ich noch nicht die Muße hatte, es ohne zu testen.

Stimmt, da steht noch ein #ifdef RFID_READER_TYPE_PN5180 dran vorher…

Das heisst der code für alle anderen Reader läuft in der main loop mit? Ist ein Core fürs decodieren abgestellt in ESPuino? Ich hab mir die Thread-Architektur noch nicht genau angesehen, bisher.

Aber jetzt wo meine grundlegende Hardware läuft, ist wohl ein guter Zeitpunkt sich darüber Gedanken zu machen. -#)

Ich habe eben mal einen Commit für den PN5180 gemacht und ihn aus seinem Task-Gefängnis befreit. Das Problem war, dass die Gesamtlaufzeit für den Scanvorgang zu lange gedauert hat, bevor @tuniii die State-Machine eingeführt hat. Das hat dazu geführt, dass anderer Kram zu sehr aufgehalten wurde. Das ist jetzt allerdings in Ordnung.

Also ja, der Code für alle Reader läuft jetzt in loop() direkt mit.

Freut mich, dann konnte ich zumindest über Umwege etwas positives beitragen. :slight_smile:

Den Treiber für den RC522 den ich verwende ist sehr rudimentär, der kennt keine Unterstützung für die Karten selbst, da muss ich mir was anderes suchen oder den von PIO portieren. Die Low-Leven-Funktionen sind ja da und taugen was.

Edit: Meine Aussetzer haben nix mit der Last zu tun, die hängen mit den Jumper-Kabeln vom RC522 zusammen. Auch wenn der inaktiv ist stört das den SPI-Bus gewaltig. 20MHz sind ja auch kein LF mehr.
Muss ich entweder kürzer kriegen, oder die Frequenz für den SD-Reader drosseln…

Wie ich sehe ist bei ESPuino der SPI auf 1MHz gesetzt, vermutlich aus demselben Grund.

Genau :slight_smile:
Ich habe am Anfang auch mit Jumperwires experimentiert und hatte da diverse Probleme.

Oh ja, aber auf einem Breadboard ist es bestimmt noch schlimmer!
Kürzen hilft sicher, bzw. schirmen oder verrdillen, aber im Versuchsstatdium ist das alles eher schwierig.

Bisher gefällt mir das ESP32-ADF Board ganz gut, Kopfhörererkennung funktioniert in Hardware, die Lautstärke ist mit den 3W-Lautsprechern genug für ein Hörspiel und die Qualität auf jeden Fall gut genug.
In Anbetracht der angespannten Liefersituation derzeit sicher ein guter Kandidat. Man muss halt auf einige IOs und damit auf einige Funktionen verzichten…

So, die Probleme mit dem SPI auf 20MHz lagen rein an der Software. Ich habe ESP-IDF auf die aktuelle 4.2.1 und die ESP-ADF auf v2.3 aktualisiert. Nun läuft alles stabil. Der RFID-Reader kann per Task gelesen werden.
Verkabelt ist momentan alles mit Jumper-Wires. Habs auch mit Oszi nachgemessen, die Flanken sind scharf. Der RC522 ist mit 1MHz angebunden, der SD-Reader mit 20Mhz (aber der ist auch onboard).

Ich habe einen MCP23017 als I2C IO-Expander gerade im Test. Mal sehen ob das mit Polling (wie hier) oder mittels interrupts besser funktioniert mit meinen Buttons. Der Drehencoder KY-040 soll ja relativ stark rauschen bzw. prellen. Man wird sehen.

Den Ansatz habe ich demletzt übrigens wieder aufgeben müssen. Das Pollen hat zu lang gedauert und man hat Störgeräusche beim Abspielen gehört. Warum das so ist weiß ich nicht, weil der Audioteil ja eigentlich in einem Task läuft. Aber auch wenn ich das höher priorisiert habe, hat sich das nicht geändert.

Kurzum: Ich habe es jetzt per Interrupt gemacht und bin die Probleme los.

Über Interrupt läuft das auch bei mir sauber. I2c mit 100kHz in Hardware. 2nd level Interrupt service routine kümmert sich um Details.
Ich habe keine Probleme mit prellen oder rauschen mit dem in Rotary encoder.

Buttons habe ich noch nicht getestet.

Warum es bei dir zu Aussetzern kommt könnte daran liegen dass i2c und spi ja in Software laufen. Mit wenig ram dürfte das schnell zu viel werden.
Ich habe allerdings auch einen wrover, also einiges an buffer.

Ich bin mir der Hardware soweit zufrieden. Kümmere mich jetzt um die Software bzw. Bedienung. Die erste Version soll Mal ohne wifi aufkommen.
Habe inzwischen lipos erhalten, bin gespannt auf den stromverbrauch im deep sleep. Bzw wird es noch lustig, alle Komponenten auch entsprechend abzuschalten auf diesem Board…

So, neuer Zwischenstand.

Die Grundfunktionen sind recht stabil, ich räume immer wieder mal den Code auf. Ich hab schon vor das ganze mal auf github oder so zu stellen, aber das ist aktuell noch zu viel Gefrickel. Vor allem den Code für den Port Expander und den Rotary Encoder möchte ich noch auslagern bzw. zumindest mal in ein File ziehen.
Zudem sind Anpassungen bei Drittkomponenten notwendig, da ist auch noch nicht klar ob bzw. wie das ohne Forks funktionieren kann.

Stromverbrauch
Das Board kriege ich mit LiPos im Deep-Sleep auf etwa 10mA runter. Das ist nicht gerade berauschend, aber ergibt immer noch eine passable Standby-Zeit.

Software-Features
Beim Runterfahren wird die aktuelle Playlist gespeichert, und beim Starten wieder der zuletzt gespielte Titel von Vorne begonnen.
Lautstärke sowie auch die Position im Titel werden nicht gespeichert bzw. wiederhergestellt.

Es gibt eine Datei (CSV) wo die 6 Bytes der RFID-Tags sowie ein string gespeichert werden. Damit wird eine Lookup-Table befüllt. Beim Auflegen der Karten wird dann nachgeschaut und bei einem Treffer der String direkt als Pfadangabe für die Wiedergabe verwendet. Beginnt der string mit „http“ dann wird zudem noch das Wlan aktiviert. Eigene Befehle oder Aktionen gibt es nicht.

Es gibt keine LEDs oder Neopixel oder sonstwas.

Für sämtliche IOs wird der MCP23017 verwendet, der über I2C angebunden ist. Derzeit wird so ein Rotary encoder unterstützt, sowie Buttons mit Aktionen bei kurzem und langen Drücken.

Für das WLAN verwende ich den exzellenten GitHub - tonyp7/esp32-wifi-manager: Captive Portal for ESP32 that can connect to a saved wireless network or start an access point where you can connect to existing wifis.

Es gibt einen Idle-Shutdown-Timer, dessen Zeit ist allerdings noch hardcoded.

Meine Software hat inzwischen auch ein Webinterface bekommen, das ist allerdings noch sehr funktional. (Will sagen: hässlich :smiley: ) Download und Upload funktionieren schon. Einlernen von RFID-Karten geht nur mühsam indem man eine Datei editiert. Also runterlädt, bearbeitet → hochlädt. Dann muss man den ESP neu starten, damit er das einliest.
Ordner anlegen und Dateien umbenennen funktioniert ebenso.

Na das klingt doch gut. Ich bin gerade gestern beim Olimex-Board (und auch beim Lyrat) wieder gelandet, als ich nochmal über das Thema Complete nachgedacht habe. Zuvor hatte ich mich eher auf den WM8960 eingeschossen, aber der scheint ja deprecated zu sein. Von daher gehe ich das Thema vielleicht mal mit einem ES8388 an.

Der ES8388 ist ganz ok, soweit ich das sagen kann. Ich kann leider den Stromverbrauch im Idle nicht messen bei dem Board, da ist zuviel anderer Kram verbaut.
Stereo-Audio mit dem Amp passt auch, wenn man das braucht.

Die Doku ist halt etwas „eigen“ - aber bis jetzt hat mir der Code der ESP-ADF genügt.