Page 1 of 1

I2S sample rate issues with INMP441 MEMS

Posted: Tue Apr 11, 2023 12:56 am
by Fluffy_Port
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.

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]);
       } 
   }
}