espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.48k stars 7.26k forks source link

Example of I2S PDM project does not detect sound from microphone (IDFGH-10425) #11679

Open misterb0407 opened 1 year ago

misterb0407 commented 1 year ago

Answers checklist.

IDF version.

v5.1

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP-EYE

Power Supply used.

USB

What is the expected behavior?

I expect for the I2S read buffer to display some random number when we speak to the microphone of the ESP-EYE board.

What is the actual behavior?

The I2S read buffer keep showing dummy value of -30935 like following regardless we speak or not to the microphone.

I (341) main_task: Calling app_main()
I2S PDM RX example start
---------------------------
D (341) i2s_common: rx channel is registered on I2S0 successfully
D (351) i2s_common: DMA malloc info: dma_desc_num = 6, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = 480
D (361) i2s_common: i2s rx channel enabled
I (361) main_task: Returned from app_main()
Read Task: i2s read 2048 bytes
-----------------------------------
[0] -6595 [1] 0 [2] -29199 [3] -32768
[4] -30203 [5] -32156 [6] -30704 [7] -31348

Read Task: i2s read 2048 bytes
-----------------------------------
[0] -30935 [1] -30935 [2] -30935 [3] -30935
[4] -30935 [5] -30935 [6] -30935 [7] -30935
.....
Read Task: i2s read 2048 bytes
-----------------------------------
[0] -30935 [1] -30935 [2] -30935 [3] -30935
[4] -30935 [5] -30935 [6] -30935 [7] -30935

Steps to reproduce.

  1. Go to the example project folder $ cd /examples/peripherals/i2s/i2s_basic/i2s_pdm
  2. Configure the project to use PDM RX mode $ idf.py menuconfig -> I2S PDM Example Configuration -> I2S PDM direction -> PDM RX
  3. Build the project $ idf.py build
  4. Flash and monitor and from the console, the I2S buffer did not change regardless we speak over the microphone or not. ...

Debug Logs.

I2S PDM RX example start
---------------------------
D (341) i2s_common: rx channel is registered on I2S0 successfully
D (351) i2s_common: DMA malloc info: dma_desc_num = 6, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = 480
D (361) i2s_common: i2s rx channel enabled
I (361) main_task: Returned from app_main()
Read Task: i2s read 2048 bytes
-----------------------------------
[0] -6595 [1] 0 [2] -29199 [3] -32768
[4] -30203 [5] -32156 [6] -30704 [7] -31348

Read Task: i2s read 2048 bytes
-----------------------------------
[0] -30935 [1] -30935 [2] -30935 [3] -30935
[4] -30935 [5] -30935 [6] -30935 [7] -30935

Read Task: i2s read 2048 bytes
-----------------------------------
[0] -30935 [1] -30935 [2] -30935 [3] -30935
[4] -30935 [5] -30935 [6] -30935 [7] -30935

.....
-----------------------------------
[0] -30935 [1] -30935 [2] -30935 [3] -30935
[4] -30935 [5] -30935 [6] -30935 [7] -30935

More Information.

I have modified the sample code to set the GPIO number associated with the ESP-EYE like following in function i2s_example_init_pdm_rx()

i2s_pdm_rx_config_t pdm_rx_cfg = { .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(EXAMPLE_PDM_RX_FREQ_HZ), /* The data bit-width of PDM mode is fixed to 16 */ .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), .gpio_cfg = { .clk = 26, //EXAMPLE_PDM_RX_CLK_IO, .din = 33, //EXAMPLE_PDM_RX_DIN_IO, .invert_flags = { .clk_inv = false, }, }, };

misterb0407 commented 1 year ago

I wonder if in the first place we can use PDM mode for ESP-EYE board? How do we decide which mode is used given development board?

L-KAYA commented 1 year ago

@misterb0407 As the datasheet in #11678 , this MIC only can recognize I2S format. I'm not sure PDM will work to it. PDM only has one clock signal, but I2S have BCLK and WS two, so, depends on MIC though.

I'll try to write a set of configuration.

L-KAYA commented 1 year ago
#include <stdint.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_pdm.h"
#include "driver/gpio.h"
#include "esp_err.h"
#include "sdkconfig.h"

#define EXAMPLE_PDM_RX_CLK_IO           GPIO_NUM_26      // I2S PDM RX clock io number
#define EXAMPLE_PDM_RX_DIN_IO           GPIO_NUM_33      // I2S PDM RX data in io number

#define EXAMPLE_PDM_RX_FREQ_HZ          16000           // I2S PDM RX frequency

static i2s_chan_handle_t i2s_example_init_pdm_rx(void)
{
    i2s_chan_handle_t rx_chan;        // I2S rx channel handler
    i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
    ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));

    i2s_pdm_rx_config_t pdm_rx_cfg = {
        .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(EXAMPLE_PDM_RX_FREQ_HZ),
        /* The data bit-width of PDM mode is fixed to 16 */
        .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
        .gpio_cfg = {
            .clk = EXAMPLE_PDM_RX_CLK_IO,
            .din = EXAMPLE_PDM_RX_DIN_IO,
            .invert_flags = {
                .clk_inv = false,
            },
        },
    };

    ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_chan, &pdm_rx_cfg));

    ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
    return rx_chan;
}

void app_main(void)
{
    int16_t *r_buf = (int16_t *)calloc(1, EXAMPLE_BUFF_SIZE);
    assert(r_buf);
    i2s_chan_handle_t rx_chan = i2s_example_init_pdm_rx();

    size_t r_bytes = 0;
    while (1) {
        /* Read i2s data */
        if (i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000) == ESP_OK) {
            printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes);
            printf("[0] %d [1] %d [2] %d [3] %d\n[4] %d [5] %d [6] %d [7] %d\n\n",
                   r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]);
        } else {
            printf("Read Task: i2s read failed\n");
        }
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}
chucrut commented 1 year ago

I have the same problem. The buffer is filled with exactly the same "random" numbers each time. Is not reading data from the PDM mic