Durch Zufall bin ich auf das Tonuino-Projekt (https://www.voss.earth/tonuino/) gestoßen und würde das Ganze gerne auf einem ESP32 zum Laufen bringen. Einerseits deshalb, damit ich OTA nutzen kann und andererseits würde ich neue mp3s gerne via WLAN auf die Karte laden. Um das Ganze zu bewerkstelligen verwende ich ein ESP32-devBoard (Wroom32) und habe einen SD-Card-Reader (https://www.az-delivery.com/products/cop...-arduino), der per SPI angebunden ist. Der externe DAC (Adafruit MAX98357A) ist per i2s an den ESP32 angebunden und treibt einen 13cm-Lautsprecher von Visaton (4 Ohm) an. Nachdem ich zwischenzeitlich mit nem anderen Pin-Layout experimentiert habe bin ich, um etwaige Fehler auszuschließen, dass auf das SPI-Layout zurück gegangen, welches für den ESP32 per Default vorgesehen ist (VSPI). Die Verdrahtung sieht also exakt so aus: https://github.com/schreibfaul1/ESP32-au...57A%20.JPG Nun habe ich folende Libs ausprobiert: https://github.com/schreibfaul1/ESP32-audioI2S https://github.com/earlephilhower/ESP8266Audio Während das Streamen von Webradio mit der ersten Lib einwandfrei läuft, habe ich mit beiden Libs das Problem, dass das Spielen von lokalen mp3-Titeln von SD-Karte zu ziemlich verzerrtem Sound führt. Auch mit .wav habe ich es mit der Lib https://github.com/nhatuan84/esp32-i2s-s...d_wav_.ino und habe exakt das gleiche Problem: Der Sound ist total verzerrt. Card-Reader (besitzt einen Spannungsregler auf 3.3V) und MAX98357A sind beide mit 5V angeschlossen, dh sie hängen zwar am DevBoard, allerdings vor dem Spannungsregler. Mit nem einfachen Multimeter gemessen liegt die Spannung so bei 4,5V etwa und unterscheidet sich auch nicht, ob via WLAN oder SD gelesen wird. Ein Beispiel-Sketch von Espressif besitzt einen i/o-Test für SD. Da hat das Schreiben von 10 Mb ca. 4,5s gedauert. Also ein Problem mit dem Durchsatz kann es auch nicht sein. Es sei an dieser Stelle erwähnt, dass der Sound via SD auf jeden Fall nicht deswegen verzerrt, weil die Ausgabe zu laut ist. Bei der ersten Lib kann man die Lautstärke von 1 bis 21 einstellen; auch auf der niedrigsten Stufe klingt es total verzerrt, während ich via Web es auch schon auf 18 hatte und alles gut war. Ich habe auch schon versucht den Gain hardwareseitig auf dem DAC von 9dB (Default) auf 3dB (das Niedrigste, was im Handbuch beschrieben ist) zu setzen, aber auch das brachte keine Abhilfe. Hat hier im Forum vielleicht jmd. eine Ahnung/Vermutung, warum ich einen Stream via Web problemlos abspielen kann und das lokale Abspielen jedoch Probleme macht?
Hallo, erstmal Danke für diesen Link: https://github.com/schreibfaul1/ESP32-audioI2S kannte ich noch nicht. Play von SD-Card ist hier völlig ok, ESP32 und UDA1334A als I2S Decoder. Ich habe auch eine Kombi mit 2x MAX98357A also Stereoverstärker, das habe ich jetzt aber nicht rausgekramt. Stream-Play geht prinzipiell auch richtig, da ist mein WLAN-Umgebung aber im Moment hier anderer Meinung... Das der MAX mit 4 Ohm Last recht kräftige Spannungsversorgung braucht, ist Dir sicher bewußt, würde aber auch den Streamplay stören. Mein Projekt benutzt ansonsten die ESP8266Audio-Lib, die macht auch keine prinzipiellen Probleme mit Play von SD-Card. Beim Streamplay ist die Anzahl DMA-Buffer bei seiner Buffergröße etwas knapp, hier auf 32 Buffer a 128 Byte geändert. Das liegt aber auch daran, daß noch ein 4" Touch-Display benutzt wird, das auch manchmal etwas Last erzeugt und keine Aussetzer beim Bedienen erzeugen soll. Gruß aus Berlin Michael
Nee, ich hatte es per Jumperwires nur gesteckt. Da ich sowas mit einem Ethernet-Modul im Experimentierstadium auch mal gemacht hatte, war mir da jetzt keine Problematik bewusst. Ich habe auf jeden Fall nochmal "frische" Jumperwires genommen und damit ging es an. Final werde ich es dann eh löten.
Hat es sich so angehört, wie im Anhang? Vermutlich nicht, denn ich bekomme das zum Verrecken nicht weg mit auch mit neuen Kabeln tut sich da nichts bei mir. Ich habe allerdings folgende Komponenten: Adafruit I2S Stereo Decoder - UDA1334A breakout: https://www.adafruit.com/product/3678 SPI reader: https://www.az-delivery.de/en/products/copy-of-spi-reader-micro-speicherkartenmodul-fur-arduino?_pos=2&_sid=636bd39db&_ss=r ESP32-WROOM-32: https://www.az-delivery.de/en/products/esp32-developmentboard?_pos=2&_sid=9b0935b0b&_ss=r Mit dem schreibfaul code läuft der Webstream problemlos. Mit der SD-Karte sind diese Hänger drin. Wenn ich es mir genau angucke, ist es so, dass bei jedem Auslesevorgang der I2S kurz aussetzt. Das fällt besonders auf, wenn ich z.B. einen Sinus aus dem RAM abspiele und dann irgendwas von der SD-Karte auslese ohne es überhaupt abzuspielen. Bei jedem Lesevorgang ist ein kurzer Aussetzer drin. Irgendeine Idee, woran das liegen könnte?
>Hat es sich so angehört, wie im Anhang?
Üblicherweise hören sich so Verstärker mit defektem Ausgangstransistor
an.
Ich tippe mal auf eine zu schlechte Stromversorgung.
Anbei noch mal der Sinus-Test. Dabei werden jede Sekunde 512 byte von der SD-Karte gelesen und in ein Array geschrieben, also in dem Fall ist das von SDFat die Funktion FatFile::Read(). (das ist von meinem eigenen Programm, wo ich wav auslesen will, nicht mp3) Denkst du, der Kartenleser zieht den kompletten Controller runter bzw. den 5V-Pin, wenn er die Karte ausliest? Wie könnte ich das prüfen/beheben? Ich habe mal testweise den Leser mit einem separaten Netzteil versorgt, was aber nur dazu führte, dass die SD-Karte nicht mehr erkannt wurde. So geht es wohl schon mal nicht :D Mit einem Arduino Due funktioniert das ganze übrigens mit dem gleichen Kartenleser, aber ohne I2S. Da war ich über den DAC gegangen. Jetzt wollte ich halt zu ESP32 konvertieren das ganze Projekt. Es geht um einen Fahrgeräuschsimulator, wen es interessiert: https://youtu.be/-sQAT78AEd8
:
Bearbeitet durch User
Hab jetzt mal ein 5 V / 3000 mA Netzteil auf den 5 V Pin probiert. Kein Unterschied. Ein Kondensator zwischen 5 V und GND hat entsprechend auch nichts gebracht. Anbei noch mal mein Aufbau. Sollte eigentlich so sein, wie bei schreibfaul: https://github.com/schreibfaul1/ESP32-audioI2S/blob/master/additional_info/ESP32_I2S_UDA1334A.JPG Nur, dass ich den Kondensator am EN noch dran habe zum Hochladen ohne den Boot-Knopf drücken zu müssen. Vom Programm her ist es eigentlich nichts anderes, wie ein Sinus-Array mit i2swrite() an den DMA-Buffer zu schicken und dann den file.read() von der SD-Karte zu machen. Ohne file.read() kommt ein glatter Sinus-Ton raus, mit kommen die Aussetzer wie oben zu hören. Ich kann ja nachher noch mal ein Minimal-Beispiel draus machen.
>Anbei noch mal der Sinus-Test.
Der Sinus an sich klingt ja ziemlich klar und rein. Die Aussetzer
zwischendrinn könnten nach Bufferleerlauf und Timingproblem klingen.
Kommt der Sinus von der SD-Karte oder wird er generisch per Programmcode
erzeugt?
Wenn der Sinus nicht so klar wäre, wäre noch die Möglichkeit des
falschen I2S Formats in Betrachtung zu ziehen gewesen.
Wenn ich mir das beigefügte Foto ansehe fällt mir auf, dass sie Jumperkabel zum SD-Kartenleser zu lang sind. Standard läuft der SPI mit 40MHz für die SD. MISO/MOSI/SCK parallel im Flachbandkabel ist ganz ungünstig.
Ja, der Aufbau ist nicht ideal, aber zum Testen sollte es reichen. Ich habe es auch nur mit 10 MHz laufen. Siehe auch unten. Ich habe jetzt mal das Minimalbeispiel zusammengebaut, womit ich diese Aussetzer erzeugen kann:
1 | #include "Arduino.h" |
2 | #include "driver/i2s.h" |
3 | #include "SdFat.h" |
4 | |
5 | int chipSelectPin = 5; |
6 | SdFat sd; |
7 | SdFile myFile; |
8 | int16_t buf[512]; // buffer for SD data |
9 | int16_t m_outBuff[512]; // buffer for i2s data |
10 | size_t m_bytesWritten=0; // set in i2s_write() but not used |
11 | |
12 | // timing stuff
|
13 | long lastmillis = 0; |
14 | int ticks = 1000; |
15 | int dt; |
16 | |
17 | void setup() { |
18 | |
19 | sd.begin(chipSelectPin,SD_SCK_MHZ(10)); |
20 | |
21 | //i2s configuration
|
22 | |
23 | i2s_config_t i2s_config = { |
24 | .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), |
25 | .sample_rate = 22050, |
26 | .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, |
27 | .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, |
28 | .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), |
29 | .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority |
30 | .dma_buf_count = 8, // max buffers |
31 | .dma_buf_len = 1024, // max value |
32 | .use_apll=1, |
33 | .tx_desc_auto_clear= true, // new in V1.0.1 |
34 | .fixed_mclk=-1 |
35 | };
|
36 | i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); |
37 | |
38 | i2s_pin_config_t pins = { |
39 | .bck_io_num = 27, // Bit Clock |
40 | .ws_io_num = 26, // wclk, Left/Right Clock |
41 | .data_out_num = 25, // Data Out |
42 | .data_in_num = I2S_PIN_NO_CHANGE |
43 | };
|
44 | i2s_set_pin(I2S_NUM_0, &pins); |
45 | |
46 | // create sinus lookup table
|
47 | for(int i=0; i<512;i++) |
48 | {
|
49 | m_outBuff[i]=sin(10*PI*i/512.0)*30000; |
50 | }
|
51 | |
52 | myFile.open("320k_test.mp3", O_READ); |
53 | |
54 | Serial.begin(115200); |
55 | }
|
56 | |
57 | void loop() |
58 | {
|
59 | i2s_write(I2S_NUM_0, m_outBuff, sizeof(m_outBuff), &m_bytesWritten, 100); |
60 | |
61 | if(millis()>lastmillis+ticks) |
62 | {
|
63 | lastmillis = millis(); |
64 | //delay(400); // if I use this delay instead of myFile.read the output sounds similar
|
65 | myFile.read(&buf, sizeof(buf)); |
66 | dt = millis()-lastmillis; |
67 | Serial.println(dt); // file read takes about 2 to 3 ms |
68 | }
|
69 | }
|
Das ganze wird mit PIO (Arduino Framework) in VS Code compiliert. Ohne delay oder file read kommt ein sauberer Sinus raus.
:
Bearbeitet durch User
ESP32-SD-Kartenleser sind gerade in: https://hackaday.com/2020/06/14/esp32-becomes-music-player-in-under-40-lines-of-code/
Also ich habe mir das Ganze mal angehört, aber ganz so übel klang das bei mir nicht. Bei mir war das wie gesagt eher ein Knacken, welches mehr oder weniger stark ausgeprägt war. Verzerrung auch ein bisschen, aber doch nicht so stark. Ich habe allerdings auch nur mit der MAX-Amp bisher gearbeitet. Ein paar Anmerkungen: - Grundsätzlich gelöst bekommen habe ich es damit, dass ich es aufgelötet habe auf eine Streifenraster-Platine - Ein Stück weit verbessern konnte ich das Ganze, wenn ich den Takt auf dem SPI-Bus herabgesetzt habe: https://github.com/biologist79/Tonuino-ESP32-I2S/blob/master/src/main.cpp#L2912 (ist vermutlich nicht notwendig, wenn es aufgelötet ist, aber ich war am End froh, dass es gelaufen ist und habe es dann so gelassen.) - Via mp3-Stream hatte ich das Problem nicht, was für mich letztlich ein Indiz war, dass es von SPI kommt Ein "neuer Benutzer" meiner Tonuino-Portierung schrieb heute Morgen noch was. Ich zitiere das einfach mal an dieser Stelle, vielleicht hilft es ja weiter: "Hab mir dann die Stromversorgung genauer angesehen. Der UDA1334 hat die Möglichkeit mit 5V oder 3.3V betrieben zu werden. Ich hatte das USB-Versorgungskabel aufgedöselt und sowohl den SD-Card Reader als auch den DAC direkt mit den 5V gespeist. Testweise hab ich dann den DAC mit 3.3V direkt vom ESP32 angeschlossen und voilà, das Brummen war sofort weg. Juhuu! Glasklarer Sound!"
Torsten schrieb: > Testweise hab ich dann den DAC mit 3.3V direkt vom ESP32 angeschlossen > und voilà, das Brummen war sofort weg. Das war's! Ich habe den I2S Decoder an die 3.3V vom ESP gehängt, während der SPI Reader an den 5 V blieb. Jetzt geht's! :) Aber fragt mich nicht wieso. Würde mich sehr freuen, wenn mir das jemand erklären könnte. Das hat mich einiges an Nerven gekostet! Dann mal vielen Dank Leute! Jetzt kann's weitergehen mit dem eigentlichen Projekt :D
Christoph M. schrieb: > ESP32-SD-Kartenleser sind gerade in: > https://hackaday.com/2020/06/14/esp32-becomes-music-player-in-under-40-lines-of-code/ Klasse Überschrift! Aber warum haben sie es nicht gleich mit nur einer Zeile Code gemacht?? :D
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.