I2S sample rate issues with INMP441 MEMS
Posted: Tue Apr 11, 2023 12:56 am
So I have a simple code to plot the INMP441 audio input into the Serial Plotter. However I find two major issues after testing the code:
-The sample rate does not match with the sample rate I set in the i2s_config structure. In fact, is the half of the frequency i set up in the .sample_rate variable. For instance, in my case, setting up the sample rate to 44.1KHz will mean that sound frequencies above 11025 Hz won't be captured by the microphone. If I set up to 88.2KHz then it will capture sound waves untill 22.5 KHz.
-INMP441 supports untill 24 bits of resolution. However when I change the bits per sample to I2S_BITS_PER_SAMPLE_24BIT I get random nonsensical values.
Please take a look at my code in case it's a firmware error. Otherwise it might be the inmp441 that is malfuctioning. I'm using Platformio in VS Code with arduino framework.
-The sample rate does not match with the sample rate I set in the i2s_config structure. In fact, is the half of the frequency i set up in the .sample_rate variable. For instance, in my case, setting up the sample rate to 44.1KHz will mean that sound frequencies above 11025 Hz won't be captured by the microphone. If I set up to 88.2KHz then it will capture sound waves untill 22.5 KHz.
-INMP441 supports untill 24 bits of resolution. However when I change the bits per sample to I2S_BITS_PER_SAMPLE_24BIT I get random nonsensical values.
Please take a look at my code in case it's a firmware error. Otherwise it might be the inmp441 that is malfuctioning. I'm using Platformio in VS Code with arduino framework.
Code: Select all
#include "Arduino.h"
#include <driver/i2s.h>
//Definir pines para el protocolo i2s con el micrófono INMP441
#define I2S_BCK_PIN 32
#define I2S_SD_PIN 33
#define I2S_WS_PIN 25
//El ESP32 cuenta con 2 procesadores i2s internos cada uno con un puerto propio
#define I2S_PORT I2S_NUM_0
//Ahora definimos el tamaño del buffer DMA y el número de registros
const uint8_t dma_count=8;
const uint16_t dma_len=512;
void i2s_install(){
//Creamos las estructuras con la configuración del protoolo I2S y los pines
const i2s_config_t i2s_config={
.mode=i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX) ,
.sample_rate=44100,
.bits_per_sample=I2S_BITS_PER_SAMPLE_16BIT,
.channel_format=I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format= i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
.intr_alloc_flags=ESP_INTR_FLAG_LEVEL1 ,
.dma_buf_count=dma_count,
.dma_buf_len=dma_len ,
.use_apll=false ,
};
const i2s_pin_config_t pin_config={
.bck_io_num=I2S_BCK_PIN,
.ws_io_num=I2S_WS_PIN,
.data_out_num=I2S_PIN_NO_CHANGE,
.data_in_num=I2S_SD_PIN
};
i2s_driver_install(I2S_PORT,&i2s_config,0,NULL);
i2s_set_pin(I2S_PORT,&pin_config);
}
void setup(){
i2s_install();
//i2s_start(I2S_PORT);
Serial.begin(115200);
Serial.printf("Inicio del programa de comunicación con el micrófono MEMS INMP441 mediante protocolo I2S.\nSe utilizará el Serial Plotter para visualizar los datos de audio.\n ");
delay(2000);
}
void loop(){
size_t bytes_read=0;
//int16_t samples=dma_len*dma_count;
static int16_t buffer[4096]; //In order to have arrays beyond 2048 we need to use the heap memory instead of the stack. I failed allocating the memory with malloc(). There was overflow issues somehow so static is a temporal valid option.
uint16_t samples_read=0 /*,range=2000*/;
esp_err_t i2s_err= i2s_read(I2S_PORT,&buffer,4096 /*samples*sizeof(int16_t)*/,&bytes_read,portMAX_DELAY);
samples_read=bytes_read/sizeof(int16_t);
if(i2s_err==ESP_OK){
for(uint16_t i=0; i<samples_read; i++){
//Serial.print(range);
//Serial.print(" ");
//Serial.print(range * (-1));
//Serial.print(" ");
Serial.println(buffer[i]);
}
}
}