Why?
I’m not living in a very big city and I’m not living on a major street either but I happen to live on a somewhat busy bus lane with around 30 buses going in two directions every hour. That means whenever my windows are open, watching movies, listening to music or simply having a nap gets interrupted regulary by some loud thing going by. Over the five years I’ve been living here, I grew more and more annoyed until I finally decided to use my anger for something sensible. Since I was looking for a topic for my master’s thesis anyway, I went a little bit outside of the usual spectrum of my IT study programme and ventured into the world of electronics. I set out to build a noise sensing device to allow laymen to make themselves aware of the noise in their surroundings. I was supported by the Media Lab Bayern both financially and with contacts to data science journalists who expressed interest in making environmental noise a more approachable topic for the general media.
My idea was relatively straight forward:
- The device should be affordable and henceforth as cheap as possible. The magic number I gathered from interviews turned out to lie between 10 and 20 Euros.
- Multiple devices should be able to communicate between each other, forming some sort of small network for higher resolution and/or accuracy improvement.
- To make using the device as simple as possible for non-techies (and save myself some work), I’d exploit the already existing and easy to use senseBox framework for Citizen Science. I should mention that, eventually, the device would also work on its own.
This results in very simple requirements for what I had in mind: A microphone for recording the environmental sound, a wireless communication device – I chose LoRa, and some form of microcontroller for sound level calculation and mediation between the other two components.
As always, I took my first steps with an Arduino Uno which proved to be far too slow for what I had in mind. Besides, both flash memory and RAM quickly become an issue for more complex software on the Aruino Uno. I looked into the STM32 range, instead. First trying with the famous “Blue Pill” (STM32F103), I soon came to realise that an MCU with more discrete interfaces would make life much more easy for me. I settled on the STM32G031 which at the time was the cheapest ARM MCU that would fit my needs.

Sound capture and analysis
Many sound projects and tutorials seem to go straight for the “classic” analogue electret microphone hooked up to an ADC, preferably with a low-pass filter in front, but I think that a digital interface such as I²S simply offers much more robustness, especially when a LoRa module is churning out RF waves right next to it. Besides, all of the digital MEMS microphones I’ve come across have a low-pass filter built into the package, so the audio data you get is nice and clean and comes in tidy packages.
Since the G031 features a dedicated I²S interface, audio data can be stored directly within a buffer by using the direct memory access controller (DMAC) thus saving valuable cycles for the required mathematical tasks such as the Fourier Transform which was accomplished with the simple arduinoFFT library. The FFT is necessary as sounds are perceived louder or quieter depending on their frequency. This phenomenon is accounted for by using the A-weighting scheme instead of reporting raw values.
Communication
To make the network aspect work, devices need to be able to “talk” to others. On the hardware side I went with the popular RFM95 LoRa modem, mostly because it’s reasonably well supported. Note, that I don’t use the LoRa WAN mode, which is designed for use with so called Gateways for facilitating access to the Internet. I chose a star network arrangement with the senseBox at the center (hub) and every additional sensor node spread out. The sensors report values back to a “special” sensor that is connected to the senseBox PCB via I²C. The senseBox keeps track of the time via NTP, prepares received data for uploading to the openSenseMap and acts as the main initiator. The communication protocol works by sending a sync pulse at specified intervals so auxiliary sensors don’t get out of sync, even without an (expensive) real time clock. Every message is prepended with a network-specific sync-word to avoid crosstalk from alien LoRa devices outside of our network.
Microcontroller
The software is programmed in C++, using STM’s hardware abstraction layer (HAL) to make it a bit nicer to look at. There are still a few quirks about HAL but it’s mostly a very enjoyable experience. To keep power consumption – and therefore battery life – reasonable, the MCU is clocked at only 16 MHz which makes it just fast enough to complete the required computations in time. The MCU also assigns a device ID determined by a combination of resistors soldered onto the PCB. It further monitors the battery level and triggers transmission of a “battery low” message to the master node. During development I came very close to flash memory restrictions and decided to upgrade the G031 MCU to the very similar G071. I’m sure by optimising the code and external libraries the smaller version would work out totally fine but since I couldn’t really spare time to shrink my code, I opted for adding those 0.70 € to the total cost and save optimisation for another time.
PCB and case design
With prior electronic projects tending to look somewhat DIY, I wanted to pay more attention to aesthetics with this prototype. Instead of using perfboard, I designed the PCB in KiCAD and sent it off to a PCB manufacturer. The battery pack and PCB are enclosed in a 3D printed PLA case that offers some protection from the elements. It probably won’t win a Swedish design award but I like to think it’s a step-up from my previous stuff.

Accuracy and Evaluation
I evaluated my design against a reference SPL meter and am happy to report an accuracy of less than 2 dbA deviation which should be sufficient for basic Citizen Science needs. Any measurement taken by laymen outside of a scientific setting will be prone to measurement errors of some form, so reported values should only be used as an indication and to warrant further investigation with more reliable equipment.

Ease of use
To find out whether I had actually built something that’s easy to use, I scheduled three user tests with journalists whereas two of those would also include building the sensor yourself. Unfortunately, due to various circumstances only one test could actually be carried out before the dead line. Therefore, I’m lacking reliable data but did at least get some feedback, which was mostly positive.
Visualisation
The final part of the thesis was to look into ways of communicating loudness values in an accessible and easily understandable form. I conducted a survey amongst 23 participants to compare three visualisation methods I’ve devised by adhering to common data visualisation techniques and standards that focus on communicating data uncertainty that is inevitably introduced in a Citizen Science setting. These visualisations aim to avoid over-interpretation of data by keeping the resolution deliberately low.
In summary
I think this thesis worked out alright. I slightly overshot my 20 € maximum by 4.15 € but that’s mainly due to extra charges for faster manufacture and delivery. As always, time restrictions resulted in some intended features being cut short. Still, for a prototype everything works fine. There are, of course, things I’m not completely satisfied with.
The protocol design in its current state is not especially robust. That means, that packages can easily be lost during transmission and are then gone for good. I’d like to revise the protocol in the future by including acknowledgement packages and resending capabilities. Yet, when implementing such features, one must also pay attention to avoid spamming the LoRa band with too many transmissions out of fairness to other devices.
Even if not strictly necessary, I’d love to shrink down my code to make it fit into the G031 I originally intended to use. It’s not a great improvement in terms of overall cost but would be an interesting challenge. In general, running a second iteration to cut down on cost and overhead might be really fun to do, even though it’d probably eat up a considerable amount of time.
Finally, only being able to conduct one out of three (which is already a tiny sample) user tests along with a measly 23 study participants was a harsh disappointment. I doubt I’ll repeat those surveys anytime soon but this way it feels like unfinished business to me.
I had to shorten this entry quite a bit. Fitting a whole master’s thesis into a bearable length article is quite hard, so feel free to check out the full PDF if you’re interested in the details.
You can find the schematic and code for this project in the corresponding git repository.