So far in this series we’ve had a diverse look at how Arduino can interact with a range of real-world devices from servo motors to ultrasonic range finders TVs to humidity sensors. Now we’ll see if we could get the Arduino to make a few sounds. We’ll actually do a bit better than that – we’ll look at the importance of pulse width modulation (PWM) to microcontrollers by building our own digital audio player called Auduino.
The two versions of our Auduino audio player. The Ethernet shield version (bottom) gives better results with more flash cards.
What we’re building
A few months ago I stumbled across a simple single-button digital audio player based around a Raspberry Pi developed by a guy for his 90-year-old grandmother who needed something simple to use. All it had was a single button and an LED and it was programmed to play digital audiobooks. The button pressed quickly would pause and play while holding it down for more than four seconds would play the previous track.
A digital audiobook player using a Raspberry Pi.
I couldn’t help wondering if we could do something similar and simpler with an Arduino. Well you can. We’ve combined an Arduino Uno microcontroller a $1.50 SD card reader module from eBay computer speakers and some other components to create a simple single-button digital audio player. There’ll be a small amount of soldering involved.
Admittedly our player’s WAV file support is modest (mono 8-bit up to 19kHz) but the quality is still more than good enough to handle music and digital audiobooks. However don’t miss the bigger picture – an audio player we can digitally control opens up a world of possibilities.
Making the WAV files
If you’re wondering where you’ll find 19kHz/8-bit/mono WAV files we’ve got that covered. I’ve created an easy-to-use audio converter that integrates into Windows Explorer and converts any audio file into the required WAV format. You can even convert multiple files at the same time and it automatically turns those files into the 8.3 filenames our player requires. All you do then is copy the WAV files to the root of a FAT32-formatted Class 4 SDHC card (we’ve tested cards up to 8GB). Load the card into the player’s SD card reader module press the button and the first track will begin playing.
How it works
The ability to turn digital data – 1s and 0s – into a proportional analogue voltage is a fundamental tenement of digital audio and it’s where the digital-to-analogue converter (DAC) gets its most celebrated use. Audio DACs appear in every smartphone tablet MP3 player PC and laptop. They’re everywhere. DACs are also used to control motors and sensors LEDs and more – anywhere where you need to turn a digital number into a real-world analogue voltage. One of the simplest ways to do it is what makes microcontrollers so popular – it’s called Pulse Width Modulation (PWM).
The problem for all microcontrollers is that their standard digital outputs only have two positions: high and low. The output will either be at the supply rail (Arduino’s 5V) or ground (0V); there’s no in between. This is where PWM comes in. It starts with a clock signal output that runs at a much higher rate than we need; in our case beyond the 20kHz audio spectrum. That clock signal is a squarewave meaning it spends half the time at digital-1 and half at digital-0 in each clock cycle. In geek speak we say it has a duty cycle of 50%.
What PWM allows us to do is modulate that duty cycle so that when its pulse waveform output is fed and filtered through a particular device the waveform is averaged and becomes an analogue voltage that’s proportional to the duty cycle. So if the waveform signal varies between 0 and 5V and has a 10% duty cycle it’ll have an average analogue voltage of 0.5V. At 50% duty cycle it’ll be 2.5V; at 90% it’ll be 4.5V.
This is how the pulsating LED on your iPhone or iPad works. The LED will be fed with a PWM waveform that varies between 0 and 100% duty cycle at a high enough frequency so you can’t see the LED flashing.
Your typical music file is the result of the reverse process: turning a complex analogue voltage into a digital representation. Audio CDs capture two channels (stereo) at a 44.1kHz sample rate with 16-bit resolution. What that means is there are 216 or 65536 distinct voltage levels that can be captured every 22.6 milliseconds or so.
It’s called Pulse-Coded Modulation (PCM) and it’s the basic format used by Windows’ WAV file format. Look at a WAV file and you’ll see a long series of 16-bit numbers that represents the audio (one per sample and one per channel). Turning those digital samples back into an analogue voltage is what every audio player does.
One way of doing this happens to be PWM. Remember how we said before that a PWM signal is modulated to create a variable duty cycle waveform? Guess what we use to modulate the clock signal with? The digital audio samples from our WAV file. So what we end up with is a PWM waveform output whose duty cycle is proportional to the PCM audio data in the WAV file. We feed the output into an audio amplifier and hey presto! We hear that digital audio WAV file coming through the speakers.
PWM can create an analogue voltage that’s proportional to its duty cycle.
While we love Arduino this is where we run into its limitations – it only has an 8-bit bus and combined with its limited 16MHz clock speed and our audio code library we only have enough speed to handle WAV files with a 19kHz sample rate and 8-bit depth. That said I’ve worked on our simple audio converter to tweak the encoding so it produces good-sounding files with a better than AM radio frequency bandwidth which is good enough for music and certainly more than enough for digital audiobooks.
Convert any audio file into ‘Auduino’ format
01 Download Auduino
Download the ‘auduino.zip’ file from apcmag.com/arduino.htm and unzip it to the ‘C:Auduino’ folder on your C: drive. Launch the ‘InstallWavConverter.reg’ file. This installs a Shell registry key that adds a new menu entry to Windows Explorer’s context menu. (Open the REG file in Notepad and you can see how it works.) Click the ‘Yes’ button to confirm and then ‘OK’ when it’s completed (‘RemoveWavConverter.reg’ deletes the registry key if you wish).
02 Convert an audio file
Use Windows Explorer to find an audio file you wish to convert right-click the file and select ‘Convert to APC/Auduino format’. You’ll see a Command Prompt screen appear briefly and when it disappears you’ll have a new WAV file in the original file’s location. You can even select multiple files to encode all at once.
Looking for free downloadable digital audiobooks? Try LibriVox and Books Should Be Free. These are usually in MP3 or OGG format with books separated into chapter files. Our encoder can easily turn these into the necessary WAV format.
03 Transfer & play
Copy this file(s) to the root folder of a Class 4 FAT32-formatted SD card up to 8GB and transfer the card to the Auduino player. Files can be up to 2GB. Power up the player and press the button.
Building the Auduino
We’re building our prototype this month on the same breadboard we used for our LED dice and weather station projects as it makes it easier to troubleshoot and program the Arduino. You can see how it goes together from the circuit diagram the overlay diagram and the photos. The SD card module has two rows of pins and each pair is wired together so it can plug straight into the breadboard.
The circuit diagram for our digital audio player.
Voltage Level Translation
If there’s a tricky part of the circuit it’ll be the diodes connecting the Arduino to the SD card module. It may look like the diodes are facing the wrong way but they’re not. We’ve got a small problem in this project that the diodes are helping to fix for us. Basically the Arduino runs on a 5V logic level (that means the digital outputs swing from 0V to 5V) but SD cards only run on 3.3V. If we feed 5V into the data lines of the SD card module we risk blowing up the card.
The diodes therefore act as a voltage level translator. The SD card module has pull-up resistors on three of the four data lines which lightly connect these lines to the supply rail. When the Arduino digital output swings low the diodes are forward-biased by the current through the pull-up resistor and the SD module control line drops low to 0.6V. When the Arduino output rises up to 5V the diode becomes reverse-biased and no current flows from the Arduino to the SD module. The pull-up resistor lifts the data line to the 3.3V supply rail so we get our digital-1 at the required 3.3V instead of the Arduino’s 5V so everyone’s happy. (The SD module has a 3.3V voltage regulator on board that drives the pull-up resistors.)
Electrical engineers would argue that this is a dodgy fix and we should be using a dedicated level translator chip like a 74HC4050 and they’re right. The diode option does work although as we’ve discovered not reliably. We tested it with half a dozen different SD cards and found two of the six worked well one sort of worked and three didn’t work at all. Some SD cards expect to see digital signals that snap between 0V and 5V in no more than five nanoseconds while others are more tolerant and they’re the ones that work.
The layout diagram of our digital audio player using an 840-point breadboard.
Choosing SD cards
The SD card module talks to the Arduino over the SPI (Serial Peripheral Interconnect) bus but SPI is really just a 1-bit economy mode interface that’s easy to implement whereas SD cards normally communicate over a 4-bit wide bus. Combine our low-level translation circuitry with the fact that not all SD cards do SPI well and that unfortunately limits the cards we can use. We recommend Class 2 or Class 4 SD cards that are preferably 8GB or smaller. You can try larger Class 4 cards (we’ve used a 32GB card successfully) although you’ll need to make some changes to our Arduino code: change the
cardType variable from
newCard . Basically the newer or larger the card the slower we need to run the SPI bus so doing this drops it back from 8MHz (half-speed) to 4MHz (quarter-speed). Any slower than 4MHz however and the data rate becomes too slow and you can hear the continual jitter in the sound output. We purchased new 4GB and 8GB Class 4 Verbatim cards. The 4GB card didn’t work but the 8GB card worked perfectly at the 8MHz/half-speed rate.
Our modified SD library still works with all existing Arduino programs (sketches) but adds a new instruction that allows us to adjust the Arduino’s SPI speed and allow more cards to work.
We’ve also come up with a more reliable option which involves ditching the $1.50 SD card reader and replacing it with a $10 Ethernet Shield that includes a microSD card slot. You remove the components connected to pins 10 11 12 13 and change the sketch by setting the
chipSelect variable to 4 (this is marked in the sketch code). You also need to set the
cardType variable to
oldCard . The Ethernet Shield has the proper level translation built in to reliably work with any microSD card. The Shield sits on top of the Arduino and you use the same I/O pins for the switch and audio out.
Solder the stereo socket
Our Auduino player doesn’t have a built-in amplifier yet so we need external speakers and a way of getting our audio signal to them. That’s what the 3.5mm stereo socket is for. We need to solder it up so to do this first grab a couple of Dupont wires. Cut them in half strip the insulation off tin them and solder them to the three tags on the socket. These give us connections to a 3.5mm plug’s tip ring and sleeve (TRS) connections. Given that we’re only using mono audio we feed the audio output to both channels so when you plug in the 3.5mm cable to your stereo amplifier you’ll hear sound coming out of both speakers.
We’ll need the ‘tmrpcm’ and a modified ‘SD’ card library. You’ll find these in the zip file you can download from apcmag.com/arduino.htm (look under the Project 5 heading). Copy the ‘SD’ and ‘tmrpcm’ folders to the ‘libraries’ folder in your Arduino IDE folder (yes overwrite the original ‘SD’ library) and restart the IDE if you’ve had it running already.
The ‘apc_05_audioplayer.ino’ file is our sketch which ties everything together. It boots up the Arduino turns on the SD module checks the card and waits for you to press the button. Press it for less than a second and it’ll load and play the first file. If you press the button again for less than a second it’ll pause playback; pressing it again resumes playback. Press it for more than a second and it’ll automatically skip forward to the next audio track and begin playback. There are no volume controls – you adjust this at your amplified speakers.
Unfortunately the ‘tmrpcm’ library creates a pop whenever a track stops or starts. A low-pass filter will help a little but it’s caused by the PWM signal turning on and off.
The specific parts for this project should cost you less than $40 if you choose the SD card module option. The hardest thing to find will be the SD card module itself – we bought ours from eBay for just US$1.48 (including shipping) from Hong Kong. The rest of the parts can be picked up from your local Jaycar Electronics or most online electronics stores.
A super-cheap SDHC card module for under $1.50 on eBay.
Give it a crack
A digital audio player we can control offers plenty of ideas. Just a few I can think of off the top of my head include a talking robot a voice-warning security system a talking weather station and I’m sure you can come up with a few of your own. By building this project you’ll learn more about digital audio and even be able to incorporate some of the techniques into your own Arduino projects.
Arduino parts list
|Part||Cost per unit||Source|
|Arduino Uno R3||US$14||eBay|
|LC Studio SD card module||US$1.48||eBay|
|Push-button momentary switch||$1.25||Jaycar|
|1N4148 signal diode||$0.40||Jaycar|
|5mm red LED||$0.25||Jaycar|
|100uF/16VW electrolytic capacitor||$0.36||Jaycar|
|0.1uF MKT capacitor||$0.40||Jaycar|
|0.0015uF MKT capacitor||$0.35||Jaycar|
|1kÎ©/0.25W metal-film resistor||$0.46||Jaycar|
|4.7kÎ©/0.25W metal-film resistor||$0.46||Jaycar|
|10kÎ©/0.25W metal-film resistor||$0.46||Jaycar|
|47kÎ©/0.25W metal-film resistor||$0.46||Jaycar|
|4GB Class 4 Verbatim SDHC card||$6.75||Various retailers (including Officeworks)|
|3.5mm stereo socket||$1.35||Jaycar|
|3.5mm male-to-male cable||$4.95||Jaycar|
|Ethernet Shield (alternative)||US$9.62||eBay|