The VS1053 Shield is the easiest way to turn an Arduino Uno microcontroller board into a multi-codec digital audio player.
You’ll find it on eBay for as little as $12.50 including shipping. It can record audio to OGG format and plays a range of codecs, the easiest to code your Arduino device for being MP3.
In our last article, we made the simplest MP3 player possible – plug in the power and it plays whatever MP3 files it finds on the card.
Here we’ll build on that first version, by adding Volume Up and Volume Down controls, Previous Track and Next Track buttons, plus a combo Play/Pause button – and the code to make them work.
Get the code!
Download the code for this project from our website.
Unzip it, go into the ‘Sparkfun-MP3’ folder, copy the ‘SdFat’ and ‘SFEMP3Shield’ subfolders into the /libraries subfolder of your Arduino IDE install.
Restart the IDE if it’s already running. Load up the AB12_audioplayer.ino code, flash it to your Arduino board, remove the power, install the VS1053 shield with MP3 tracks on a MicroSD card, build up the prototype board, plug in your headphones, plug the USB power pack in and you should be away.
Don’t have the Arduino IDE? Get the latest version here.
Making the stack
Put simply, you plug the VS1053 Shield into the Arduino and the Prototype Shield into the VS1053 Shield. Power automatically runs to each board, so you only need to plug in a USB cable and all three boards are active.
We’ve installed five small ‘momentary-on’ pushbutton switches on the breadboard, arrange as a row of three and column of two.
The column is the audio level/volume buttons, while the row is Previous Track (left), Play/Pause (middle) and Next Track (right).
These buttons are called ‘momentary-on’ because that’s what they do – left alone, the switch is in the ‘off’ (no connection between the two pins) position, press down and the switch is on (contact), but only while it’s pressed. Let go and it goes back to the ‘off’ position.
Each switch connects between the ground plane (GND) and one of the analog inputs, A0 through A4. We’re also using the built-in ‘pull-up resistor’ inside each of those inputs to enable us to track when each button is pressed.
In the ‘off’ position, each input is pulled ‘high’ by the internal resistor to the 5V supply rail, a digital ‘1’, indicating the button isn’t being pressed. But as soon as it is pressed, the button pulls the input to GND, a digital ‘0’.
And that’s about it – by plugging the ‘stack’ together, you create the rest of the circuit.
We’ve used Dupont wires to make the switch connections – again, 65 of these can be had on eBay for a couple of dollars.
If you could zoom in and see what happens over the first half-second or so, the switch contact ‘bounces’ into position – and that’s a problem.
If you’re waiting to detect a press on that button, you’re looking for a change of level from ‘1’ to ‘0’. But if you’re getting ‘100010101011100’ in the first 50-milliseconds, you’ve got multiple triggers, not just the one.
In electronics, this is solved with a ‘debounce circuit’, essentially a resistor-capacitor filter on the switch feeding a logic gate called a ‘Schmitt Trigger’, but here, we’re implementing an extremely crude debouncer in code – a simple time delay.
As soon as we detect a change on one of the input lines, we set off a 300-millisecond time delay, which is enough to allow these switches to settle into their steady-state position. It’s also easy to implement because it’s just one line of code:
It does mean we can only detect one change every 300-milliseconds, but that’s enough here. We’ve tested the code (very enjoyably, I might add) and it works a treat.
You still need to have your MP3 files in the format ‘track001.mp3’, ‘track002.mp3’, track003.mp3’ and so on. This ‘8.3’ filename limitation comes from using the ‘playTrack(int)’ command that takes just a single 8-bit integer – file-renaming apps can sort this out for you pretty easily.
This method does limit you to 200 tracks, but other than that, you can have full 48kHz sampling up to 16-bit stereo at 320Kbps bit rate.
Why not standard Windows long filenames? Well, with only 2KB of RAM to play with, there’s only so much an Arduino Uno microcontroller can cope with.
Still, when creating a blank Word 2010 .docx document requires 13KB, the Arduino isn’t doing too badly here with just 2KB.
Power source & VS1053 limitations
Lastly, the VLSI VS1053 audio codec chip that makes this project possible was originally designed for stand-alone battery-powered (3.3VDC) use, so it implements a separate audio ground that’s not at normal ground voltage (0V). Instead, it sits at 1.25VDC.
If you decide to connect this up using a 3.5mm cable to a powered speaker system, you’ll create what’s called a ‘ground loop’, which is where current will automatically flow from that 1.25VDC source into the ground plane.
That won’t do the VS1053 chip any good – in fact, it’ll like blow up that part of the circuit. The solution is to stick with headphones, or if you’re clever, you can implement the ‘simple line-out connection’ circuit, which solves the problem.
Finally, if you’re listening to this MP3 player with headphones, we recommend you power it with a USB battery power pack that delivers 5VDC to a Type-A USB port from a Lithium-ion battery or AA-size cells.
Avoid powering it with a cheap USB charge adapter – if something fails in one of those things, you could have 240VAC power disappear up your headphone cable. Don’t risk it.