Custom wired doorbell chime with an Arduino MKR Zero
This is a small DYI project to replace a very old doorbell chime with a custom-made one using an Arduino board. There are plenty of commerical products out there, but they are either wireless or very bulky. My old doorbell chime was built into an electric box, and I wanted to keep the form factor, while improving the sound.
The MKR Zero is a very nice board for such a project, due to its small form factor. It has an integrated SD card reader and can play sounds through I2S. To convert audio signal into sound, it needs an external board that acts as a DAC/Amp as well as a loudspeaker.
The initial inspiration for this project came from the following tutorial. This program uses the Arduino Sound Library to load a wave file stored on a SD card and play it. We can pretty much copy and paste it, but we need to add an external trigger. This can be simply done by connecting the doorbell button to a digital pin with a pullup resistance.
We could just leave it like that, and have the main loop check for the state of the digital pin. However, it is a bit wasteful. The doorbell button is only triggered rarely and the microcontroller would be sitting idle most of the time. Fortunately, the MKR Zero comes with a MCU equipped with low power features. We thus use the Low Power library to put the board to sleep when it is not being used. The library is able to tie a wakeup even to a digital pin state change, which is perfect for our purpose. We can simply have the main loop play a chime and go to sleep when it's done.
The Low Power library features 3 different sleep modes: Idle, sleep and deep sleep. Deep sleep is the most efficient of them but its wake up time is supposed to be slower. For the doorbell chime application, though, I could not notice any difference between the normal sleep and the deep sleep mode, so I went for deep sleep.
Using an SD card of 1 GB or more to store a door bell chime is quite a waste of storage space. For that reason, I added a feature allowing to play several different tunes. I originally wanted to take advantage of the RTC the MKR Zero provides to play a different tune every month. However, it turns out that the I2S and RTC libraries do not work together. So I ended up rotating among a few different chimes after the doorbell has been pressed for a predefined number of time. It is as simple as loading a new wave file from the SD card.
Just place chime sounds as wave files in the SD card's root
folder. Name them as chime_0.wav
, etc. Wave files can be created
from MP3s with tools like FFMpeg.
Here is the hardware I used for this project:
- Arduino MKR Zero
- DAC/Amp
- Speaker
- USB power adadapter
In addition, you will need a soldering iron, some wire to connect the boards and screws and spacers to attach the boards.
The MKR Zero is powered by the USB power adapter. The DAC/Amp takes power from the MKR Zero 5V output. It also works with 3.3V, but will result in lower volume.
The data connection between the Zero and the DAC/Amp is made by 3 wires connected to pins A6, D2 and D3 on the Zero and DIN, BCLK and LRC on the amp, respectively.
The loudspeaker is connected to the amp's + and - ports.
Finally, the doorbell button should be connected to one digital pin (pin 0 in my listing) and the ground pin on the MKR Zero.
Note that many doorbell buttons are lit by a small bulb. This means that the circuit is closed, even when the button is not pressed. It is a problem for our digital pin, because it will understand that the button is constantly pressed. This issue can be simply solved by opening the doorbell button and removing the bulb.
Formatting the SD card with any OS formatter (Windows, Linux) failed. While the card was readable on both OS, the Arduino board could not handle the file system. I had to use this formatting application to successfully format a card that the Arduino could read.
Once you have uploaded your first program, the Arduino will always go to deep sleep while it is not playing a tune. This is an issue, because a new program cannot be uploaded while the board is in deep sleep. The solution is to press the reset button twice. The orange light will blink and the board is then ready for a new upload.