Page 1 of 1

I2S PDM Mode - Wrong Output

Posted: Fri Jun 26, 2020 10:18 am
by mtsm45
I am working on a project to interface a PDM microphone with an ESP32. At the moment, I am using the Arduino IDE but I am using the native I2S interface. I have been trying to use the PDM to PCM convertor, but I am getting the wrong results. When I connect the microphone, I get values between 100-250 which is much less than the 16 bit (0-65535) range. I have saved this on an SD and the audio played is right but obviously the effective resolution is very low. I have tried the extreme values by connecting a DATA_IN to GND and the VDD. In both cases I am getting 34601 output.
Using a 16 bit samples
34601/65535(2^16) = 0.527
I have also tried to use a 32 bit samples but I am getting the same ratio as the other one
2267645737/4294967296(2^32) = 0.527
I am displaying the values I have read and the last half are always empty.
Can someone help me with it, I have been trying to get this to work but to no avail.

Code: Select all

#include <FS.h>
#include <Arduino.h>
#include "freertos/task.h"
#include "freertos/FreeRTOS.h"
#include "driver/i2s.h"
#include "esp_system.h"
#define SAMPLE_RATE (48000)
#define PIN_I2S_BCLK 26
#define PIN_I2S_LRC 22
#define PIN_I2S_DIN 15
#define PIN_I2S_DOUT 25

#define I2S_PDM_CONF_REG *((volatile uint32_t *)(0x3FF4F0B4))

const int sizeBuffer = 1024;
uint16_t i2s_read_buff[sizeBuffer];
int num;

void setup() {
  Serial.begin(115200);
  
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX  | I2S_MODE_PDM ),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_ALL_RIGHT,
    .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = 0,
    .dma_buf_count = 2,
    .dma_buf_len = 1024
  };
  i2s_pin_config_t pin_config;
  pin_config.bck_io_num = PIN_I2S_BCLK;
  pin_config.ws_io_num = PIN_I2S_LRC;
  pin_config.data_out_num = I2S_PIN_NO_CHANGE;
  pin_config.data_in_num = PIN_I2S_DIN;
  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
  i2s_set_sample_rates(I2S_NUM_0, 48000); 
 
  //I2S_PDM_CONF_REG = 0b00000000010101010000000000101100;
  
  for (int j = 0; j < 1000; ++j) {
  num = i2s_read_bytes(I2S_NUM_0, (char *)i2s_read_buff, sizeBuffer , portMAX_DELAY);
  if( j == 20){
    
    for(int b = 0; b<1024; b++){
      Serial.print(b);
      Serial.print("  :  ");
      Serial.println(i2s_read_buff[b]);
    }
   
  }
    
  }

}



void loop() {
}


These is a short snipped of the output that I am getting
0 : 34601
1 : 34601
2 : 34601
3 : 34601
4 : 34601
5 : 34601
6 : 34601
7 : 34601
8 : 34601
9 : 34601
10 : 34601
11 : 34601
12 : 34601
13 : 34601
14 : 34601
15 : 34601
.
.
.
.

485 : 34601
486 : 34601
487 : 34601
488 : 34601
489 : 34601
490 : 34601
491 : 34601
492 : 34601
493 : 34601
494 : 34601
495 : 34601
496 : 34601
497 : 34601
498 : 34601
499 : 34601
500 : 34601
501 : 34601
502 : 34601
503 : 34601
504 : 34601
505 : 34601
506 : 34601
507 : 34601
508 : 34601
509 : 34601
510 : 34601
511 : 34601
512 : 0
513 : 0
514 : 0
515 : 0
516 : 0
517 : 0
518 : 0
519 : 0
520 : 0
521 : 0
522 : 0
523 : 0
524 : 0
525 : 0
526 : 0
527 : 0
528 : 0
529 : 0
530 : 0
531 : 0
.
.
.
.
1014 : 0
1015 : 0
1016 : 0
1017 : 0
1018 : 0
1019 : 0
1020 : 0
1021 : 0
1022 : 0
1023 : 0

Re: I2S PDM Mode - Wrong Output

Posted: Tue Jun 30, 2020 6:58 am
by vibro_tech
Hi,
I am using ESP-IDF (not Arduino) and get similar results. I posted below and got no response. Still trying. did you find a solution?

viewtopic.php?p=61903&sid=b05d48ffb3afb ... 2e0#p61903