ESP32 - DAC erzeugt komische Geräusche

Hallo mal wieder,

nachdem ich es doch irgendwie geschafft habe, mein Musikprogramm auf den zweiten Kern des ESP32s zu verschieben, habe ich jetzt ein sehr merkwürdiges Problem: Es sieht so aus, als würden die Bildschirmaktualisierungen ein komisches hohes Klickergeräusch verursachen (s. Anhang), das in stillen Momenten der Musik schon unschön zu hören ist. Wenn ich das Display abziehe oder wenn sich nichts auf dem Bildschirm verändert (dann lässt die Lib nämlich den Datentransfer sein), dann setzt dieses Geräusch aus. Ich verstehe einfach nicht, wodurch dieses Geräusch verursacht wird. Kann mir da wer von euch was sagen?

Gruß
HTML-Fan

Anhang.zip (64.3 KB)

HTML-Fan:
Hallo mal wieder,
s. Anhang

Anhang vergessen?

Moko:
Anhang vergessen?

Fast, das Forum hatte Probleme mit einer mp3, ich musste sie zippen.

Das Display nutzt übrigens I²C und das Geräusch entsteht auch, wenn ich den DAC-Befehl rausstreiche.

Hallo,

das klingt für mich wie ein Spulenfiepen. Sind Spulen in der Nähe? DC-DC Wandler?
Oder wird durch einen ähnlichen Effekt in die Tonleitung eingekoppelt.
50Hz Netzbrummen ist es nicht.

Wenn der Ton über einen Verstärker läuft, dann spuckt da möglicherweise irgendwas rein.

Doc_Arduino:
Sind Spulen in der Nähe?

Zählt ein Lautsprecher als Spule? Aber warum kommt dann dieses Geräusch nur, wenn das Display aktualisiert wird?

Doc_Arduino:
DC-DC Wandler?

Der ESP32 hat seinen eingebauten 5V-zu-3.3V-Konverter.

Hallo,

Lautsprecher hat zwar eine fette Spule, aber die erzeugt kein Fiepen, sondern den sauberen gewünschten Ton. :slight_smile:

Der ESP32 hat seinen eingebauten 5V-zu-3.3V-Konverter.

Da haben wir es doch vermutlich gefunden, meine ich. Die Spule davon sollte die Ursache sein. Fiepen entsteht durch ungünstige Strombelastung, dazu noch kommt noch unsaubere Fertigung/Befestigung der Spule selbst. Das Ding schwingt. Einharzen kann helfen. Hier bestimmt nicht möglich. Wenn du dein Display nur aller paar Sekunden aktualisiert sollte sich das fiepen im Intervall bemerkbar ändern. Damit kann man es bestätigen oder ausschließen. Teste mit verschiedenen Intervallen und Längen der Aktualisierungen. Das fiepen kann verzögert beginnen. Abhilfe kann sein dem Display noch paar Abblockkondensatoren zu gönnen, direkt am Display. Um die Stromspitzen zu reduzieren. Wobei ein Display eigentlich keine Last darstellt. Oder steuerst du die Helligkeit mit PWM an?

Unangenehmes Spulenfiepen hat(te) man auch im Rechner mit Grafikkarten. Hat sich die letzten Jahre aber gelegt. Unterschiedliche Lastfälle können das immer mal wieder sporadisch erzeugen. Kann eine ganze Serie betreffen oder auch nur einzelne Karten. Was auf individuelle Fertigungstoleranzen schließen lässt.

Doc_Arduino:
Wobei ein Display eigentlich keine Last darstellt.

Das dachte ich auch, da dieses 1.3-Zoll-OLED jetzt nicht gerade viel verbrauchen sollte. Ich hatte eher vermutet, dass vielleicht der ESP32 während der I²C-Datenübertragung irgendwas komisches mit dem DAC macht. Ich habe probiert, einen ElKo (4,7µF, hatte ich vor meiner Nase liegen) am Display zwischen VDD und GND anzubringen, gebracht hat's nichts.

Hallo,

hmmm, probiere mal verschiedene "Nutzungszeiten" vom Display wie angedacht. Neue Daten aller 5s schreiben, tritt das fiepen dann auch aller 5s auf? Kannst du den Finger auf die Spule drücken? Verändert sich das fiepen?
Wenn sich da was tut hätte man den Übertäter aber noch nicht die Ursache beseitigt.
Anderes ESP Board probieren ... ?
Oder alle Peripherie fremd versorgen und nicht vom ESP speisen lassen. Falls du das tust.

Doc_Arduino:
Neue Daten aller 5s schreiben, tritt das fiepen dann auch aller 5s auf?

Ja, soweit ich weiß, schon. Ich benutze das Display momentan für eine Art Autorennspiel und da das Display nur aktualisiert wird, wenn sich was geändert hat, kann man ein langsames Klickern erzeugen, indem man sich einfach langsam (also nur alle 5s einen Pixel) bewegt.

Doc_Arduino:
Kannst du den Finger auf die Spule drücken? Verändert sich das fiepen?

Wenn die Spule des Stromumwandlersin diesem länglichen schwarzen Kasten mit drei Pins auf der einen und einem dicken Pin an der anderen Seite auf der Platine des ESPs in der Nähe des USB-Anschlusses ist, dann verändert sich das Geräusch nicht, wenn ich da draufdrücke.

Doc_Arduino:
Oder alle Peripherie fremd versorgen und nicht vom ESP speisen lassen. Falls du das tust.

Das Display wird durch den ESP mit 3.3V versorgt - sonst ist nichts angeschlossen. Außer ein Joystick, aber der ist es nicht, der zieht ja fast nix und wenn ich ihn rausziehe, dann ändert das auch nichts am Geräusch. Übrigens habe ich auch mal die I²C-Verbindung durch zwei 220Ω-Widerstände gejagt - ich dachte, vielleicht zieht ja die Übertragung da ordentlich Strom und zieht dabei den DAC runter - aber es brachte nichts.

Hallo,

habe mir mal paar Bilder von diversen ESP32 Boards angeschaut. Der "schwarze Kasten" ist der Spannungsregler sein. Auf jeden Fall ist das nicht die Spule. Dann ist das im Nachgang auch kein Schaltregler mit Spule vorhanden. Demnach stehen wir wieder am Anfang. Tut mir leid.

Ein ähnliches Thema gabs schon einmal. Vielleicht hilft dir das.

Ein ESP32 liegt auf meinem Schreibtisch und Töne am DAC habe ich auch schon erzeugt. Sollte es also irgendeinen Erkenntnisgewinn bringen, kann ich gerne ein kleines Testprogramm von Dir aufspielen. Nur so als Angebot :slight_smile:

agmue:
Ein ESP32 liegt auf meinem Schreibtisch

Hast du auch ein I²C-Display (SSD1306 / SH1106) und einen Joystick?

Übringens: Es liegt nicht an exakt diesem ESP. Ich habe es mit einem anderen Ding ausprobiert, da ist’s auch so. Aber beide sind aus einer Lieferung, also könnte die ganze Fuhre defekt oder der Hersteller geizig sein.

HTML-Fan:
Hast du auch ein I²C-Display (SSD1306 / SH1106) und einen Joystick?

SSD1306 ja, Joystick nein.

Joystick = zwei Potis?

agmue:
Joystick = zwei Potis?

Exakt. Nur ist das, was ich da habe, kein klassisches Autorennen, darum könntest du Probleme bei der Steuerung kriegen.
Okay, im Anhang ist das Programm, die Potis müssen auf D34 und 35, D25 ist der DAC und das Display sollte die Adresse 0x3C haben, sonst ändern. Das Programm ist momentan für SSD1306-Displays, auch das lässt sich ändern. Die Lib gibt’s hier. Ist meine überarbeitete Version, wurde noch nicht übernommen. Es gab Probleme mit fillCircle(). Es ist übrigens ein Knock-Out-Rennen, du fliegst also raus, wenn alle außer dir schon die Ziellinie überquert haben und die Kamera springt dann zu irgendeinem anderen KI-Gegner (mit der nächsten ID). Und die Musik im Hintergrund ist von mir selbst, sie war allerdings als Test für Ringmodulation gedacht und nicht für dieses Spiel, deswegen passt sie nicht allzu gut.

Programm.zip (12.6 KB)

Das wird wohl nichts, denn ich bekomme leider viele Fehlermeldungen (gekürzt):

...\162.ino:1:0: warning: "DISPLAY" redefined

 #define DISPLAY false

 ^

In file included from sketch\162.ino.cpp:1:0:

...\1.0.4\cores\esp32/Arduino.h:50:0: note: this is the location of the previous definition

 #define DISPLAY 0x1

 ^

In file included from ...\162.ino:10:0:

sketch\definitions.h:6:0: warning: "constrain" redefined

 #define constrain(a, b, c) min(max(a, b), c)

 ^

In file included from sketch\162.ino.cpp:1:0:

...\1.0.4\cores\esp32/Arduino.h:71:0: note: this is the location of the previous definition

 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

 ^

In file included from ...\162.ino:12:0:

sketch\noteNames.h:18:0: warning: "F" redefined

 #define  F       5

 ^

In file included from ...\1.0.4\cores\esp32/Arduino.h:146:0,

                 from sketch\162.ino.cpp:1:

...\1.0.4\cores\esp32/WString.h:40:0: note: this is the location of the previous definition

 #define F(string_literal) (FPSTR(PSTR(string_literal)))

 ^

In file included from ...\162.ino:14:0:

sketch\patterns.h:19:200: warning: backslash and newline separated by space

                                0, 12,  SOUND_BASS(o2+F, 12),  SOUND_BASS(o2+D, 12),  SOUND_BASS(o2+F, 12),  SOUND_BASS(o2+D, 12),  SOUND_BASS(o1+A, 12),  SOUND_BASS(o2+C, 12),  SOUND_BASS(o2+D, 12), \                               

                                                                                                                                                                                                        ^

In file included from ...\162.ino:24:0:

sketch\playing_routine.h: In function 'void onTimer()':

sketch\playing_routine.h:56:13: warning: unused variable 'cutoffPos' [-Wunused-variable]

     uint8_t cutoffPos = (melodyOscs[i].vcf.pos / 0xFFFFFF);

             ^

In file included from ...\1.0.4\cores\esp32/WString.h:29:0,

                 from ...\1.0.4\cores\esp32/Arduino.h:146,

                 from sketch\162.ino.cpp:1:

sketch\playing_routine.h: In function 'uint32_t pgm32(const void*)':

sketch\playing_routine.h:168:60: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

   return (pgm_read_byte(pos) << 24) | (pgm_read_byte(pos + 1) << 16) | (pgm_read_byte(pos + 2) << 8) | pgm_read_byte(pos + 3);

                                                            ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h:168:93: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

   return (pgm_read_byte(pos) << 24) | (pgm_read_byte(pos + 1) << 16) | (pgm_read_byte(pos + 2) << 8) | pgm_read_byte(pos + 3);

                                                                                             ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h:168:124: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

   return (pgm_read_byte(pos) << 24) | (pgm_read_byte(pos + 1) << 16) | (pgm_read_byte(pos + 2) << 8) | pgm_read_byte(pos + 3);

                                                                                                                            ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h: In function 'uint32_t pgm16(const void*)':

sketch\playing_routine.h:171:58: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

   return (pgm_read_byte(pos) << 8) | pgm_read_byte(pos + 1);

                                                          ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h: In function 'void onTimer2()':

sketch\playing_routine.h:182:79: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

         byte data = pgm_read_byte(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos);

                                                                               ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h:190:96: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].timeLeft = pgm_read_byte(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos);

                                                                                                ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

sketch\playing_routine.h:195:92: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].drum = pgm_read_byte(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos) & 1;

                                                                                            ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

In file included from ...\162.ino:24:0:

sketch\playing_routine.h:200:89: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].vca.decay = pgm32(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos);

                                                                                         ^

In file included from ...\1.0.4\cores\esp32/WString.h:29:0,

                 from ...\1.0.4\cores\esp32/Arduino.h:146,

                 from sketch\162.ino.cpp:1:

sketch\playing_routine.h:207:99: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].vca.sustain = pgm_read_byte(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos) << 8;

                                                                                                   ^

...\1.0.4\cores\esp32/pgmspace.h:38:57: note: in definition of macro 'pgm_read_byte'

 #define pgm_read_byte(addr)   (*(const unsigned char *)(addr))

                                                         ^

In file included from ...\162.ino:24:0:

sketch\playing_routine.h:211:90: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].vca.attack = pgm32(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos);

                                                                                          ^

sketch\playing_routine.h:215:91: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].vca.release = pgm32(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos);

                                                                                           ^

In file included from ...\1.0.4\cores\esp32/WString.h:29:0,

                 from ...\1.0.4\cores\esp32/Arduino.h:146,

                 from sketch\162.ino.cpp:1:

sketch\playing_routine.h:220:96: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]

             melodyOscs[i].timeLeft = pgm_read_byte(pgm_read_ptr(musicData + i) + melodyOscs[i].musicPos) << 8;

                                                                                                ^

...

cc1plus.exe: some warnings being treated as errors

exit status 1

Komisch, bei mir geht's. Ist aber auf ESP32 eingestellt, ja?

HTML-Fan:
Ist aber auf ESP32 eingestellt, ja?

ESP32_Einstellungen.png

ESP32_Einstellungen.png