ESP32 with INM441 I2S microphone.
Re: ESP32 with INM441 I2S microphone.
just confirming my "artifacts in the low-bye:
using I2S_STD_MSB_SLOT_DEFAULT_CONFIG:
...
val:0x000015e0
val:0x000030e0
val:0x00003fe0
val:0x7ffe4ae0 -neg value
val:0x0000a3e0
val:0x7fffa6e0 -neg value
...
using I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG:
...
val:0x000151c0
val:0x00040fc0
val:0xffffd5c0 -neg value
val:0x000263c0
val:0x00021fc0
val:0x000255c0
val:0x0002c9c0
val:0xfffebfc0 -neg value
...
so yes,I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG is the right choice. otherwise its right-shifted by 1.
Still, there shouldnt be any bits set in the low-byte.
using I2S_STD_MSB_SLOT_DEFAULT_CONFIG:
...
val:0x000015e0
val:0x000030e0
val:0x00003fe0
val:0x7ffe4ae0 -neg value
val:0x0000a3e0
val:0x7fffa6e0 -neg value
...
using I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG:
...
val:0x000151c0
val:0x00040fc0
val:0xffffd5c0 -neg value
val:0x000263c0
val:0x00021fc0
val:0x000255c0
val:0x0002c9c0
val:0xfffebfc0 -neg value
...
so yes,I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG is the right choice. otherwise its right-shifted by 1.
Still, there shouldnt be any bits set in the low-byte.
-
MicroController
- Posts: 2661
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32 with INM441 I2S microphone.
The INM441's output appears to go high-z after the 24th bit, so there can easily be 'echoes' of the last valid bit if you have no pull-down/-up on the line. In any case, any bits you see after the 24th are invalid, don't indicate a problem, and can be safely ignored.
Re: ESP32 with INM441 I2S microphone.
I admit to not fully understanding how the INMP441 interface works
I looked at many (and contradictory!) examples online, especially https://github.com/kaloprojects/KALO-ES ... -Assistant lib_audio_recording.ino to get my code working, which it does appears to - it's deployed in two bird recorders that have been operating for 8 months. Nevertheless I'm very willing to believe that it can be improved.
Let's see if we can clear up various points.
1. The INMP441 interface delivers 32 bit samples which contain 24 bit of data in the high order bytes. This is fixed in the mic h/w and cannot be changed (according to info I read online) so I2S has to be configured with data_bit_width = I2S_DATA_BIT_WIDTH_32BIT. This therefore contradicts the KALO-ESP32-Voice-Assistant example which uses I2S_DATA_BIT_WIDTH_16BIT, so I'm confused.
2. I understand that in MONO mode, each 32 bit sample (which contains 24 bit of data) is taken from the configured channel (from the L/R setting) at the configured sample rate. @xenpac suggests that both left and right channels are always sampled, which means what? That the samples alternate left and right and so the sample rate for each channel is only half the configured rate? Or that there are 2x32 bit values for each sample? And if it does sample both channels, how to know which is left and which is right at any particular point? This is certainly not what my code assumes, although in stereo mode they would be questions to be answered.
Let's try those questions first before any others.
Let's see if we can clear up various points.
1. The INMP441 interface delivers 32 bit samples which contain 24 bit of data in the high order bytes. This is fixed in the mic h/w and cannot be changed (according to info I read online) so I2S has to be configured with data_bit_width = I2S_DATA_BIT_WIDTH_32BIT. This therefore contradicts the KALO-ESP32-Voice-Assistant example which uses I2S_DATA_BIT_WIDTH_16BIT, so I'm confused.
2. I understand that in MONO mode, each 32 bit sample (which contains 24 bit of data) is taken from the configured channel (from the L/R setting) at the configured sample rate. @xenpac suggests that both left and right channels are always sampled, which means what? That the samples alternate left and right and so the sample rate for each channel is only half the configured rate? Or that there are 2x32 bit values for each sample? And if it does sample both channels, how to know which is left and which is right at any particular point? This is certainly not what my code assumes, although in stereo mode they would be questions to be answered.
Let's try those questions first before any others.
-
MicroController
- Posts: 2661
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32 with INM441 I2S microphone.
1) Haven't verified it, but I assume that the mic starts outputting bits from the MSB whenever it gets 'selected' by the WS line and stops outputting bits when it gets 'deselected'. So the I2S master can clock as few bits per sample out of it as it wants.
2) With only one mic, the master will still clock in both left and right samples alternatingly, but one of the channels contains no data, or only digital noise from the floating data line.
2) With only one mic, the master will still clock in both left and right samples alternatingly, but one of the channels contains no data, or only digital noise from the floating data line.
Last edited by MicroController on Sun Jan 18, 2026 8:10 pm, edited 2 times in total.
Re: ESP32 with INM441 I2S microphone.
2) With only one mic, the master will still clock in both left and right samples alternatingly, but one of the channels contains no data, or only digital noise from the floating data line.
So does this mean every other sample I get is garbage, to be ignored? Currently I process every sample assuming it comes from the single mono channel.
-
MicroController
- Posts: 2661
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32 with INM441 I2S microphone.
Apparently, the ESP32's I2S can be configured to ignore either channel (I2S_RX_FIFO_MOD "mode 3", "32-bit single channel data"), and the docs seem to confirm that only the selected channel's data is returned.So does this mean every other sample I get is garbage, to be ignored?
Btw, it may be a good idea to enable the pull-up or pull-down on the data pin as otherwise the line is left floating whenever the mic isn't actively driving it (which would be >50% of the time with only one mic connected.)
Re: ESP32 with INM441 I2S microphone.
Apparently, the ESP32's I2S can be configured to ignore either channel (I2S_RX_FIFO_MOD "mode 3", "32-bit single channel data"), and the docs seem to confirm that only the selected channel's data is returned.
Btw, it may be a good idea to enable the pull-up or pull-down on the data pin as otherwise the line is left floating whenever the mic isn't actively driving it (which would be >50% of the time with only one mic connected.)
It would seem to do this automatically if I2S_SLOT_MODE_MONO is set since all the samples I get seem valid for the single channel.
I conclude that all seems OK with my code and setup (I do have the data pin pulled down, as recommended).
I actually tried out another I2S mic, the MSM261S4030H0R, which seems easier to get hold of. I use this one now as it appears to behave identically. There is one difference in the spec: the INMP441 says that VDD should be decoupled to ground with a 0.1uF capacitor; the MSM261S4030H0R has the same but specifies a 0.1uF plus a 10uF capacitor. This makes no sense to me and I assume it's a mistake. Actually I've found that decoupling using either has little effect. The mics are quite noisy, as shown in their output spectrograms.
-
MicroController
- Posts: 2661
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32 with INM441 I2S microphone.
Correcting myself:
INM441 Datasheet says
INM441 Datasheet says
So slot_bit_width must always be I2S_SLOT_BIT_WIDTH_32BIT, but data_bit_width can still be set to I2S_DATA_BIT_WIDTH_16BIT if the application only needs 16 bits.There must be 64 SCK cycles in each WS stereo frame, or 32 SCK cycles per data-word.
Re: ESP32 with INM441 I2S microphone.
The inmp441 (and many other i2s devices) creates 24 bits per sample/ADCconversion.
But there is no natural dataype of int24, only int8,int16,int32,int64.
So it is programmed to output the 24bits as a int32, where the low-byte is set to 0.
Thus the 24bit of pcm-data are located on the high side of the int32 value, effectively multiplying the 24bit by 256.
Why it is doing this left-shifting, ? we dont know, but increased amplitude seems good.
To place it on the I2S-Bus it expects 32 serial clocks for every such int32 value.
Also it expects the WS-line to have configured polarity so it knows when to place the data (stereo).
The I2S transports by default 2 audio channels (stereo) and outputs a WS-signal to indicate which channel shall currenty be supplied.
So it transports stereo frames with 2 int32 values (left/right) forming a "sample".
The "Samplerate" (number of ADCconversion per second) is valid for both channels.
The "Datarate" for stereo is twice that of a single channel.
So for Every frame containing 2 int32 values, 64 bit clocks are needed and WSsignal toggle in the middle.
On the receiving I2S-side, the esp32 stores the incoming values in a DMA buffer and after a configured number of samples
an interrupt occurs.
The esp32-driver then reads the DMA-buffer and delivers it to the user application.
If you look at the data delivered, you see int32 values where the even addresses represent the left-channel data
and the odd-addresses the right-channel data.
If you only want the left-channel data you have to copy the even-address values to a seperate buffer for further processing.
If you configured the esp32-I2S as "mono" the docu is a bit unclear.
either the left or the right channel will be 0-value in this case, at least what i observed.
Our desire would be to have only the left or the right channel data being delivered by the driver so we dont need to process
the data ourselfs, but ??
As to my "artifacts", the pullup resistor on the dataline is 100K. Maybe a bit too high.
Will experiment with lower values. My INMP441 is from china.
But there is no natural dataype of int24, only int8,int16,int32,int64.
So it is programmed to output the 24bits as a int32, where the low-byte is set to 0.
Thus the 24bit of pcm-data are located on the high side of the int32 value, effectively multiplying the 24bit by 256.
Why it is doing this left-shifting, ? we dont know, but increased amplitude seems good.
To place it on the I2S-Bus it expects 32 serial clocks for every such int32 value.
Also it expects the WS-line to have configured polarity so it knows when to place the data (stereo).
The I2S transports by default 2 audio channels (stereo) and outputs a WS-signal to indicate which channel shall currenty be supplied.
So it transports stereo frames with 2 int32 values (left/right) forming a "sample".
The "Samplerate" (number of ADCconversion per second) is valid for both channels.
The "Datarate" for stereo is twice that of a single channel.
So for Every frame containing 2 int32 values, 64 bit clocks are needed and WSsignal toggle in the middle.
On the receiving I2S-side, the esp32 stores the incoming values in a DMA buffer and after a configured number of samples
an interrupt occurs.
The esp32-driver then reads the DMA-buffer and delivers it to the user application.
If you look at the data delivered, you see int32 values where the even addresses represent the left-channel data
and the odd-addresses the right-channel data.
If you only want the left-channel data you have to copy the even-address values to a seperate buffer for further processing.
If you configured the esp32-I2S as "mono" the docu is a bit unclear.
either the left or the right channel will be 0-value in this case, at least what i observed.
Our desire would be to have only the left or the right channel data being delivered by the driver so we dont need to process
the data ourselfs, but ??
As to my "artifacts", the pullup resistor on the dataline is 100K. Maybe a bit too high.
Will experiment with lower values. My INMP441 is from china.
-
MicroController
- Posts: 2661
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32 with INM441 I2S microphone.
As to my "artifacts", the pullup resistor on the dataline is 100K. Maybe a bit too high.
Will experiment with lower values. My INMP441 is from china.
The SD trace should have a pull-down resistor to discharge the line during the time that all microphones on the bus have tri-stated
their outputs. A 100 kΩ resistor is sufficient for this, as shown in Figure 7.
Who is online
Users browsing this forum: Baidu [Spider] and 11 guests