The Sparkfun MP3 Player Shield for Arduino is a inexpensive and easy way to add MP3 playback capability to your Arduino project. But it was lacking an easy to use Arduino Library to go along, so I fixed that. Introducing the SFEMP3Shield library just for this shield. Now playing an MP3 files is as easy as MP3player.playTrack(5); and all the work is done behind the scenes.
Most of this library comes from the existing example code, with the major new feature of being interrupt driven. So no need to worry about feeding the MP3 chip, whenever it’s ready for more the library will be ready to feed it. This allows the Arduino to perform other tasks while music is playing. The most basic use of the library is as follows:
#include <SPI.h> #include <SdFat.h> #include <SdFatUtil.h> #include <SFEMP3Shield.h> SdFat sd; SFEMP3Shield MP3player; void setup() { Serial.begin(9600); //start the shield sd.begin(SD_SEL, SPI_HALF_SPEED); MP3player.begin(); //start playing track 1 MP3player.playTrack(1); } //do something else now void loop() { Serial.println("I'm bored!"); delay(2000); }
That’s all it takes to get your Arduino to play an MP3 file using the shield. How easy is that?
The library does have more functions and even error reporting. All of which can be found in the ReadMe file or in the Example Sketch included with the Library.
Source Code available on GitHub project pages: Sparkfun MP3 Player Shield Arduino Library
Or Direct Download here.
Using the SPI bus for something else as well?
I added some functions to make sure there will be no data collisions on the SPI bus caused by the MP3 decoder asking for more data at the wrong time. You need to wrap any SPI code you add to your project with these two functions. Here’s an example from my project that also has a shift register on the SPI bus:
//disable interrupts to avoid collisions on the SPI bus between this code //and the MP3player library MP3player.pauseDataStream(); //shift data tempIO = SPI.transfer(HIBYTE(output)); tempIO<<8; tempIO = SPI.transfer(LOBYTE(output)); //latch output on shift registers digitalWrite(OUTLATCH,LOW); digitalWrite(OUTLATCH,HIGH); digitalWrite(OUTLATCH,LOW); //enable interrupts MP3player.resumeDataStream();
But you can’t stop the data stream to the MP3 Shield for too long before it runs out of data so be careful and try not to do too much stuff in between the functions.
Wanna be your own DJ?
New features! Requested in the comments below, there are now functions to skip around a playing track. You could fast forward, rewind, create loops, etc.
Here’s an example that will just open a file, jump to the 30 second mark (measured in milliseconds, 30 seconds = 30000 ms), and loop the song back every 750 ms:
MP3player.playTrack(1); for(;;) { MP3player.skipTo(30000); delay(750); }
If you want to know where you are in the current playback, do this:
time = MP3player.currentPosition(); Serial.println(time);
Both functions are not super accurate and depend on the bitrate of the file. The library should auto-detect the bitrate of the file but may fail on some MP3 files. If that happens, you have to set the bitrate manually like this:
MP3player.playTrack(1); MP3player.setBitRate(192);
I can already see the cool DIY DJ equipment that could be made with this. Let me know if you have problems, and comment below if you ever make something cool with the library.
Troubleshooting
Pulled from the GitHub Project Page
The below is a list of basic questions to ask when attempting to determine the problem.
- Did it initially PRINT the available RAM and Full Help Menu?
- The MP3Shield_Library_Demo.ino example should initially provide a opening print indicating the amount of available SRAM and full menu help. If you don’t see this the problem is between your Target and IDE. And likely not this library
- Is Serial Monitor set to the correct tty or com port and 115200 baud rate? Did you change the baud rate?
- Reset the Arduino after Serial Monitor is open or send any key. It may have printed these prior to the Serial Monitor being started.
- WHAT is the Error reported?
- Is the Error Code is indicating a file problem.
- Are the filenames 8.3 format? See below warning.
- See also Error Codes
- Did the SdCard LOAD?
- Try reseating your SdCard.
- Is it FAT(FAT16 or FAT32)?
- If the Error Code is indicating problems with the INIT, VOLUME or Track not being successful. It is recommend to use SdFat Example Library’s QuickStart.ino as to see if it can access the card. Additionaly, SdInfo.ino may indicate if it can mount the card. Which may then need to formatted in FAT16 or FAT32. Where SdFormatter.ino can do this for you.
- Are the needed files on the root?
- Remember to put patch and audio track files on the SdCard after formatting.
- Are the filenames 8.3 format? See below warning.
"Error code: 1 when \b trying to play track"
- See the above Limitations. about Non-Blocking.
- Remember to check your audio cables and volume.
"Warning: patch file not found, skipping."
- See the Plug Ins and Patches
- Why do I only hear1 second of music, or less?
- This symptom is typical of the interrupt not triggering the SFEMP3Shield::refill(). I bet repeatidly sendnig a track number will advance the play about one second at a time, then stop.
- What board is it? Check Hardware Limitations. about Interrupts.
- Are you trying the SFE provided test files ? Or some homemade mp3 files? The SFE test files are nice as they are Immediately LOUD.
- Interrupt problems may cause mp3 files that have a quiet lead in (or ramp up of volume) to be falsely diagnosed as not playing at all. Where the first 1 second may not be loud enough to be heard.
Free RAM = 1090 Should be a base line of 1094
- As a courtesy and good practice the provided example MP3Shield_Library_Demo.ino prints out the available remaining RAM, not statically allocated. And the actual available amount may depend on specific processor, IDE version, libraries and or other factors. A Uno built with IDE version 1.0.2 should have approximately 1094 bytes available from the example as is. And a Mega using a 2560 may show 6713, as it has more RAM.
Note
- This library makes extensive use of SdFat Library as to retrieve the stream of audio data from the SdCard. Notably this is where most failures occur. Where some SdCard types and manufacturers are not supported by SdFat. Though SdFat Lib is at this time, supporting most known cards.
Warning
- SdFatLib only supports 8.3 filenames. Long file names will not work. Use the
'd'
menu command to display directory contents of the SdCard."longfilename.mp3"
will be converted to"longfi~1.mp3"
. Where one can not predict the value of the 1. The DOS command of"dir \c /x"
will list a cross reference, so that you know exactly, what is what.
Still Need Help?
Use the support forum to look for a solution or ask for help. Please don’t use the comments below to ask for help.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Warning: Use of undefined constant single - assumed 'single' (this will throw an Error in a future version of PHP) in /homepages/46/d285670699/htdocs/bill/wp-content/themes/wordpress_survive/single.php on line 63
Trackbacks / Pingbacks
Warning: count(): Parameter must be an array or an object that implements Countable in /homepages/46/d285670699/htdocs/bill/wp-includes/comment.php on line 879
590 Comments.
Thank you.
I’m just tinkering, built a portable mp3 loudspeaker consisting of an Arduino Mega, Sparkfun MP3 Shield and STA540 Audio Amp kit. I really appreciate the ease of use of your library. I of course want to take it a step further and I’m a networking guy.
So I want to pick your brain, there is a project-
http://maniacbug.wordpress.com/2011/12/30/arduino-on-ice-internet-radio-via-shoutcast/
It uses a VS1053 as well to fetch an internet radio stream and it feeds the encoded stream directly to the chip.
I’ve poked around a bit between the Shield Library and the VS1053 library from the mentioned project. I am not confident I have what it takes but, I’m hoping you might take interest in adding a feature to allow the handoff of a data stream such as HTTP streaming radio rather than just file.
Hey Josh,
I wrote this library for that particular shield. To add features like HTTP connection streaming goes outside its original scope. But it seems like that guy has already done exactly what you want, so what trouble are you having?
And yes, I have wanted to try to stream audio in a setup like his, but don’t have the time to play with that right now.
That might come off sounding harsh. I don’t mean it to be. Yes, I’d like to try streaming some day. But I’m too busy at the moment to play with it.
Oh I understand, it came off just fine. I can sound a bit rough around the edges at times too. No harm no foul.
Maybe I should elaborate. I don’t want you to stray and do anything not shield oriented with the library.
My point is though, that this shield (and especially the earlier ones without SD) are capable of playing from sources other than from SD. Currently the “refill()” function is pretty much bound to fetch from SD.
If there were a way to manipulate the functionality when you initialize the shield that would be awesome, ideally you should be able to create a single instance of the MP3Player and switch it’s source on the fly. Take for example a networked PA system, it should be able to play ambient audio from a local SD and then at any point cut out for an over the air announcement.
I will certainly help with what I can, but honestly I am an amateur when it comes to code….it takes a bunch of time pondering for me to come up with a bit of code with elegance and perfect functionality.
….sorry gotta roll, work calls.
It would not be too hard to implement, just have a function that passes in 32 bytes of data to send to the shield. If I get time I’ll consider adding it.
Hi Bill
Your library looks interesting. Is there a possibility to use the encoding-capabilities of the chip as well?
Thank you very much,
Dani
Daniel,
The Sparkfun shield doesn’t have the hardware for encoding audio, but since it seems there is a lot of people asking for features not related to the shield I might consider adding more functions. Can’t give you a timeline though, I’m rather busy at the moment.
Hi Bill
Thanks for you quick answer, according to the datasheet of the VS1053b (http://www.sparkfun.com/datasheets/Components/SMD/vs1053.pdf), there should be the ability of encoding «Ogg Vorbis audio and IMA ADPCM from mic/line (stereo)».
Thanks for having another look at it.
Dani
BTW: Using your library, is it also possible to play ordinary (uncompressed) WAV-files?
Yes the chip supports it, but Sparkfun left those pins unconnected so there’s no way to use the shield for recording.
Not sure about WAV, I’ll have to look into it.
That’s a shame they left them unconnected 🙁 Thanks for having a good look at it!
Hi!
Thanks for this awesome library.
Somehow I can’t get it to work!
No clue why, the simple example code seems to run fine, according to print. Reformatted the card, tried a couple of different mp3 files, (all 192 kbps) Even tried another board.
Any tips on where I should start to look for bugs / faults?
Thanks ‘n cheers!
Do you get an error message in the serial monitor? What does it say?
wow, ur fast!
nope, only prints the “i’m bored”
The only feedback I get is the funky stuff during upload…
O, I don’t mean using the sketch you see on this page. Use the example sketch in the library and see what it says.
i meant, funky sounds
How silly of me, I’ve only looked at the SdFat examples.
It gives me:
Error code: 2 when trying to play track
So, it can’t find the file right?
Yup, the SDFat library is giving the error. Make sure the MP3 file name is exactly “track001.mp3”. Make sure windows isn’t hiding the extension so really you are making the file name “track001.mp3.mp3”. Download THIS and put those MP3s (without editing their names) on the SD card and see what you get.
Read through this a bit and see if it helps: http://www.sparkfun.com/tutorials/295
ouch, I’m having a hard time to admit this: the track was named track01.mp3
jeez…what a moron I am.
thanks bigtime for helping me out!
I’ll buy you a beer via paypal!
cheers!
Haha, it happens. And thanks, I could really use a beer right now too. Rough week at work… :-/
Cheers!

Want to use the code for another music shield. The fez music shield (www.ghielectronics.com/catalog/product/289) also uses the VS1053 architecture. would at least some of the code work?
Oh, that’s interesting, since that board seems to have connected the mic-IN-pins! Dani
Hmm, This board is going to be trouble. They connected the chip’s DREQ line to digital pin 4, which means using external interrupts to feed in music data won’t work. The end user would have to poll the pin constantly. Or I could hijack an internal interrupt to poll the pin so the end user does’t have to worry about it. Other then that it all you would have to do is change the pin definitions. I’m interested in tackling this problem so I may release an official update that would run this.
In the mean time, you could jumper Digital pin 4 and 2 and change (in SFEMP3Shield.h )
#define MP3_XCS 6
#define MP3_XDCS 7
to
#define MP3_XCS A5
#define MP3_XDCS A4
And change #define SD_SEL 9 to whatever pin your SD card CS pin is connected to and the library should work.
It’s also a shame they didn’t add an SD card slot. That would have made this shield more capable then the Sparkfun version.
They have an SD card slot on their mainboard, thats probably why they didn’t include one in the shield.
Hi there and thanks for this amazing library – made the job of integrating sound effects into my project a breeze!
I do run into a bit of an issue though, and I guess this might not be strictly due to your library, but that’s at least where I get the symptoms.
I’m trying to play a nearly 3 minute long (192bps) MP3, which I restart if finished, using : if (!MP3player.isPlaying()) playSound(“Alive.mp3”); in the loop().
Trouble is, it plays fine, but the playSound function never returns, meaning the program hangs here, playing the song to the end and then does nothing.
My setup is a bit weird – it’s a Peggy 2.0 board (Evil Mad Scientist) that shares power with a Diavolino (Duemilanove 328 clone) with the MP3 shield attached. The Peggy 2.0 and Diavolino are connected to the same 5V power and talks to each other using I2C.
Top-off-my-head ideas: RAM? (I don’t quite know how much extra your library eats while playing), I2C conflict? (unlikely I guess), voltage? (unlikely, as the 5V wallwart can do 1500mA). At my wits’ end here. Any ideas?
Hmm, that’s odd. Can you put print statements in playMP3() function in the .cpp file of the library so we can find where in the function it is hanging? For example, add to the end of the function:
Serial.print(“0”);
//gotta start feeding that hungry mp3 chip
refill();
Serial.print(“1”);
//attach refill interrupt off DREQ line, pin 2
attachInterrupt(0, refill, RISING);
Serial.print(“2”);
return 0;
Save the file and then re-upload and watch the output on the serial monitor so we can see if it’s one of those calls that is locking up the main thread.
Errr, I did as you suggested and now I think I’m slightly losing my mind 😉
After end of track the system hangs, and upon a reset the MP3 Player Shield refuses to initialize. It only manages to print half the Serial.printl() that reports errors before coming to a halt, so I cannot see the error code (it gets to “Err” before hanging). A couple of seconds’ power off seems to clear it, but all serial communication stops after the MP3 Shield is activated. It plays the song to completion, but the animation I have running on the Peggy 2.0 display to check that we’re alive (streamed from the Diavolino with the MP3 shield) hangs after a few seconds, and as serial dies when initializing the shield, I get no status messages. It seems almost as if playing the MP3 file sucks up all the RAM, but I’m too green on Arduino to trust my own judgement here (as a UNIX guy, that’d be my guess, but I think I’m looking at it from the wrong angle).
I suspect that I am possibly wasting your time, as it might be that there are other issues with code or hardware, and the MP3 library is not at fault. I guess my best option trying to debug this would be to try to strip out parts of the code to I get down to something that works and rebuild until it doesn’t. That would at least help if it really is RAM that’s the issue.
I’ve tried three different suggestions for checking free RAM, but it seems they all give highly diverging and erratic results, so I think I’ll just strip and then start adding code until it acts up again.
thanks bill again for that smooth working library. one noob question though: is it possible to still use one or both of the digital pin interrupts? i am triggering the mp3 tracks via a hall sensor and use a push button to stop playing, which both would be better as interrupts i suppose. however, the shield itself seems to already use pin 2 and 3. do you have any ideas how to work around that?
You can’t use pin 2, as that needs to be exclusively used for the shield. But if you aren’t using MIDI (my guess is no if you are using my library) then you can cut the trace in-between the two gold pads on the shield next to pin 3 so you can use pin 3 for something else.
But it looks like you already finished your project, looks good!
yeah thought so… won’t do the cutting as the code is running without interrupt for now. i wish though arduino would have more interrupt pins… thanks for your reply.
[…] awesome work of bill porter and bill greimann I can use their smooth libraries for this project: sparkfun mp3 player shield library and sdfat library. apart from that, the coding is pretty straight forward. whenever the magnet is […]
Hi ! First of all, thanks a lot for your library. As soon as I can get my mp3 shield to work, it will make my life infinitely more happy !!
So, I have downloaded the libraries, installed them inside my Arduino app (osx -> content:ressources/java/libraries/).
The MP3_Shield_Library_Demo compile well but then return a” Error code: 1 when trying to start MP3 player” on the serial monitor.
Any idea that can cause such an error ?
Does the “Sd2PinMap.h” file have to be modified ?
If you read the ‘ReadME.txt’ file you see that error 1 is “SD Card Init Failure” which is an error generated by the SDFat library. I can’t help you much with that other then to follow the Sparkfun guide for formatting the SD card correctly.
You could also run the “SdInfo” example in the SDFat library to see what error it gives when it tries accessing the card. You have to change
const uint8_t SdChipSelect = SS_PIN;
to
const uint8_t SdChipSelect = 9;
in that example sketch. Let me know what it says and maybe we can figure this out. Also, did you try another SD card?
To complete my previous message :
MP3_Shield_Example.pde -> gives nothing but silence
MP3_Player_Example.pde –>
MP3 Testing
Error: Card init
Error: Volume ini
Error: Opening root
The SD card is FAT16
Any idea ? Thanks again 🙂
[…] slot, and audio jack for the powered speakers. [Sebastian] grabbed a copy of [Bill Porter's] mp3 shield library to get the project up and running […]