ESP32 Audio Input Using I2S and Internal ADC

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone for my next project i need to get audio data into the esp32 to do this we're going to use the built-in analog-to-digital converters on the esp32 now the esp32 integrates two 12-bit analog to digital converters adc1 has 8 channels and adc 2 has 10 channels adc2 is used by the wifi driver so we can only use adc2 when not using wi-fi in addition some of the pins attached to adc2 are used for strapping pins so it cannot be used freely i'm going to be using wifi in my project so i'll stick to using adc1 for simple low frequency sampling we can use the arduino analog read or we can use the expressive adc functions directly if you need very accurate readings then you can calibrate your analog to digital converter the chips manufactured recently this may have been done in the factory but if required you can also do this manually check the description for some links on how to do this to get a calibrated value from the adc we need to do a few steps we need a full back value for the vref if nothing is available from the calibration system we then need to set up our adc in a known configuration in this example code we are setting our adc to 12 bit resolution giving us a range from naught to 4096 we're also setting our attenuation to 11 db this should give us the full input range from naught to 3.3 volts we can now pull back the calibration characteristics for these settings and now we can get the raw value from the adc and map it onto a voltage using the calibration characteristics to test this i've hooked up a potentiometer to one of the adc channels and printed out both the raw value and the calibrated value in a loop as we vary the voltage on the pin the value read from the adc changes you can see from my dev board that it's been factory calibrated with a vref value using the adc in this way is fine if you only need to get a value every so often or you want to sample at very low frequencies for very low quality speech we need to capture a bandwidth of around four kilohertz for good quality speech we need around eight kilohertz and for high quality audio we need a bandwidth of 20 kilohertz to avoid issues with aliasing we need to sample at the nyquist rate which is twice the highest frequency you want to sample for audio this would be around 40 kilohertz you can see in this animation the effect when the sampling rate is too low as the input frequency approaches past the nyquist limit we start to see aliasing and the output signal cannot be reconstructed from the samples since our audio signals will go up to 20 kilohertz we need to sample at a minimum of 40 kilohertz now doing this in a loop on the cpu would leave us no time for doing any other work our cpu would be constantly polling the adc for new samples and would not have much time for any other processing we would also struggle to achieve a consistent sampling period leading to weird artifacts in our audio fortunately there is an alternative mechanism for reading samples from the adc we can use the i2s peripheral to read the samples this has a dedicated dma controller that allows us to stream samples straight into ram buffers independently from the cpu i've written a simple sketch that uses i2s to read the samples and as audio data becomes available it streams it to a server running on my desktop computer which writes the audio data to disk i've set a sample rate of 40 kilohertz and allocated four dma buffers at 1024 bytes each this should give us sufficient time to process any buffers without them being overwritten with new data we've set up the i2s peripheral to read from adc one channel seven this equates to gpio35 and then we set up a task to read the values from the its queue looking at our reader task it waits for an itos event rx done to be received and then reads bytes from the dma buffer into our own local buffer once we've read all the samples we're interested in we do whatever processing we need to do and in our case i'm just sending the samples over to a local server running on my desktop machine here's the output when we use our potentiometer to change the values on the adc for this example i've just used a sampling rate of 10 kilohertz we can now move on to getting audio into the system i've got two microphone breakout boards the max 4466 and the max 9814 now the max 4466 has an adjustable gain from 25 times to 125 times and the max 9814 has a built-in automatic gain control this will make quiet sounds louder and louder sounds quieter both these modules are simple and easy to wire up only requiring power and ground so here's an audio recording from the max 4466 testing testing as you can hear we have some audio data but it's terribly noisy and it's not going to be usable uh here's the audio recording from the max 9814 testing testing one two three it's a bit better but there is still quite a lot of noise coming through it looks like the noise can inside with our transmission of data over wi-fi i've attached an oscilloscope to the 3.3 volt output from the dev board and the output from the max 4466 you can see that our 3.3 volt line has a lot of noise when the module is transmitting this noise is being amplified by the sensitive op amps on the microphone board looking at the v in line we can see a similar problem so what can we do we could connect up a separate power supply or we could use a battery to power our microphone boards but this is not going to be very convenient we could also turn off wi-fi but i need wi-fi for my project so the underlying problem seems to be the current draw when the esp needs to transmit this is causing a large amount of noise on the 3v3 power rail which is then picked up by the very sensitive microphone amplifiers i've tried adding capacitors which have a small effect but to really fix it we would need to add excessively large capacitors to both the vin and the 3v3 rails so our microphone boards don't require very much current so what we can do is take the vin line and pass it through an rc filter for my tests i'm just using a 30 ohm resistor and a 470 microfarad capacitor we can then feed this filtered signal into a low dropout regulator to generate a clean 3v3 power supply for the microphone boards looking at the low-pass filtered vin we can see that we have a cleaner signal and on the 3v3 output of the regulator we now have a pretty clean signal with noise down to around 20 millivolts instead of the 200 millivolts that we were seeing on the original 3v3 line from the board looking at a trace from our microphone boards here's the max 4466 we don't see any noise now when the esp32 transmits and the same is true for the max 9814 so here's an audio sample from the max4466 testing testing one two three and an audio sample from the max 9814 testing testing one two three they are both better but still quite noisy one thing we can do is filter out some of the noise by over sampling and then take an average value as the actual sample value so i've tried using a median filter here and you can see that our simulation shows quite an impact and here's the audio from the max 4466 testing testing one two three and the audio from the max 9814 testing testing one two three so which module should we actually use for my next project i think the max 9814 comes out the winner it seems to be less susceptible to power supply noise and the automatic gain control makes it very useful we don't have to fiddle with a potentiometer to change the volume um if you really need high quality low noise input then the built-in adcs on the esp32 are probably not suitable and i would take a look at some external boards for this kind of project but on balance i think we'll use the max 9814 for my next project so thanks for watching i hope you found this video useful and interesting all the code is in a github repo the links in the description if you did find the video useful then please subscribe to the channel and hit the like button there's another video coming soon well i'll actually do something with the audio data so see you in the next video
Info
Channel: atomic14
Views: 104,970
Rating: undefined out of 5
Keywords: esp32 audio recording, esp32 analog input, esp32 analog read, esp32 i2s dac, esp32 microphone, esp32 i2s adc, esp32 adc calibration, esp32 adc, analog to digital converter, esp32 projects, max4466, esp32 max4466, max9814, exp32 max9814, esp32 analog digital converter, esp32 audio input, max4466 microphone, max9814 microphone, esp32 mic, esp32 microphone input, nyquist rate, nyquist limit, esp32 analogread example, esp32 analogreadresolution, esp32 analogread arduino
Id: pPh3_ciEmzs
Channel Id: undefined
Length: 10min 43sec (643 seconds)
Published: Mon Aug 17 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.