1
\$\begingroup\$

I've been trying to read the ICS-43434 microphone using esp32 wroom 32-d but I'm getting negative values that stay in more or less the same range, despite varying noise levels. What am I doing wrong? Here's the program I'm using, it's from https://github.com/atomic14/esp32-i2s-mic-test.

#include <driver/i2s.h>

// you shouldn't need to change these settings
#define SAMPLE_BUFFER_SIZE 512
#define SAMPLE_RATE 8000
// most microphones will probably default to left channel but you may need to tie the L/R pin low
#define I2S_MIC_CHANNEL I2S_CHANNEL_FMT_ONLY_LEFT
// either wire your microphone to the same pins or change these to match your wiring
#define I2S_MIC_SERIAL_CLOCK GPIO_NUM_32
#define I2S_MIC_LEFT_RIGHT_CLOCK GPIO_NUM_25
#define I2S_MIC_SERIAL_DATA GPIO_NUM_33

// don't mess around with this
i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 4,
    .dma_buf_len = 1024,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0};

// and don't mess around with this
i2s_pin_config_t i2s_mic_pins = {
    .bck_io_num = I2S_MIC_SERIAL_CLOCK,
    .ws_io_num = I2S_MIC_LEFT_RIGHT_CLOCK,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = I2S_MIC_SERIAL_DATA};

void setup()
{
  // we need serial output for the plotter
  Serial.begin(115200);
  // start up the I2S peripheral
  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &i2s_mic_pins);
}

int32_t raw_samples[SAMPLE_BUFFER_SIZE];
void loop()
{
 
  
   size_t bytes_read = 0;
  i2s_read(I2S_NUM_0, raw_samples, sizeof(int32_t) * SAMPLE_BUFFER_SIZE, &bytes_read, portMAX_DELAY);
  int samples_read = bytes_read / sizeof(int32_t);

  // calculate and dump the dB values out to the serial channel
  for (int i = 0; i < samples_read; i++) {
    // Calculate the amplitude (absolute value of the sample)
    float amplitude = abs(raw_samples[i]);
    
    // Calculate dB value. Using a reference amplitude of 2^31 - 1 for a 32-bit sample
    float dB = 20 * log10(amplitude / 2147483647.0);

    Serial.printf("%f dB\n", dB);
  }
}

And here's the sample output:

-47.712887 dB
-60.276260 dB
-56.260658 dB
-50.918934 dB
-77.350952 dB
-49.164951 dB
-55.350086 dB
-55.604759 dB
-66.171638 dB
-60.289097 dB
-61.654121 dB
-50.232655 dB
-60.323421 dB
-62.170216 dB
-73.168007 dB
-54.036129 dB
-51.763836 dB
-54.163162 dB
-62.159588 dB
-55.571114 dB
-59.478195 dB
-51.481255 dB
-55.634773 dB
-60.332024 dB
-54.171627 dB
-53.176498 dB
-75.127449 dB
-56.898865 dB
-52.085014 dB
-47.621769 dB
-59.237785 dB
-78.473801 dB
-50.811859 dB
-60.123688 dB
-56.887280 dB
-74.304970 dB
-54.882763 dB
-57.714119 dB
-77.214638 dB
-58.416660 dB
-71.476593 dB
-48.353985 dB
-57.238720 dB
-70.315788 dB
-55.380451 dB
-55.999378 dB
-57.595554 dB
-60.462086 dB
-56.279530 dB
-89.166138 dB
-61.724556 dB
-63.591068 dB
-56.146957 dB
-52.705235 dB
-67.237465 dB
-55.173664 dB
-66.419579 dB
-53.996613 dB
-63.313736 dB
-51.981564 dB

I have placed a jumper from WS to GPIO 25 as required by the program. (Schematic created by me)

This is how it's wired.

\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

I see 30 dB difference between max and min. That��s about what can be expected from someone speaking with normal dynamics and some background noise. Your values are in dBFS, so only negative and zero are the values you will get.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ thanks for your input. The problem is when I play a 1000 hz test tone right next to the microphone, the set of readings are similar as to when its quiet, with similar average and median. \$\endgroup\$
    – Zik
    Commented Mar 9 at 19:00
  • \$\begingroup\$ @Zik That’s unfortunate. How about just silence? The code is beyond my programming skills, but when I do try to debug my own code, it’s Serial.println on whatever was just computed on the line before until I find it. Professionals use test benches. \$\endgroup\$
    – winny
    Commented Mar 10 at 12:01
  • \$\begingroup\$ Similar values for silence as well. Tried another PCB, same results. Looks like I'm gonna have to do some reading to try and figure this out. \$\endgroup\$
    – Zik
    Commented Mar 11 at 17:51
  • \$\begingroup\$ @Zik Check with an oscilloscope/logic analyzer on the I2C and see if samples look correct. If yes, the problem is in the code. \$\endgroup\$
    – winny
    Commented Mar 11 at 18:48
  • \$\begingroup\$ Ok I will try that, thanks. Its I2S interface btw. \$\endgroup\$
    – Zik
    Commented Mar 13 at 6:03
0
\$\begingroup\$
  1. check obvious things like power to the mic.
  2. do you have a scope or a simple analyser? monitor the data, WD and CLK lines, see if they look about right. Your WD line is not connected to the processor - is this correct? Check data sheets of both mic and processor.
  3. if these signals look correct, do you see activity on the data lines when you tap the mic? You should see something.
  4. if all of this checks out, start digging into the hardware config of the interface in the processor. Try to read back config registers and incomimng data words directly, see if things look correct.
\$\endgroup\$
1
  • \$\begingroup\$ Ok will try your suggestions. I'll post here if I manage to get it working, Thanks. \$\endgroup\$
    – Zik
    Commented Mar 18 at 9:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.