The sound of silence
Part of the project is to wake the amateur astronomer up when it starts raining 🌧️. Or when we lose the communication with the rain sensor.
We will naturally embed a siren alarm in the base station to do that!
In this sound alarm prototype, I did not have a clear idea of what I was aiming for: a simple beep sound? 8-bit music? MP3/WAV music or ringtone? I was also unsure about the technical implications, so I explored many options. I must admit that I got a bit lost and undecided during the journey.
Indeed, we have a lot of options to produce a sound with electronics, each with its own pros and cons. Let’s look at them.
Buzzers vs Speakers
It seems we have two primary hardware components to produce a sound for us:
Piezoelectric buzzers: Quite cheap and easy to use, but they produce a very annoying sound. That’s the usual beep sound you hear very often on “non-media” electronic devices. They are divided into 2 sub-categories:
- Active buzzers: You just need to power them to produce a fixed-pitch sound, thanks to an internal oscillator.
- Passive buzzers: You need to supply an AC signal to produce a sound, and the pitch is affected by the frequency of that signal.
- Speakers: They produce a much more pleasant sound, but they require more hardware to drive them correctly (an amplifier at minimal, we will get back to this later). They need an AC signal.
Having said that, we have plenty of solutions when it comes to the integration:
Active Buzzer: This is the simplest solution. It’s as easy as turning a LED ON. Though, I really don’t want a fixed tone ringing.
Passive Buzzer + PWM Modulation⭐: Slightly more complex than above but still fairly simple: we’re using LEDC (LED control) with the ESP32 to generate a PWM signal to control the pitch. A small capacitor can more or less smooth the squared signal into an AC shape to fine-tune the sound. Sometimes science is more art than science, Morty.
Speaker + Internal ESP32 DAC (digital-analog converter): The idea here is to use the ESP32’s internal DAC to produce a modulated sinusoidal waveform. The DAC is an 8-bit one, which will be okay for Chiptune but not ideal for regular 16-32 bit music. However, the output of the DAC cannot be used to drive a speaker directly because a speaker requires 4-8 Watts of power (that’s 1A in our 3.3V logic circuit!🚒). Therefore, an amplifier is needed in between to “repeat” the logic circuit signal with higher power. The core issue I have with this design is that it looks intimidating code-wise, as the music sampling rate will depend on the CPU clock frequency. This means that we would need to isolate a part of the ESP32 resources (perhaps using interrupt timers?) for the music, while still dealing with radio communication, etc. This solution is too low-level for me. The discovery of the Mozzi library later confirmed my doubts even further.
Speaker + External DAC: We can use an external DAC (16-Bit) to produce better sound. The DAC will still need to be connected to an amplifier to drive the speaker, but it’s common to see the two functions bundled together. That’s the case with the
MAX98357AI’ve tried. We connect this dude to the ESP32 via the
I2S(Inter-IC Sound) protocol. Unlike the previous method, playing a sound is easier on the software side as we deal with highly abstracted libraries. During my tests, I couldn’t achieve this without adding an SD card reader to stream the music from. In another attempt, I would improve this to stream from the ESP32 flash memory or just accept the SD card reader, enabling everyone to customize the alarm sound.
Speaker + PWM Modulation: This was a silly idea I had, thinking I could replace a passive buzzer with a speaker. It turns out this would work, but an amplifier is needed.
Now that we have a good overview of the options, we can break the results as follows:
|Bill of materials
|Passive Buzzer + PWM Modulation
|Speaker + Internal ESP32 DAC
|speaker + amplifier
|Speaker + External DAC (+ SD Card Reader)
|++ / (+++)
|++ / (+)
|speaker + amplifier + DAC (+SD card reader)
|Speaker + PWM Modulation
|speaker + amplifier
The use of a speaker introduces a lot of extras. I haven’t even scratched the surface of the software challenges, such as storing the music files and bundling extra libraries into the build. If using an SD Card is absolutely unavoidable, that would mean having two
SPI devices (the SD card reader and the LoRa module, from part 2), necessitating sharing the SPI bus. My board has a second
SPI bus, but it seems unusable to me: one of the pins must be at 0V at boot time 🤦♀️, a requirement I discovered when failing to boot.
Reflecting on our product values (simplicity, reliability…), it becomes clear that a pragmatic decision is to opt for a Passive Buzzer + PWM Modulation design.
Protoyping the sound alarm
The Passive Buzzer + PWM Modulation and Speaker + External DAC + SD Card Reader architectures are demonstrated in the following video. 🔊🔊🔊
The buzzer chiptune looks really good. On the other hand, you can notice that the speaker volume isn’t stable, I don’t know why at this point but it’s not a power delivery issue.
From here, we really see the difference in terms of complexity between the two architectures.
We’ve learned a few things:
- The Passive Buzzer + PWM Modulation is the best option for our use case. The sound is loud enough, and the quality is certainly adequate for chiptune sounds. It enables us to create distinctly different sounds for each type of alarm (rain or communication lost), unlike the Active Buzzer.
- We spent a considerable amount of time exploring this, but it was fun. I mean, this is an alarm you’re best off never hearing throughout the entire product lifecycle, so we could have omitted the idea of using speakers from the start.
We have two more things to prototype:
- Temperature and Humidity sensors for the rain sensor module.
- A screen 📺 for the base station should follow as well.
Then, it will be about integrating all of these components together. 🏆