I2S microphone (RX)

ppisljar
Posts: 19
Joined: Wed Feb 22, 2017 4:36 pm

I2S microphone (RX)

Postby ppisljar » Thu Apr 27, 2017 12:46 pm

I am trying to connect I2S mic to ESP32 with no luck. (using SPH0645LM4H-B mic)

i2s init code:
```
i2s_config_t i2s_in_config = {
mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
sample_rate: 16000,
bits_per_sample: (i2s_bits_per_sample_t)16, // found some posts saying 32bit mode is giving extra problems ... so i am going with 16
channel_format: I2S_CHANNEL_FMT_ONLY_LEFT,
communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
dma_buf_count: 8,
dma_buf_len: 64
};

// if i understand correctly i can use any IO pin
i2s_pin_config_t i2s_in_pin_config = {
bck_io_num: 16,
ws_io_num: 4,
data_out_num: -1, //Not used
data_in_num: 17
};

i2s_driver_install((i2s_port_t)0, &i2s_in_config, 0, NULL);
i2s_set_pin((i2s_port_t)0, &i2s_in_pin_config);
```

and then i loop on this
```
uint16_t sample_val;
i2s_pop_sample((i2s_port_t)0, (char *)&sample_val, portMAX_DELAY);
Serial.print(sample_val);
```

however all i am getting is 0s. I read around this forum and found some old posts mentioning that RX is not working correctly yet with I2S, however some later posts seem to suggest that some ppl were succesfull ?

i would greatly appreciate any help on this.

derdolch
Posts: 1
Joined: Wed May 03, 2017 4:38 pm

Re: I2S microphone (RX)

Postby derdolch » Wed May 03, 2017 4:46 pm

You can read the datasheet of shp0645.
try

sample_rate: 32000 - 64000
bit_per_sample: 32
channel_format: I2S_CHANNEL_FMT_RIGHT_LEFT

In this way the BCLK will be 64th MCLK and the MIC sends Data.

I got sampled data into my esp32, but it did not work to send it to my DAC-Modul.

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: I2S microphone (RX)

Postby BuddyCasino » Mon May 08, 2017 12:27 pm

Would you mind posting your code? Because even with the latest I2S fixes in the ESP-IDF I get nothing.

Microphone I2S configuration:

Code: Select all

i2s_config_t i2s_config = {
			.mode = I2S_MODE_MASTER | I2S_MODE_RX,
			.sample_rate = 44100,
			.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
			.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
			.communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
			.dma_buf_count = 14,                            // number of buffers, 128 max.
			.dma_buf_len = 32 * 2,                          // size of each buffer
			.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1        // Interrupt level 1
	};

    i2s_pin_config_t pin_config = {
            .bck_io_num = GPIO_NUM_17,
            .ws_io_num = GPIO_NUM_18,
            .data_out_num = I2S_PIN_NO_CHANGE,
            .data_in_num = GPIO_NUM_5
    };
Loop:
uint64_t buffer = 0;
while(1)
{
buffer = 0;
i2s_pop_sample(I2S_NUM_1, &buffer, 10);
i2s_push_sample(I2S_NUM_0, &buffer, 10);
}
All when I look at the 'buffer' variable, all bits are set to 1.
Microphone type is SPH0645.

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: I2S microphone (RX)

Postby BuddyCasino » Thu May 11, 2017 11:52 am

Ok, these pins work:

Code: Select all

	i2s_pin_config_t pin_config = {
			.bck_io_num = 26,
			.ws_io_num = 25,
			.data_out_num = I2S_PIN_NO_CHANGE,
			.data_in_num = 23
	};
These don't:

Code: Select all

	i2s_pin_config_t pin_config_rx = {
			.bck_io_num = 17,
			.ws_io_num = 18,
			.data_out_num = I2S_PIN_NO_CHANGE,
			.data_in_num = 5
	};

Anyone got an idea whats going on here?
Theres a pin schematic that says which pins can be used for what, but I can't make sense of it in respect to I2S: http://www.espressif.com/sites/default/ ... ist_en.pdf

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: I2S microphone (RX)

Postby WiFive » Thu May 11, 2017 12:29 pm

Maybe because the driver does not do gpio_set_direction and gpio_set_pull_mode

ppisljar
Posts: 19
Joined: Wed Feb 22, 2017 4:36 pm

Re: I2S microphone (RX)

Postby ppisljar » Thu May 11, 2017 9:14 pm

i tried setting pin 17 to input/input_pulldown/input_pullup ... none seem to work (with pullup i get int32 max value)

Code: Select all

void i2s_config() {
  // http://esp-idf.readthedocs.io/en/latest/api/peripherals/i2s.html
  // input
  i2s_config_t i2s_in_config = {
    mode: (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    sample_rate: 64000, // tried with 44100 ... same
    bits_per_sample: (i2s_bits_per_sample_t)32,
    channel_format: I2S_CHANNEL_FMT_RIGHT_LEFT,
    communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
    dma_buf_count: 8,
    dma_buf_len: 64
  };
  i2s_pin_config_t i2s_in_pin_config = {
    bck_io_num: 16,
    ws_io_num: 4,
    data_out_num: -1, //Not used
    data_in_num: 17
  };

	pinMode(17, INPUT);
	pinMode(16, OUTPUT);
	pinMode(4, OUTPUT);


  i2s_driver_install((i2s_port_t)0, &i2s_in_config, 0, NULL);
  i2s_set_pin((i2s_port_t)0, &i2s_in_pin_config);

}


void read_i2s() {
  uint32_t sample_val = 0;
  i2s_pop_sample((i2s_port_t)0, (char *)&sample_val, portMAX_DELAY);
  Serial.print(sample_val);
}

ppisljar
Posts: 19
Joined: Wed Feb 22, 2017 4:36 pm

Re: I2S microphone (RX)

Postby ppisljar » Sun May 14, 2017 11:35 am

Seems to be a buggy driver ...

on espidf 2.0 i get output from mic with the above code (however it doesnt seem to be correct output ....)
on latest version of espidf i get only 0 with the same code.

ppisljar
Posts: 19
Joined: Wed Feb 22, 2017 4:36 pm

Re: I2S microphone (RX)

Postby ppisljar » Sun May 14, 2017 11:45 am

also i noticed that i need to read two 32 bit integers (stereo) ...

Code: Select all

void read_i2s() {
  uint32_t sample_val[2] = {0, 0};
  i2s_pop_sample((i2s_port_t)0, (char *)sample_val, portMAX_DELAY);
  Serial.println("==>");
  Serial.println(sample_val[0]);
  Serial.println(sample_val[1]);

}
wierd thing is that i am getting both values (and its mono microphone .... )
if i set it to mono i start getting 0 only.

the output i get is bad:

Code: Select all

4033937408
4033216512
4033413120
4032823296
4033413120
4032823296
0
0
0
0
0
0
0
0
0
.... (mix of really high values and 0 ... keeps repeating in a pattern)

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: I2S microphone (RX)

Postby BuddyCasino » Sun May 14, 2017 12:10 pm

The driver is probably not buggy, they fixed it recently. Are you using the latest ESP-IDF?

Using the SPH0645LM4H with I2S_BITS_PER_SAMPLE_32BIT, this works for me:

Code: Select all

	uint64_t buffer = 0;
	uint64_t buffer_out = 0;
	while(1)
	{
		cnt++;
		buffer = 0;
		int bytes_popped = i2s_pop_sample(I2S_NUM_0, &buffer, 10);
		buffer_out = buffer << 5;
		i2s_push_sample(I2S_NUM_0, &buffer_out, 10);
	}
Shifting by 5 was determined by try and error. The chip emits 24 bits with 18 bits of them valid followed by zeros, so this doesn't make sense to me - but it distorts with 6 (=24-18) bits.

Edit: just tested different pins, this configuration works now. The gpio_matrix_in_check() in the i2s.c driver should take care of everything:

Code: Select all

	i2s_pin_config_t pin_config_rx = {
			.bck_io_num = 17,
			.ws_io_num = 18,
			.data_out_num = I2S_PIN_NO_CHANGE,
			.data_in_num = 5
	};
	i2s_set_pin(I2S_NUM_1, &pin_config_rx);
Edit 2: I'm not sure I2S_CHANNEL_MONO actually works, I get no data.

User avatar
rudi ;-)
Posts: 1731
Joined: Fri Nov 13, 2015 3:25 pm

Re: I2S microphone (RX)

Postby rudi ;-) » Sun May 14, 2017 1:36 pm

BuddyCasino wrote:
The driver is probably not buggy, they fixed it recently. Are you using the latest ESP-IDF?

Using the SPH0645LM4H with I2S_BITS_PER_SAMPLE_32BIT, this works for me:

Code: Select all

	uint64_t buffer = 0;
	uint64_t buffer_out = 0;
	while(1)
	{
		cnt++;
		buffer = 0;
		int bytes_popped = i2s_pop_sample(I2S_NUM_0, &buffer, 10);
		buffer_out = buffer << 5;
		i2s_push_sample(I2S_NUM_0, &buffer_out, 10);
	}
Shifting by 5 was determined by try and error. The chip emits 24 bits with 18 bits of them valid followed by zeros, so this doesn't make sense to me - but it distorts with 6 (=24-18) bits.

Edit: just tested different pins, this configuration works now. The gpio_matrix_in_check() in the i2s.c driver should take care of everything:

Code: Select all

	i2s_pin_config_t pin_config_rx = {
			.bck_io_num = 17,
			.ws_io_num = 18,
			.data_out_num = I2S_PIN_NO_CHANGE,
			.data_in_num = 5
	};
	i2s_set_pin(I2S_NUM_1, &pin_config_rx);

@Buddy
can't test - cause have just in time no I2S HW Mic on the Hand -

in this way you did - you use successful I2S0 ( I2S_NUM_0) for output and the I2S1 ( I2S_NUM_1) for input, right?

so this config must be valid for run for the ICS.I2S as Left Channel example?
and for Left and Right ( 2 Mics ) example too?

perhabs you can look small time on this picture, please:
mic_pins_I2S.png
mic_pins_I2S.png (58.51 KiB) Viewed 39730 times
what is your saying?

best wishes
rudi ;-)
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪

Who is online

Users browsing this forum: Bing [Bot], MicroController and 133 guests