I am trying to use a microphone sensor on my esp32 microcontroller. Currently, it is running the ESP-IDF framework. The microphone is the sph0645lm4h-b. I am using the I2S protocol to connect to the sensor.
I2S config is shown below:
void i2s_init()
{
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX, // I2S_MODE_TX Only TX
.sample_rate = 17000,
.bits_per_sample = 32,
// .channel_format = I2S_CHANNEL_FMT_ALL_LEFT, //2-channels
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
.dma_buf_count = 8,
.dma_buf_len = 64,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1
};
i2s_pin_config_t pin_config = {
.bck_io_num = 26,
.ws_io_num = 25,
.data_out_num = -1, //Not used
.data_in_num = 27
};
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, &pin_config);
}
The code that collects data:
i2s_init(); //initializes mics
int samples_value, samples_data;
samples_value = i2s_pop_sample(I2S_NUM, &samples_data, 2);
printf("%d,", samples_data);
When I upload the code to the microcontroller, I am getting confusing data. The outputs alternate from a really negative value and 1.
Data:
-191725568,1,-191823872,1,-191889408,1,-192020480,1,-192118784,1,-190152704,1,-190054400,1,-190021632,1
I am unsure if this is the data that I am supposed to be receiving from the microphone sensor and I read on the I2S documentation that the i2s_pop_sample is depreciated so I tried to use the i2s_read but I am getting a StoreProhibited error.
Code for i2s_read:
int *samples;
int s;
samples = &s; //pointer initialization
i2s_read(I2S_NUM,&samples,4,4,2);
Error:
Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400d7552 PS : 0x00060b30 A0 : 0x800d1c9f A1 : 0x3ffcc950
A2 : 0x00000000 A3 : 0x3ffccaa8 A4 : 0x00000004 A5 : 0x00000004
A6 : 0x00000002 A7 : 0x00000005 A8 : 0x800d1e72 A9 : 0x3ffcc900
A10 : 0x3d87e746 A11 : 0x00000000 A12 : 0x00000001 A13 : 0x00000002
A14 : 0x7f800000 A15 : 0x00000000 SAR : 0x00000015 EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000004 LBEG : 0x40002390 LEND : 0x4000239f LCOUNT : 0x00000000
Backtrace: 0x400d7552:0x3ffcc950 0x400d1c9c:0x3ffcc990 0x400e9994:0x3ffccae0
I'm just going to address the i2s_read()
issue since i2s_pop_sample()
is deprecated.
The way you're calling i2s_read()
, you're using a pointer as a data buffer and passing an integer as a pointer.
Here's the prototype of i2c_read()
taken from the ESP-IDF manual.
esp_err_t i2s_read(i2s_port_ti2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait)
i2s_num
is the i2s port numberdest
is the address of the buffer to read the data intosize
is the size of the bufferbytes_read
is a pointer to a size_t
which will have the number of bytes read written to itticks_to_wait
is a timeoutThere are two problems with the arguments you passed to i2s_read()
. You're calling it this way:
int *samples;
int s;
samples = &s;
i2s_read(I2S_NUM,&samples,4,4,2);
You're passing &samples
as the address of the buffer. So what you're telling i2s_read()
is to read 4 bytes of data and store them in samples
, which doesn't make a lot of sense since it's a pointer. You should just pass &s
as the buffer and skip mucking about with samples
.
The second problem is you're passing 4
as the bytes_read
argument. I'm actually surprised this even compiled. This makes i2s_read()
attempt to store a size_t
with the number of bytes read at address 4, which will certainly cause some kind of exception.
Try this:
int32_t sample;
size_t bytes_read;
i2s_read(I2S_NUM, &sample, 4, &bytes_read, 2);
This:
int
and guarantees a 4 byte (32 bit) integer for sample
i2s_read()
size_t
so that i2s_read()
can store the number off bytes it read.And if you want to know how many bytes were actually read, that's in bytes_read
.
User contributions licensed under CC BY-SA 3.0