Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High noise on INMP441 output #6699

Closed
1 task done
Huyyuh2000 opened this issue May 5, 2022 · 15 comments
Closed
1 task done

High noise on INMP441 output #6699

Huyyuh2000 opened this issue May 5, 2022 · 15 comments
Assignees
Labels
Area: Peripherals API Relates to peripheral's APIs. Resolution: Awaiting response Waiting for response of author Status: Needs investigation We need to do some research before taking next steps on this issue

Comments

@Huyyuh2000
Copy link

Huyyuh2000 commented May 5, 2022

Board

DOIT ESP32 Devkit V1, WEMOS LOLON32 Lite, Wemos D1 R32

Device Description

All hardware plain on breadboard

Hardware Configuration

INMP441_WS connected to D15
INMP441_SD connected to D13
INMP441_SCK connected to D2
INMP441_VDD connected to 3.3V Pin
INMP441_GND connected to GND

Version

v2.0.2

IDE Name

Arduino IDE

Operating System

Windows 11 Home Single Language

Flash frequency

80MHz

PSRAM enabled

no

Upload speed

115200

Description

Hello, I recorded .wav file using INMP441 and the data was able to process (noise was at acceptable level). At the moment, when I am recording for collect data, the noise is very high. I have change wire, dev kit and sensor but the result are the same. Here are the link that I save 2 recorded file. The low noise is before I meet the problem.
I have read #3939 and follow some suggestion like soldering 10K between SD and GND but still not working.

Sketch

#include <driver/i2s.h>
#include <SPIFFS.h>

#define I2S_WS 15
#define I2S_SD 13
#define I2S_SCK 2
#define I2S_PORT I2S_NUM_0
#define I2S_SAMPLE_RATE   (16000)
#define I2S_SAMPLE_BITS   (16)
#define I2S_READ_LEN      (16 * 1024)
#define RECORD_TIME       (30) //Seconds
#define I2S_CHANNEL_NUM   (1)
#define FLASH_RECORD_SIZE (I2S_CHANNEL_NUM * I2S_SAMPLE_RATE * I2S_SAMPLE_BITS / 8 * RECORD_TIME)

File file;
const char filename[] = "/recording.wav";
const int headerSize = 44;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  SPIFFSInit();
  i2sInit();
  xTaskCreate(i2s_adc, "i2s_adc", 1024 * 3, NULL, 1, NULL);
}

void loop() {
  // put your main code here, to run repeatedly:

}

void SPIFFSInit(){
  if(!SPIFFS.begin(true)){
    Serial.println("SPIFFS initialisation failed!");
    while(1) yield();
  }
  SPIFFS.remove("/test.wav");
  SPIFFS.remove(filename);
  file = SPIFFS.open(filename, FILE_WRITE);
  if(!file){
    Serial.println("File is not available!");
  }

  byte header[headerSize];
  wavHeader(header, FLASH_RECORD_SIZE);

  file.write(header, headerSize);
  listSPIFFS();
}

void i2sInit(){
  esp_err_t err;
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = I2S_SAMPLE_RATE,
    .bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS), 
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S | I2S_COMM_FORMAT_STAND_MSB),
    .intr_alloc_flags = 0,
    .dma_buf_count = 8,
    .dma_buf_len = 1024,
    .use_apll = 1
  };

  err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
  if (err!=ESP_OK) {
    Serial.println("Failed to install driver");
  } else {
    Serial.println("Installed driver");
  }

  const i2s_pin_config_t pin_config = {
    .bck_io_num = I2S_SCK,
    .ws_io_num = I2S_WS,
    .data_out_num = -1,
    .data_in_num = I2S_SD
  };

  err = i2s_set_pin(I2S_PORT, &pin_config);
  if (err!=ESP_OK) {
    Serial.println("Failed to install pin");
  } else {
    Serial.println("Installed pin");
  }

}


void i2s_adc_data_scale(uint8_t * d_buff, uint8_t* s_buff, uint32_t len)
{
    uint32_t j = 0;
    uint32_t dac_value = 0;
    for (int i = 0; i < len; i += 2) {
        dac_value = ((((uint16_t) (s_buff[i + 1] & 0xf) << 8) | ((s_buff[i + 0]))));
        d_buff[j++] = 0;
        d_buff[j++] = dac_value * 256 / 2048;
    }
}

void i2s_adc(void *arg)
{
//    i2s_start(I2S_PORT);
    int i2s_read_len = I2S_READ_LEN;
    int flash_wr_size = 0;
    size_t bytes_read;

    char* i2s_read_buff = (char*) calloc(i2s_read_len, sizeof(char));
    uint8_t* flash_write_buff = (uint8_t*) calloc(i2s_read_len, sizeof(char));

    i2s_read(I2S_PORT, (void*) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
    i2s_read(I2S_PORT, (void*) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
    
    Serial.println(" *** Recording Start *** ");
    while (flash_wr_size < FLASH_RECORD_SIZE) {
        //read data from I2S bus, in this case, from ADC.
        i2s_read(I2S_PORT, (void*) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY);
        //example_disp_buf((uint8_t*) i2s_read_buff, 64);
        //save original data from I2S(ADC) into flash.
        i2s_adc_data_scale(flash_write_buff, (uint8_t*)i2s_read_buff, i2s_read_len);
        file.write((const byte*) flash_write_buff, i2s_read_len);
        flash_wr_size += i2s_read_len;
        ets_printf("Sound recording %u%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE);
        ets_printf("Never Used Stack Size: %u\n", uxTaskGetStackHighWaterMark(NULL));
    }
    file.close();

    free(i2s_read_buff);
    i2s_read_buff = NULL;
    free(flash_write_buff);
    flash_write_buff = NULL;
//    Serial.println("Finish free memory");
    listSPIFFS();
//    Serial.println("Finish lissSPIFFS function");
//    i2s_stop(I2S_PORT);
    vTaskDelete(NULL);
}

void example_disp_buf(uint8_t* buf, int length)
{
    printf("======\n");
    for (int i = 0; i < length; i++) {
        printf("%02x ", buf[i]);
        if ((i + 1) % 8 == 0) {
            printf("\n");
        }
    }
    printf("======\n");
}

void wavHeader(byte* header, int wavSize){
  header[0] = 'R';
  header[1] = 'I';
  header[2] = 'F';
  header[3] = 'F';
  unsigned int fileSize = wavSize + headerSize - 8;
  header[4] = (byte)(fileSize & 0xFF);
  header[5] = (byte)((fileSize >> 8) & 0xFF);
  header[6] = (byte)((fileSize >> 16) & 0xFF);
  header[7] = (byte)((fileSize >> 24) & 0xFF);
  header[8] = 'W';
  header[9] = 'A';
  header[10] = 'V';
  header[11] = 'E';
  header[12] = 'f';
  header[13] = 'm';
  header[14] = 't';
  header[15] = ' ';
  header[16] = 0x10;
  header[17] = 0x00;
  header[18] = 0x00;
  header[19] = 0x00;
  header[20] = 0x01;
  header[21] = 0x00;
  header[22] = 0x01;
  header[23] = 0x00;
  header[24] = 0x80;
  header[25] = 0x3E;
  header[26] = 0x00;
  header[27] = 0x00;
  header[28] = 0x00;
  header[29] = 0x7D;
  header[30] = 0x00;
  header[31] = 0x00;
  header[32] = 0x02;
  header[33] = 0x00;
  header[34] = 0x10;
  header[35] = 0x00;
  header[36] = 'd';
  header[37] = 'a';
  header[38] = 't';
  header[39] = 'a';
  header[40] = (byte)(wavSize & 0xFF);
  header[41] = (byte)((wavSize >> 8) & 0xFF);
  header[42] = (byte)((wavSize >> 16) & 0xFF);
  header[43] = (byte)((wavSize >> 24) & 0xFF);
  
}


void listSPIFFS(void) {
  Serial.println(F("\r\nListing SPIFFS files:"));
  static const char line[] PROGMEM =  "=================================================";

  Serial.println(FPSTR(line));
  Serial.println(F("  File name                              Size"));
  Serial.println(FPSTR(line));

  fs::File root = SPIFFS.open("/");
  if (!root) {
    Serial.println(F("Failed to open directory"));
    return;
  }
  if (!root.isDirectory()) {
    Serial.println(F("Not a directory"));
    return;
  }

  fs::File file = root.openNextFile();
  while (file) {

    if (file.isDirectory()) {
      Serial.print("DIR : ");
      String fileName = file.name();
      Serial.print(fileName);
    } else {
      String fileName = file.name();
      Serial.print("  " + fileName);
      // File path can be 31 characters maximum in SPIFFS
      int spaces = 33 - fileName.length(); // Tabulate nicely
      if (spaces < 1) spaces = 1;
      while (spaces--) Serial.print(" ");
      String fileSize = (String) file.size();
      spaces = 10 - fileSize.length(); // Tabulate nicely
      if (spaces < 1) spaces = 1;
      while (spaces--) Serial.print(" ");
      Serial.println(fileSize + " bytes");
    }

    file = root.openNextFile();
  }

  Serial.println(FPSTR(line));
  Serial.println();
  delay(1000);
}

Debug Message

None

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Huyyuh2000 Huyyuh2000 added the Status: Awaiting triage Issue is waiting for triage label May 5, 2022
@Huyyuh2000
Copy link
Author

@PilnyTomas Please help me. Thanks in advance.

@VojtechBartoska VojtechBartoska added Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: Awaiting triage Issue is waiting for triage labels May 6, 2022
@PilnyTomas
Copy link
Contributor

Hi @Huyyuh2000, thanks for creating the issue.
Let me understand some things:

  • Do you use some pre-soldered dev board with the INMP441, or did you make all the soldering yourself?
  • What bits-per-second does the microphone transmit?
  • The recorded data were ok, but after some change, it was broken?
    • What was the change that broke it?

@Huyyuh2000
Copy link
Author

Hi @PilnyTomas,
I soldered all the pin header for each sensor by myself,
I config sample rate is 16kHz, 16 bit depth and 1 channel so that 256kbps,
I don't change anything, after recorded I thought It was ok so move to another part of my project. When I get back to compile everything, I meet this problem

@PilnyTomas
Copy link
Contributor

How did you manage to set up 16 bit depth on the microphone?
Can you please send a block diagram of the connection for the microphone + a photo from the bottom side of the board with the microphone?

@VojtechBartoska VojtechBartoska added the Resolution: Awaiting response Waiting for response of author label May 9, 2022
@Huyyuh2000
Copy link
Author

Hi @PilnyTomas ,
About set up 16 bit depth, I config .bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS) which I2S_SAMPLE_BITS is defined as (16).
Here are all the things that you require: link

@PilnyTomas
Copy link
Contributor

That is a setup in the ESP I2S module. My question was about the microphone. How do you know the microphone is outputting 16 bits per sample?

@Huyyuh2000
Copy link
Author

Sorry, I don't know, Is there any way to check the output of the microphone?

@PilnyTomas
Copy link
Contributor

Usually, the first thing is to read the documentation for the chip you want to use. I don't know the chip you are using.
Please read the documentation and let me know what setup the microphone expects.

@Huyyuh2000
Copy link
Author

The datasheet said that the microphone output is industry-standard 24-bit I²S interface.
image

@PilnyTomas
Copy link
Contributor

Cool. Is the picture from the documentation, because there is depicted 32 bit per sample format.
Try setting up 24 and 32 to see which one works.

@Huyyuh2000
Copy link
Author

Hello, I tried change bit per sample and other parameters that come with it but there is still having noise.
I found the reason why there a lot of noise was the L/R pin unconected. I watch some instructions and said that the sensor will auto set to ONLY_LEFT_CHANNEL if the pin is unconected. Seem like by unconecting the pin to Vdd or GND cause the problem.

@aliyou-sn
Copy link

Hello, please how do you solve this problem, i connect L\R pin to ground, I’m not getting any audio

@CaptHigh
Copy link

Hello, please how do you solve this problem, i connect L\R pin to ground, I’m not getting any audio

If You are using Arduino Framework with ESP32 then try connecting the L/R pin with GND and then set the input channel
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,

Using this approach worked for me, try the Left channel if the Right one doesn't work

@Vegethalia
Copy link

Hello, do you remember if changing the bits_x_sample from 16 to 24/32 made any difference for you?

I'm receiving audio samples without problems and the quality is good (using a very similar configuration of the I2S as the one shown in the 1st post), but the "volume" of the samples is extremely low:
image
The 4 "veritical lines" are 4 claps that I did just in front of the mic.

I don't know how to make it "louder".... of course I can "scale up" the signal, but the quality then is horrible.

@Vegethalia
Copy link

Ok I'll answer myself, just in case this serves someone else:
The problem was that I had configured the I2S in 16 bit mode, and then I was only capturing the MSB of the bit stream.
If I configured 24 bits, then the stream was garbled.
The solution is to configure I2S in 32 bits mode and when reading, each sample takes 4 bytes and one must be discarted.
Like this:

REAL_BYTES_X_SAMPLE=4;

i2s_read(I2S_NUM_0, (void*)dataOrig, buffSizeOrig, &bytesRead, portMAX_DELAY);
uint16_t samplesRead = bytesRead / REAL_BYTES_X_SAMPLE;
for (int i = 0; i < samplesRead; i++) {
    byteIndex = i * REAL_BYTES_X_SAMPLE;
    int32_t value = ((int32_t*)(dataOrig + byteIndex))[0]>>8;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Resolution: Awaiting response Waiting for response of author Status: Needs investigation We need to do some research before taking next steps on this issue
Projects
Development

No branches or pull requests

6 participants