Close

I2S Microphone

A project log for Street Sense

Portable electronic device to measure air and noise pollution

mike-teachmanMike Teachman 11/05/2018 at 23:451 Comment

Measurement  of noise pollution is one of the ambitions for this project.   Initially, the Street Sense unit will be designed to continuously record a stream of audio samples to a WAV file on a SD Card.  The WAV file will be post-analyzed to identify various audio metrics.

The microphone selected is the Adafruit I2S MEMS microphone based on the SPH0645LM4H-B device.
I2S MEMS microphone

This microphone is compact, low power,  and fits the budget of this project.   The audio sampling is controlled by an I2S digital interface.  The ESP32 micro controller has an I2S interface, which will be configured in Master mode to read audio samples from the microphone.

One challenge is MicroPython - there is no version of MicroPython that supports the I2S capabilities of the ESP32.  The Arduino core for the ESP32 does offer I2S.  However, I am fairly determined to attempt the programming in MicroPython.  This means diving into the bowels of MicroPython and adding I2S Master support.

Using existing MicroPython module implementations as a guide, I wrote the low-level C code to add a new I2S class into the machine module of MicroPython.   Here is a simplified view of the MicroPython code used to read audio samples.

from machine import I2S

SAMPLE_BLOCK_SIZE = 2048
samples = bytearray(SAMPLE_BLOCK_SIZE)
audio=I2S(... initialization arguments ...)
audio.read(samples, SAMPLE_BLOCK_SIZE)
audio.deinit()

Blocks of samples are read from the microphone, then written to the SD Card.  The DMA controller of the ESP32 is configured so that the audio stream is "gapless".  It should be possible to continuously write a WAV file into the SDCard at a 44.1kHz sample rate.  Initial results look promising, although some block writes to the SD Card are longer than others.  Under some conditions sample gaps may appear - more testing needs to be done to evaluate this design risk.

The breadboard prototype is shown below

MicroPython test code was written to capture 10 second audio clips and stream the samples to a WAV file on the SD Card.  A LiPo battery was used to power the unit and traffic sounds were captured at a local street.  Two WAV files containing traffic sounds are attached.  Wind noise is mixed with traffic sounds in the first WAV file.  Some sort of microphone covering will be needed to mitigate wind caused noise.  In the 2nd clip you can hear the sound of a passing ambulance.

Audio clip: Traffic and Wind

Audio clip: Ambulance

Discussions

abdylan wrote 11/01/2019 at 14:50 point

Hi Mike, great article.

Can you please shed light on why, despite having all the code setup right, there are still gaps in the Audio generated? Specifically, what im asking is how can one narrrow this down. Is it cos of the 

(1) DMA buffer len

(2) SD card writing maybe takes 0.1 seconds to write. This maybe skips that 0.1 seconds of audio which in turn has those gaps?

Stuck at this problem for more than a week now. Please guide if possible.

  Are you sure? yes | no