-
Notifications
You must be signed in to change notification settings - Fork 57
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
MIC_CONVERT #17
Comments
Hmm. It works just fine for me as is (i.e. using 32 bits). 32 bit:
Yes, the rightmost byte might contain non-zeros, but it will be shifted anyway. If I'm trying to use 24 bit sampling, I'm getting quite weird results, which I even don't know how to interpret: 24 bit:
I'm using:
The only reason I was looking through issues is because I messed up communication format a bit, trying to fix deprecations. typedef enum {
I2S_COMM_FORMAT_STAND_I2S = 0X01, /*!< I2S communication I2S Philips standard, data launch at second BCK*/
I2S_COMM_FORMAT_STAND_MSB = 0X02, /*!< I2S communication MSB alignment standard, data launch at first BCK*/
I2S_COMM_FORMAT_STAND_PCM_SHORT = 0x04, /*!< PCM Short standard, also known as DSP mode. The period of synchronization signal (WS) is 1 bck cycle.*/
I2S_COMM_FORMAT_STAND_PCM_LONG = 0x0C, /*!< PCM Long standard. The period of synchronization signal (WS) is channel_bit*bck cycles.*/
I2S_COMM_FORMAT_STAND_MAX, /*!< standard max*/
//old definition will be removed in the future.
I2S_COMM_FORMAT_I2S __attribute__((deprecated)) = 0x01, /*!< I2S communication format I2S, correspond to `I2S_COMM_FORMAT_STAND_I2S`*/
I2S_COMM_FORMAT_I2S_MSB __attribute__((deprecated)) = 0x01, /*!< I2S format MSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_MSB) correspond to `I2S_COMM_FORMAT_STAND_I2S`*/
I2S_COMM_FORMAT_I2S_LSB __attribute__((deprecated)) = 0x02, /*!< I2S format LSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_LSB) correspond to `I2S_COMM_FORMAT_STAND_MSB`*/
I2S_COMM_FORMAT_PCM __attribute__((deprecated)) = 0x04, /*!< I2S communication format PCM, correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/
I2S_COMM_FORMAT_PCM_SHORT __attribute__((deprecated)) = 0x04, /*!< PCM Short, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT) correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/
I2S_COMM_FORMAT_PCM_LONG __attribute__((deprecated)) = 0x08, /*!< PCM Long, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG) correspond to `I2S_COMM_FORMAT_STAND_PCM_LONG`*/
} i2s_comm_format_t; Currently in source code format is set as: |
Hi, I am sorry, but I was wrong. By the time I opened the issue, I was trying to save the data into an SD and playing it on audacity to verify that I was reading the mic correctly, and I was confused because there was no combination that worked fine. Since then I've replaced Arduino and now I am doing my project in the espressif IDF framework directly. I do not remember which settings I was using when I sent you the issue, but I can tell you that now I am using next settings: static void i2s_example_init_std_rx(void)
{
/* Step 1: Determine the I2S channel configuration and allocate two channels one by one
* The default configuration can be generated by the helper macro,
* it only requires the I2S controller id and I2S role
*/
i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle));
/* Step 2: Setting the configurations of standard mode and initialize each channels one by one
* The slot configuration and clock configuration can be generated by the macros
* These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode.
* They can help to specify the slot and clock configurations for initialization or re-configuring */
i2s_std_config_t rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED, // some codecs may require mclk signal, this example doesn't need it
.bclk = CONF_I2S_BCLK,
.ws = CONF_I2S_WS,
.dout = CONF_I2S_DOUT,
.din = CONF_I2S_DIN,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
/* Default is only receiving left slot in mono mode,
* update to right here to show how to change the default configuration */
// rx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT;
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &rx_std_cfg));
} and the data I read from the i2s is like this:
As you can see, the last byte is always I've been doing a lot of tests with diferent settings and this is the one that works fine for me. That you get I am using:
Again, thank you for your work, it helped me a lot! |
I've just found a good explanation why last byte could be non-zero. I haven't tried to replace resistor myself, but sound like it should fix the issue. Interesting that with IDF 5.1 you have always zeros in last byte. Seems like they've changed API/config a bit since 4.x, probably they introduced other changes there as well, like how they handle last byte/tri-state. Probably should check 5.x version as well. BTW, I'm curious, if you've managed to use it successfully in your project, what were SPL values you've got? I'm a bit confused, because minimal SPL value in complete silence I'm getting is 40 dBA. I understand that the mic has self noise, but according to specs it should be 33 dBA, so I'm not sure where additional noise comes from. Here is typical "silence" looks like in my case: Have you experienced something similar? Update: Ahh... Somehow I missed that by default C-weighting is used, not A-weighting as I was expecting: #define WEIGHTING C_weighting // Also available: 'C_weighting' or 'None' (Z_weighting) With A-weighting I'm getting 36 dBA minimum, which is closer to 33 dBA that I'm expecting, but maybe still missing something... |
20000-30000 values seems like too much even for pretty bad instance. I would double check there is no EM/RF interference. I had similar values with one of my ESP32 boards when streaming audio over WiFi, and I was able to hear how noise changes, moving the mic around the board, closer or farther from it. However for another ESP32 board I didn’t have such issues, even when streaming. BTW, don’t know if you are finally using 24 or 32 bit sampling, but seems like having bit width less than 32 bits causes folding/aliasing. Although ICS 43434 and 16 bits was mentioned there, I see similar issue with INMP441 and 24 bits sampling (it is even worse): |
Thank you for your feedback, it helped. I've changed the cable for a longer one so I can put the mic away from the electronics and I get results closer to your ones. Filtering: #define WEIGHTING A_weighting
#define MIC_EQUALIZER INMP441
res->sum_sqr_SPL = MIC_EQUALIZER.filter(df_buf, df_buf, DATA_BUF_SIZE);
res->sum_sqr_weighted = WEIGHTING.filter(df_buf, df_buf, DATA_BUF_SIZE); Closer, but still worse than your values. |
You could also try lowering wifi power (if you are using it):
The last frequency response chart I posted with big peaks was to demonstrate another issue (not related to microphone self noise in silence). To get it I played 5kHz tone on my mobile phone and recorded it with the mic using 24 bit width. You can see there is a correct peak at 5kHz, but you also get multiple other peaks. You can read more explanation by the link I provided in my previous post. However if recording with 32 bit depth there is no such issue. I mentioned this as there was prior conversation wether to use 24/32 bit sampling. Besides RF/EM interference there seems to be some weird noise variability after device restarts. I described it in more detail here. So if you make multiple recordings separated by device restarts, you might get slightly different results. I've just tested it in absence of external noise, but there more tests needed to see how measurements might differ in presense of some real signal. |
Cool! I am using 32 bits data width for the i2s configuration: i2s_std_config_t rx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED, // some codecs may require mclk signal, this example doesn't need it
.bclk = CONF_I2S_BCLK,
.ws = CONF_I2S_WS,
.dout = CONF_I2S_DOUT,
.din = CONF_I2S_DIN,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
}; I also did a similar test with the long cable, generating 3 tones with my laptop (https://onlinetonegenerator.com/multiple-tone-generator.html) (440 Hz, 600Hz and 1900Hz) and they are correctly resolved: I will try to check if I see those differences on restarts of the mic with my units, will comment on your issue (yep, when reading the issue I realized, you are not the author of the repo, my bad) |
Yes, with 32 bits it should be OK
Haha, unfortunately not, just trying to learn from it, just like you :) |
Hi,
First of all, let me thank you for this project, which has helped me greatly in my own project. I am adapting your code to a project to check the noise of a street, and I think I've found a problem in your code, although I may be wrong.
When you configure the I2S driver you set the bits_per_sample to 32:
Where
SAMPLE_BITS = 32
.After reading data with i2s, you shift the samples with the
MIC_CONVERT
macro:The problem is that in my setup (with an INMP441) when I set the sample bits to 32, the values are already right aligned. If I print some samples with
#define SAMPLE_BITS 32
:If I set
#define SAMPLE_BITS 24
then values output by the mic are left shifted 8 bits:So you should shift the samples if you set
SAMPLE_BITS
to 24 only.It seems that the LSbits are crappy (either 00 or FC only) when
SAMPLE_BITS
is set to 32, and might be losing resolution.The problem is that you might be working with 16 bits samples and not 24 if you set
SAMPLE_BITS
to 32 and shift the samples by 8 bits. This made me think that the way to calculateshort_SPL_dB
could be wrong, as you count the reference as 24 bits, not 16 bits:In my opinion, at least with an INMP441, the way to operate should be: initialize the driver with
#define SAMPLE_BITS 24
and shift samples 8 bits to the right:This implementation breaks your solution for several MEMS, but as I only have INMP441 sensors I do not know if this happens in all of them or just on the INMP441.
Thank you for your time
The text was updated successfully, but these errors were encountered: