Since quite a few construction zones popped up around my flat, I’m continuously exposed to heavy noise, hammering and concreting vibrations during the daytime. Some colleagues of mine asked me about the situation. As I wasn’t able to provide any answer of scientific meaning, I came up with the idea of building a sensor node that continuously tracks the sound pressure. The whole project is designed to be a weekend project, knowing that many aspects can be improved.

With that idea in mind, the work of choosing the right hardware components began. The device shall be located at the balcony and store the gathered data in a locally hosted influxDB. Ideally, the whole setup should work wirelessly and without any service being required. The requirements due to tolerances are not that tight: A low temperature-behavior and somehow comparable results were excellent. But everything above that is primarily determined by what is possible with the given budget.

Disclaimer: In this project no audio information apart from the sound pressure level is processed or captured. There is no possibility to gain any vocal information out of the captured sound pressure measurements.

MCU

Choosing the right MCU was one of the most straightforward tasks. The requirement of wireless communication directly put me in the direction of ESP32 controllers. These are incredibly well supported, cheap, and provide onboard wifi. I ended up taking a development board that includes an ESP32-WROOM-32 module.

Microphone

Selecting the microphone was already a bit more involving. The first idea was to take an electret microphone capsule. But how to build the amplifier? Most amplifiers require a dual supply (positive and negative supply voltage). Moreover, the microphone signal would require a logarithmizing circuit to provide a high enough dynamic range. All in all, the introduced error, including inadequate decoupling on a prototyping PCB, temperature coefficients, matching, etc., is way too unpredictable for the given scope.

However, it turned out that there are modules available that already provide a suitable amplification. Only the AD-conversion and post-processing have to be carried out by the MCU. These modules are mostly equipped with a potentiometer to adjust the gain. This, however, leads to further difficulties: How accurate are the populated components? How to set the gain without any calibrated reference? How linear is the circuit? Still not the right choice for the task.

Finally, an I2S MEMS microphone like the INMP441 sounded promising. It directly delivers a digital signal, is factory calibrated, has acceptable tolerance and a minimal temperature coefficient due to the MEMS technology.


More Things to Consider

The next step to worry about is sufficient protection against environmental conditions. Although my balcony is relatively well protected from direct rain, there still might be high moisture and dust in the air. I decided to put everything into a plastic case and leave holes to expose the sensors to the environment, hoping that the microphone membrane will remain functional and accurate over a long enough period. Some silica gel is added to absorb moisture on temperature changes.

To enclose the entire setup in a small and tightly sealed box concerned me in terms of produced heat. Since the MCU continuously performs signal processing tasks, the power dissipation might be a relevant factor. Subsequently, two temperature sensors of type DS18B20 are included. One takes measurements of the out-temperature. The other one observes the temperature progress inside the sealed box. In that way, the overdrive temperature can be computed, and a safety shut-off performs if something goes wrong.

Software

Thanks to Ivan Kostoski, who did some excellent work on building a sound level meter based on I2S digital microphones, making the software was a piece of cake. In his GitHub repository [1], he spent a lot of effort in frequency compensating the microphone, applying the correct frequency weighting, and providing ready pre-prepared sound pressure readings.

Based on this software, I added MQTT support and code to read the two temperature sensors regularly. All readings are published to a Mosquitto MQTT broker running on a Raspberry Pi 4.

Once the messages arrive at the MQTT broker, they are processed by a node-red flow. It turned out that influxDB combined with Grafana does not support a feature to compute moving average RMS values. I ended up trying different ways but got stuck every time. E.g., calculating the RMS averages in Grafana failed because mathematical transformation does not support taking the square-root of samples. Also, some appropriate aggregation is currently not available [2]. Hence, the RMS values for different window-sizes are computed in node-red by the cost of additional storage being used.

Node-Red data flow.

Results

In the end, data is transmitted wirelessly by MQTT, as mentioned in the concept. The supply, however, is provided by cables (USB, 5 volts). This takes away a lot of the effort in designing the software with a focus on energy efficiency. With a flat-flex cable of an old printer, I could bring the supply through my window directly to the sensor node without worrying about having a large enough battery, a propper (photovoltaic) energy source, and so on.

The attached figure shows the measurement results of the sound pressure and temperature reading. Apart from some erroneous samples (needs more investigation), the in-box temperature is raised by about 3 degrees centigrade. Much less than expected for the work carried about within in the MCU. A simple USB current meter from china shows an average current consumption of about 50 mA at 5.1 volts which is fine.

Temperature samples.

In the Grafana plots, the sound pressure levels are shown at different levels of downsampling. The readings seem to be within the assumed range. Although I don’t own a calibrated VU-meter to compare the values, a check with a smartphone app showed comparable results.

Sound pressure samples RMS over 1 second („slow“) with A-weighting [db(A)].
Sound pressure samples RMS over 5 minutes and 30 minutes with A-weighting [db(A)].

Further Adjustments

There are already some aspects I’d like to improve: The currently provided samples of the sensor node are one-second RMS measurements. It would be great to provide 1/8-second RMS measurements according to the measurement standard „fast“. Moreover, reporting the peak values within each second could also provide useful information. Many sound sources are, e.g., hammers or nailguns that produce high intense but short sound pressure impulses. Due to computing the RMS over one second, these spikes are mainly lost.

  • [1] https://github.com/ikostoski/esp32-i2s-slm
  • [2] https://stackoverflow.com/questions/61477564/is-there-a-way-to-create-a-custom-aggregation-function-in-influxdb