Forum: Mikrocontroller und Digitale Elektronik ESP32 + I2S - Immer nur Brummen zu hören


von Alexander (alexdozer)


Lesenswert?

Hallo,

ich habe mir einen esp32 gekauft weil ich damit ein kleines 
Synthesizer-Projekt basteln wollte. Leider scheitert es aber schon an 
der Sound-Ausgabe.

Ich hab als DA einen PCM5102A gekauft. Zudem hab ich noch zwei 
MAX98357A. Immer nur ein DA angeschlossen. Das ganze über I2S. Ich habe 
mir von der ESP-IDF das Beispiel heruntergeladen und programmiert.

Mein Problem ist jetzt: Egal was ich ausprobiere, ich höre immer nur 
Brummen. Nicht immer das gleiche Brummen, hört sich oft unterschiedlich 
an.

Was ich schon ausprobiert habe:

- Andere GPIO benutzt
- Anderen ESP32 benutzt
- Alle 3 DA, die ich habe, ausprobiert. Beim MAX98357A kann ich nur 
Messen was rauskommt, da messe ich immer über 1Mhz obwohl ich ein 440Hz 
Sinus via Code ausgebe.
- Alles zigmal geprüft ob Kontakt vorhanden ist
- Zigmal geprüft ob nicht irgendwo ein Kurzschluss ist
- Mir von ChatGPT mehrere Versionen programmieren lassen
- Stromversorgung über Steckbrett-Netzteil
- Arduino probiert, da war gar nichts zu hören

Egal was ich mache, es brummt. Es ist wie verhext. Hat jemand eine Idee? 
Ich bin mit meinen Ideen am Ende. Schon mal vielen Dank im Voraus!

Gruß Alex
1
/*
2
 * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
3
 *
4
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
5
 */
6
7
#include <stdint.h>
8
#include <stdlib.h>
9
#include "freertos/FreeRTOS.h"
10
#include "freertos/task.h"
11
#include "driver/i2s_std.h"
12
#include "driver/gpio.h"
13
#include "esp_check.h"
14
#include "sdkconfig.h"
15
#include "i2s_example_pins.h"
16
#include <math.h>
17
18
19
/* Set 1 to allocate rx & tx channels in duplex mode on a same I2S controller, they will share the BCLK and WS signal
20
 * Set 0 to allocate rx & tx channels in simplex mode, these two channels will be totally separated,
21
 * Specifically, due to the hardware limitation, the simplex rx & tx channels can't be registered on the same controllers on ESP32 and ESP32-S2,
22
 * and ESP32-S2 has only one I2S controller, so it can't allocate two simplex channels */
23
#define EXAMPLE_I2S_DUPLEX_MODE         CONFIG_USE_DUPLEX
24
25
#define EXAMPLE_STD_BCLK_IO1        EXAMPLE_I2S_BCLK_IO1      // I2S bit clock io number
26
#define EXAMPLE_STD_WS_IO1          EXAMPLE_I2S_WS_IO1      // I2S word select io number
27
#define EXAMPLE_STD_DOUT_IO1        EXAMPLE_I2S_DOUT_IO1     // I2S data out io number
28
#define EXAMPLE_STD_DIN_IO1         EXAMPLE_I2S_DIN_IO1     // I2S data in io number
29
#if !EXAMPLE_I2S_DUPLEX_MODE
30
#define EXAMPLE_STD_BCLK_IO2        EXAMPLE_I2S_BCLK_IO2     // I2S bit clock io number
31
#define EXAMPLE_STD_WS_IO2          EXAMPLE_I2S_WS_IO2     // I2S word select io number
32
#define EXAMPLE_STD_DOUT_IO2        EXAMPLE_I2S_DOUT_IO2     // I2S data out io number
33
#define EXAMPLE_STD_DIN_IO2         EXAMPLE_I2S_DIN_IO2     // I2S data in io number
34
#endif
35
36
#define EXAMPLE_BUFF_SIZE               2048
37
#define SAMPLE_RATE 22050
38
39
static i2s_chan_handle_t                tx_chan;        // I2S tx channel handler
40
static i2s_chan_handle_t                rx_chan;        // I2S rx channel handler
41
42
static void i2s_example_read_task(void *args)
43
{
44
    uint8_t *r_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE);
45
    assert(r_buf); // Check if r_buf allocation success
46
    size_t r_bytes = 0;
47
48
    /* Enable the RX channel */
49
    ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
50
51
    /* ATTENTION: The print and delay in the read task only for monitoring the data by human,
52
     * Normally there shouldn't be any delays to ensure a short polling time,
53
     * Otherwise the dma buffer will overflow and lead to the data lost */
54
    while (1) {
55
        /* Read i2s data */
56
        if (i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000) == ESP_OK) {
57
            printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes);
58
            printf("[0] %x [1] %x [2] %x [3] %x\n[4] %x [5] %x [6] %x [7] %x\n\n",
59
                   r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
60
        } else {
61
            printf("Read Task: i2s read failed\n");
62
        }
63
        vTaskDelay(pdMS_TO_TICKS(200));
64
    }
65
    free(r_buf);
66
    vTaskDelete(NULL);
67
}
68
69
static void i2s_example_write_task(void *args)
70
{
71
    uint8_t *w_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE);
72
    assert(w_buf); // Check if w_buf allocation success
73
74
    for (int i = 0; i < EXAMPLE_BUFF_SIZE / 2; i++) {
75
        float phase = (2.0f * M_PI * i) / (SAMPLE_RATE / 220);
76
        int16_t sample = (int16_t)(127 * sinf(phase));
77
        w_buf[i] = sample;  // Kein MSB nötig bei 8 Bit
78
        w_buf[2 * i + 1] = (sample >> 8) & 0xFF; // MSB
79
}
80
81
82
    size_t w_bytes = EXAMPLE_BUFF_SIZE;
83
84
    /* (Optional) Preload the data before enabling the TX channel, so that the valid data can be transmitted immediately */
85
    while (w_bytes == EXAMPLE_BUFF_SIZE) {
86
        /* Here we load the target buffer repeatedly, until all the DMA buffers are preloaded */
87
        ESP_ERROR_CHECK(i2s_channel_preload_data(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes));
88
    }
89
90
    /* Enable the TX channel */
91
    ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));
92
    while (1) {
93
        /* Write i2s data */
94
        if (i2s_channel_write(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes, 1000) == ESP_OK) {
95
            printf("Write Task: i2s write %d bytes\n", w_bytes);
96
        } else {
97
            printf("Write Task: i2s write failed\n");
98
        }
99
        vTaskDelay(pdMS_TO_TICKS(200));
100
    }
101
    free(w_buf);
102
    vTaskDelete(NULL);
103
}
104
105
static void i2s_example_init_std_simplex(void)
106
{
107
    /* Setp 1: Determine the I2S channel configuration and allocate two channels one by one
108
     * The default configuration can be generated by the helper macro,
109
     * it only requires the I2S controller id and I2S role
110
     * The tx and rx channels here are registered on different I2S controller,
111
     * Except ESP32 and ESP32-S2, others allow to register two separate tx & rx channels on a same controller */
112
    i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
113
    ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
114
    i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
115
    ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));
116
117
    /* Step 2: Setting the configurations of standard mode and initialize each channels one by one
118
     * The slot configuration and clock configuration can be generated by the macros
119
     * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode.
120
     * They can help to specify the slot and clock configurations for initialization or re-configuring */
121
122
     
123
124
125
i2s_std_config_t std_cfg = {
126
    .clk_cfg = {
127
        .sample_rate_hz = SAMPLE_RATE,
128
        .clk_src = I2S_CLK_SRC_DEFAULT,
129
        .mclk_multiple = I2S_MCLK_MULTIPLE_256
130
    },
131
   .slot_cfg = {
132
    .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT,
133
    .slot_bit_width = I2S_SLOT_BIT_WIDTH_16BIT,
134
    .slot_mode = I2S_SLOT_MODE_STEREO,
135
    .slot_mask = I2S_STD_SLOT_BOTH,
136
    .ws_width = I2S_DATA_BIT_WIDTH_16BIT,
137
    .ws_pol = false,
138
    .bit_shift = true,
139
    .msb_right = false
140
    },
141
    .gpio_cfg = {
142
        .mclk = I2S_GPIO_UNUSED,
143
        .bclk = GPIO_NUM_5,
144
        .ws   = GPIO_NUM_25,
145
        .dout = GPIO_NUM_26,
146
        .din  = I2S_GPIO_UNUSED,
147
        .invert_flags = {
148
            .mclk_inv = false,
149
            .bclk_inv = false,
150
            .ws_inv   = false
151
        }
152
    }
153
};
154
155
   ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg));
156
157
158
    i2s_std_config_t rx_std_cfg = {
159
        .clk_cfg  = I2S_STD_CLK_DEFAULT_CONFIG(22050),
160
        .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
161
        .gpio_cfg = {
162
            .mclk = I2S_GPIO_UNUSED,    // some codecs may require mclk signal, this example doesn't need it
163
            .bclk = EXAMPLE_STD_BCLK_IO2,
164
            .ws   = EXAMPLE_STD_WS_IO2,
165
            .dout = EXAMPLE_STD_DOUT_IO2,
166
            .din  = EXAMPLE_STD_DIN_IO2,
167
            .invert_flags = {
168
                .mclk_inv = false,
169
                .bclk_inv = false,
170
                .ws_inv   = false,
171
            },
172
        },
173
    };
174
    /* Default is only receiving left slot in mono mode,
175
     * update to right here to show how to change the default configuration */
176
    rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT;
177
    ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &rx_std_cfg));
178
}
179
180
181
extern "C" void app_main(void)
182
{
183
#if EXAMPLE_I2S_DUPLEX_MODE
184
    i2s_example_init_std_duplex();
185
#else
186
    i2s_example_init_std_simplex();
187
#endif
188
189
    /* Step 3: Create writing and reading task, enable and start the channels */
190
    xTaskCreate(i2s_example_read_task, "i2s_example_read_task", 4096, NULL, 5, NULL);
191
    xTaskCreate(i2s_example_write_task, "i2s_example_write_task", 4096, NULL, 5,

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Aber ein Oszilloskop hast Du nie an die IIS-Schnittstelle gehängt?

von Wastl (hartundweichware)


Angehängte Dateien:

Lesenswert?

Alexander schrieb:
> Egal was ich mache, es brummt.

Bei mir brummt es auch, aus anderen Gründen.

von Joachim B. (jar)


Lesenswert?

Alexander schrieb:
> Hallo,

Wichtige Regeln - erst lesen, dann posten!
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

nicht verstanden?

von Alexander (alexdozer)


Lesenswert?

Ok entschuldigt wegen dem längeren Source-Code. Kann es jetzt leider 
nicht mehr ändern. Werde nächstes Mal dran denken!

Ein Oszilloskop habe ich noch nicht verwendet weil UPS es nicht schafft 
es zu liefern. Aber am Montag hole ich es ab und dann werde ich es mir 
darauf mal ansehen. Werde berichten!

Gruß Alex

von Alexander (alecxs)


Lesenswert?

Alexander schrieb:
> Mir von ChatGPT mehrere Versionen programmieren lassen

Finde den Fehler

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

"ChatGPT, finde den Fehler!"

SCNR

von Thomas (db8nr)


Lesenswert?

Vielleicht hast du eine Masseschleife gebastelt?
https://de.wikipedia.org/wiki/Erdschleife
Zum Test taugt ein ETAL P2001, der taugt aber nur für Telefon-Sprache.
Wenn dann das Brummen weg ist, dann war es so.

von Alexander (alecxs)


Lesenswert?

Ich habe die MAX98357A auch in Betrieb allerdings spiele ich mp3 Dateien 
ab. Wenn Arduino für Dich keine Zumutung ist kannst Du damit testen ob 
es ein Hardware- oder Software-Problem ist.

Ich nutze die earlephilhower/ESP8266Audio Library für den ESP32.

: Bearbeitet durch User
von Jens K. (jensky)


Lesenswert?

Wastl schrieb:
> Alexander schrieb:
>> Egal was ich mache, es brummt.
>
> Bei mir brummt es auch, aus anderen Gründen.

Du bist nicht belastbar :-)

von Alexander (alexdozer)


Angehängte Dateien:

Lesenswert?

Ok es lag anscheinend an dem Steckbrett und auch an den Kabeln. Jetzt 
mit anderen Kabeln und ohne Steckbrett funktioniert es.

Ich musste allerdings noch einige Stunden rumbasteln bis dann auch ein 
Ton herauskam. Mit dem Beispiel von ESP-IDF hörte ich nichts. Habs es 
aber irgendwie hinbekommen das ein Ton zu hören ist. Keine Ahnung wie 
aber Hauptsache es geht jetzt weiter.

Ich hänge den Quellcode an für andere die auch da vielleicht auch drüber 
stolpern. Der Code ist für die Kombi ESP32 + PCM5102A

Gruß Alex

Update: Hab dem Code noch unnötige Zeilen entfernt. Weiß leider nicht 
wie das andere File entfernen kann. Nehmt den kleineren Quellcode, das 
ist der neue.

: Bearbeitet durch User
von Helmut -. (dc3yc)


Lesenswert?

Alexander schrieb:
> Ok es lag anscheinend an dem Steckbrett und auch an den Kabeln.

Merke: Steckbretter mit ausgeleierten Kontakten und Eisenkabel mit 
hauchdünnem Cu-Überzug sind schei....

: Bearbeitet durch User
von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

Alexander schrieb:
> Ok es lag anscheinend an dem Steckbrett und auch an den Kabeln

deswegen immer doppelt legen mit Kupfer und keine Eisenjumperleitungen, 
Magnetprüfung.

läuft nun 10 Jahre ohne Störung

von Alexander (alexdozer)


Lesenswert?

Joachim B. schrieb:
> Alexander schrieb:
>> Ok es lag anscheinend an dem Steckbrett und auch an den Kabeln
>
> deswegen immer doppelt legen mit Kupfer und keine Eisenjumperleitungen,
> Magnetprüfung.
>
> läuft nun 10 Jahre ohne Störung

Was ist die Magnetprüfung? Könntest du das bitte mir erklären?

von Helmut -. (dc3yc)


Lesenswert?

Alexander schrieb:
> Was ist die Magnetprüfung? Könntest du das bitte mir erklären?

Halte einen Magneten an die Kabel. Bei den meisten wirst du eine 
Anziehungskraft verspüren. Sprich: die meisten Billig-Dupontkabel 
heutzutage sind aus hauchdünnem Eisendraht!

von Alexander (alexdozer)


Lesenswert?

Helmut -. schrieb:
> Alexander schrieb:
>> Was ist die Magnetprüfung? Könntest du das bitte mir erklären?
>
> Halte einen Magneten an die Kabel. Bei den meisten wirst du eine
> Anziehungskraft verspüren. Sprich: die meisten Billig-Dupontkabel
> heutzutage sind aus hauchdünnem Eisendraht!

Danke!

von Klaus B. (butzo)


Lesenswert?

Helmut -. schrieb:
> Sprich: die meisten Billig-Dupontkabel
> heutzutage sind aus hauchdünnem Eisendraht!
Gabe es denn Quellen mit Kupferleiter?


Butzo*aussen

von Harald K. (kirnbichler)


Lesenswert?

Klaus B. schrieb:
> Gabe es denn Quellen mit Kupferleiter?

Eine oder mehrere Rollen Litze in den gewünschten Farben, eine 
Abisolierzange (Knipex oder Stripax), eine Tüte Crimpkontakte und 
Leergehäuse und die passende Zange (Engineeer PA-24). Und etwas Geduld.

Da weiß man, was man hat.

von Nemopuk (nemopuk)


Lesenswert?

Die Kontakte der meisten Steckbretter tagen auch nicht zur 
Stromversorgung, da (scheinbar) aus Dosenblech gestanzt.

von Helmut -. (dc3yc)


Lesenswert?

Nemopuk schrieb:
> Die Kontakte der meisten Steckbretter tagen auch nicht zur
> Stromversorgung, da (scheinbar) aus Dosenblech gestanzt.

In der aktuellen "Make" (3/25) ist ein Vergleich der diversen 
Steckbretter und auch ihre Qualitätsunterschiede. Federn z.B. aus 
Weißblech vs. Phosphorbronze.

von Harald K. (kirnbichler)


Lesenswert?

Wer Frickelboards kennt, lernt löten.

von Alexander (alexdozer)


Lesenswert?

Helmut -. schrieb:
>
> In der aktuellen "Make" (3/25) ist ein Vergleich der diversen
> Steckbretter und auch ihre Qualitätsunterschiede. Federn z.B. aus
> Weißblech vs. Phosphorbronze.

Hab die Ausgabe als PDF gekauft und mein Steckbrett (AZDelivery) hat am 
schlechtesten abgeschnitten :D

Naja das erklärt einiges.

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.