Sparkfun MP3 Shield Arduino Library

Posted in Arduino Libraries by Bill
28 Jan 2012

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.
  • 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.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Share

Trackbacks / Pingbacks

  1. Getting Started with the LilyPad MP3 Player

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
  1. 590 Comments.

    • jbarthNo Gravatar says:

      I posted to the forum regarding a couple of ideas I have and I’d really appreciate any input.

      http://www.billporter.info/forum/topic/2-ideas-gettrackinfo-and-httpother-stream-sources/

    • Michael P. FlagaNo Gravatar says:

      Not sure who was asking for this. I can not find the exact thread.
      I have just added to the pre-release version the ability to start initial or resuming play from an offset, along with a pauseMusic().

      MP3player.resumeMusic(2000); // resumes from approx 2 seconds from begin.

      or

      MP3player.playMP3(“track001.mp3”, 2000); // starts from approx 2 seconds from begin.

      the 2000 is optional.

      In both cases it approximate and for the playMP3 it will only work on MP3 files and not for others. as MP3 is the only header decoded before actual play.

    • jonnyNo Gravatar says:

      Hi..
      i have downloaded SdFat library but there is no Sd2PinMap.h file present in library.
      Using arduino uno,arduino 1.0.2,using mp3file of 192 bitrate.
      While playing given code i got this kind of messages in serialmonitor…
      MP3 Testing
      Error: Card init
      Error: Volume ini
      Error: Opening root
      but there is no sound
      please help me out
      thanking you in anticipation

    • Michael P. FlagaNo Gravatar says:

      The serial prints do not correlate to 1.0.2. Sounds like you have attempted your own version, different then the example.

      Sd2PinMap.h is piece of the native SD library to the Arduino’s IDE. So it feels like your environment is not set up correctly. Also I think I have seen that print error prints about Sd2PinMap when some of the SdFatLib’s includes are missing.

    • jonnyNo Gravatar says:

      Hi..
      Thank you for your reply…i changed that in native SD library now i am getting in my serialmonitor is
      MP3 Testing
      Error: Card init
      Error: Volume ini
      Error: Opening root
      SCI_Mode (0x4800) = 0x0
      SCI_Status (0x48) = 0x0
      VS Version (VS1053 is 4) = 0
      SCI_ClockF = 0x0
      SCI_ClockF = 0x0
      Failed to open track001.mp3
      Failed to open track002.mp3
      .. same thing repeated up to 100..
      Failed to open track100.mp3
      Whoa there cowboy!
      I am trying with the Sparkfun MP3 samples with name track001.mp3 and track002.mp3
      Thanking you in anticipation

    • Michael P. FlagaNo Gravatar says:

      New release of 1.02.00 is here with new features. It rolls up many of the pre-release features and fixes, many of you have asked for. Such as :
      1. Better handling of the playing state.
      2. VU meter
      3. Differential Speaker Feature.
      4. pauseMusic() and resumeMusic.
      5. WebPlayer.ino example
      6. sdfatlib20121219

      Points worth noting.
      With sdfatlib20121219 sd.begin is now in the INO.
      example:

      SdFat sd; //newly required
      SFEMP3Shield MP3player;
      ...
      if(!sd.begin(SD_SEL, SPI_HALF_SPEED)) sd.initErrorHalt(); //newly required
      if(!sd.chdir("/")) sd.errorHalt("sd.chdir"); //best practice
      result = MP3player.begin();

      There is a run time error print to detect this. It can be removed to save space.
      This provide simpler handling of the SD card. Easier to change directories and such. The WebPlayer.ino takes advantage of some these abilities.

      The WebPlayer.ino requires the
      #define USE_MP3_REFILL_MEANS USE_MP3_Polled
      in the SFEMP3ShieldConfig.h, and remember to set the IP to your subnet.
      And yes, there is a skip when a file starts playing, when you use a browser, but if you use wget it does not. The little AVR really can not read both the MP3 and the WebPage simulaneously.
      And I am not sure why I can not use interrupts, something in the Ethernet Library.
      I welcome any solutions.

    • ArcadeNo Gravatar says:

      Great library, was wondering if you ever figured out how to control the treble and bass to make tuners out of them. If so and you can send me an example coding for them both or point me in some direction it would be greatly appreciated!!

    • Angel PradoNo Gravatar says:

      Please help! 🙁
      I have already made this shield work on my Arduino UNO R3 by serial communication, now I see that pins 10, 11, 12, 13 doesn’t have marks on them, is it possible to use a pushbutton to play an mp3 file by reading the digital state of any of those unmarked pins?

    • Angel PradoNo Gravatar says:

      Please help! 🙁
      I have already made this shield work on my Arduino UNO R3 by serial communication, now I see that pins 10, 11, 12, 13 doesn’t have any marks on them, is it possible to use a pushbutton to play an mp3 file by reading the digital state of any of those unmarked pins?

    • gallegojmNo Gravatar says:

      I plan to make a web radio listener.
      For that project I would use an Arduino Due, an Arduino Ethernet shield and a SparkFun MP3 Player.
      The first step was to put to work the MP3 Player with the Arduino Due.
      I have to redirect SPI pins (only available on SPI connectors from Arduino Due) to pins 11, 12 and 13 of MP3 Player. For that I solder three wire on the Arduino Ethernet shield and I bent the connectors corresponding to pins 11-13. So the Arduino Ethernet shield act as an adapter between Arduino Due and MP3 Player
      The second step was to modify your great library adapting it to the peculiarities of SAM3X8E processor.
      It is working fine. I test it with MP3Shield_Library_Demo sketch, reproducing perfectly mp3 files up to 320 kpbs
      So I can begin the next step: put to work the ethernet module
      If you are interested, I can send you the modified library, so may be you can include the modifications. Just give me an e-mail where to send it.
      I hope you would understand my bad english …

    • KevinNo Gravatar says:

      I’m having quite a bit of trouble getting started. I tried running the example codes, and it keeps erroring out.

      It starts with:

      MP3Shield_Library_Demo:42: error: ‘SdFat’ does not name a type
      MP3Shield_Library_Demo:49: error: ‘SFEMP3Shield’ does not name a type

      and continues to inform me nothing is declared.

      Help please?

    • Michael P. FlagaNo Gravatar says:

      I have not experienced this exact symptom. It seems odd for the Example. Which should work out of the box. The Error indicates the types being instanced: SdFat and SFEMP3Shield, are not yet defined. Where their should be before them, define them. Which are done correctly in the Examples.

      I suspect somehow the libraries are not properly installed. They have to be manually installed as they are custom libraries. http://arduino.cc/en/Guide/Libraries

    • […] the audio decoding chip. Your code can use SPI between data transfers if you’re careful; see Bill Porter’s MP3 Library documentation for instructions on how to do […]

    • KevinNo Gravatar says:

      My MP3 Shield seems to be working intermittently…. namely only the first time I open code on my computer and upload it. If I make small modifications, no sound comes out. The code doesn’t produce an error, but no sound.

      What PinOuts on the MP3 shield can I NOT use? I’m using tri color LED’s on Pins 5-13. They seem to work fine by themselves, but when loaded with the MP3 libraries, things get… weird.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.