New and Improved DFPlayer Mini Library!!

I just want to point out that I tested the library as it stands today and it currently plays/loops file (etc) exactly as it should.

If anyone can't get their sketches to work in the future, please post:

  • Your entire sketch
  • Full wiring schematic (an additional set of pictures of your wiring is also a plus)
  • File contents of your SD card

Update

I did some work upgrading the library - now all DFPlayerMini commands and queries are supported by the library!

I literally just tagged the new release, so I expect the changes to be reflected in the IDE's libraries manager in a few hours. Either way, you can always get the latest version from the GitHub repo.

Here's the API listing for the library:

bool begin(Stream& stream);

void playNext();
void playPrevious();
void play(uint16_t trackNum);
void incVolume();
void decVolume();
void volume(uint8_t volume);
void EQSelect(uint8_t setting);
void loop(uint16_t trackNum);
void playbackSource(uint8_t source);
void standbyMode();
void normalMode();
void reset();
void resume();
void pause();
void playFolder(uint8_t folderNum, uint8_t trackNum);
void volumeAdjustSet(uint8_t gain);
void startRepeatPlay();
void stopRepeatPlay();
void playFromMP3Folder(uint16_t trackNum);
void repeatFolder(uint16_t folder);
void randomAll();
void startRepeat();
void stopRepeat();
void startDAC();
void stopDAC();
void sleep();
void wakeUp();

bool isPlaying();
int16_t currentVolume();
int16_t currentEQ();
int16_t currentMode();
int16_t currentVersion();
int16_t numUsbTracks();
int16_t numSdTracks();
int16_t numFlashTracks();
int16_t currentUsbTrack();
int16_t currentSdTrack();
int16_t currentFlashTrack();
int16_t numTracksInFolder(uint8_t folder);
int16_t numFolders();

void findChecksum(stack *_stack);
void sendData();
void flush();
int16_t query(uint8_t cmd, uint8_t msb=0, uint8_t lsb=0);
bool getStatus(uint8_t cmd);
bool parseFeedback();
bool timeout();

void printStack(stack _stack);

Please let me know if you have any problems or run into any bugs!

Also, if you want to send custom packets or parse response packets (from the DFPlayer) if your sketch, you can use the following structs; sendStack and recStack:

struct stack {
 uint8_t start_byte;
 uint8_t version;
 uint8_t length;
 uint8_t commandValue;
 uint8_t feedbackValue;
 uint8_t paramMSB;
 uint8_t paramLSB;
 uint8_t checksumMSB;
 uint8_t checksumLSB;
 uint8_t end_byte;
 } sendStack, recStack;

Each member of the structs can be accessed directly in your sketch. Also, you can pass a stack struct pointer to

void findChecksum(stack *_stack);

to automatically find and insert the correct checksum into your stack. To automatically send the contents of sendStack to the DFPlayer to make a command or query, simply call

void sendData();

. When parsing a response to the recStack struct, just call

bool parseFeedback();

and the DFPlayer's response will automatically load into recStack. Your sketch can then access each member of recStack directly for processing.

To print the contents of any stack, call

void printStack(stack _stack);

Hello I'm new to the DF player module, I come from the Adafruit Sound FX platform.

Anyway your library is simple and lightweight, which means it's great for what I need.

For some reason though I am unable to use the myMP3.loop(x); command.

This is the code I have:

#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>

SoftwareSerial mySerial(3, 2); // RX, TX
DFPlayerMini_Fast myMP3;

void setup()
{
  Serial.begin(115200);
  mySerial.begin(9600);

  myMP3.begin(mySerial);
  
  Serial.println("Setting volume to max");
  myMP3.volume(20);
  delay(20);
  /*
  Serial.println("Playing track 1 for 5 sec");
  myMP3.loop(1);
  delay(20);
  Serial.println(myMP3.currentSdTrack());
  delay(5000);
  Serial.println("Sleeping for 5 sec");
  myMP3.sleep();
  delay(5000);

  Serial.println("Waking up");
  myMP3.wakeUp();
  delay(200);
  Serial.println("Looping track 1");
  myMP3.loop(2);
  Serial.println(myMP3.currentSdTrack());
  */
  //myMP3.volume(30);
  //delay(50);
 // myMP3.loop(0);
}

void loop()
{
  myMP3.loop(1);
  delay(5000);
  Serial.println(myMP3.currentSdTrack());
  delay(1000);
  myMP3.play(1);
  Serial.println(myMP3.currentSdTrack());
  delay(1000);
  myMP3.loop(1);
  Serial.println(myMP3.currentSdTrack());
  delay(600000);

}

The serial results are "0, 1, -1" Definitely wasn't expecting to return two different values after the same loop command. Maybe I'm doing it wrong.

The card is freshly formatted with only one audio file copied. It plays for the second that .play(1) runs.

Power_Broker:
I just want to point out that I tested the library as it stands today and it currently plays/loops file (etc) exactly as it should.

If anyone can't get their sketches to work in the future, please post:

  • Your entire sketch
  • Full wiring schematic (an additional set of pictures of your wiring is also a plus)
    - File contents of your SD card

What exactly does the content on the SD card look like? Do you have all of your files in a folder named "mp3"?

Also, if you get a -1 response from a query, it means the DFplayer timed-out. Otherwise, the response is what the DFplayer reported (response type varies with query - obviously)

Hi, i want check current volume level.
I use currentVolume function into void Loop section for printing volume value but playng is slowly. Anyone have the same problem?

Another question, i use isPlaying function for "pause and resume" with one button.
When i click button for pause, i not have a fast response, resume function it's ok.
If i connect arduino in usb port and i open serial monitor for checking "isPlayng status" i had 0 and 1 result in alternate mode.

nokiandrea:
Hi, i want check current volume level.
I use currentVolume function into void Loop section for printing volume value but playng is slowly. Anyone have the same problem?

Please post the following:

  • Your entire sketch
  • Full wiring schematic (an additional set of pictures of your wiring is also a plus)
  • File contents (including file paths) of your SD card

Did you read the library's readme and DFPlayer Wiki?

I'm transitioning over to this DFplayer library and I have a quick question. How do you stop playing a track? .stop doesn't appear to be supported and I didn't see anything similar on GitHub.

exit status 1
'class DFPlayerMini_Fast' has no member named 'stop'; did you mean 'loop'?

The library's readme on the repo page shows the entire API listing. Here it is for quick reference:

bool begin(Stream& stream);

void playNext();
void playPrevious();
void play(uint16_t trackNum);
void playFromMP3Folder(uint16_t trackNum);
void playAdvertisement(uint16_t trackNum);
void incVolume();
void decVolume();
void volume(uint8_t volume);
void EQSelect(uint8_t setting);
void loop(uint16_t trackNum);
void playbackSource(uint8_t source);
void standbyMode();
void normalMode();
void reset();
void resume();
void pause();
void playFolder(uint8_t folderNum, uint8_t trackNum);
void volumeAdjustSet(uint8_t gain);
void startRepeatPlay();
void stopRepeatPlay();
void repeatFolder(uint16_t folder);
void randomAll();
void startRepeat();
void stopRepeat();
void startDAC();
void stopDAC();
void sleep();
void wakeUp();

bool isPlaying();
int16_t currentVolume();
int16_t currentEQ();
int16_t currentMode();
int16_t currentVersion();
int16_t numUsbTracks();
int16_t numSdTracks();
int16_t numFlashTracks();
int16_t currentUsbTrack();
int16_t currentSdTrack();
int16_t currentFlashTrack();
int16_t numTracksInFolder(uint8_t folder);
int16_t numFolders();

void findChecksum(stack *_stack);
void sendData();
void flush();
int16_t query(uint8_t cmd, uint8_t msb=0, uint8_t lsb=0);
bool getStatus(uint8_t cmd);
bool parseFeedback();
bool timeout();

void printStack(stack _stack);

To answer your question, you can use 'pause()'.

Power_Broker:
Update

I did some work upgrading the library - now all DFPlayerMini commands and queries are supported by the library!

Sorry for the noob question, I read through the thread first and saw this and assumed .stop was included. I just figured that .pause was fundamentally different than .stop, but after thinking about it more it probably has the same result. Thanks for the response!

Added the ability to stop an "advertisement" in release 1.1.3.

Power_Broker:
Added the ability to stop an "advertisement" in release 1.1.3.

Thank You!

Hi, Many thanks for this, I have downloaded and it works great running 3 * MP3 players from an Uno on my test bench.

My final application is a model railway where various sensors trigger sounds at differnt parts of the layout. I plan to have this master Uno linked to three others that monitor various sensors. Using I2C network, I want them to pass commands to the master to play sounds on one of three MP3 players lnked to speakers in different locations.

A couple of questions if I may.....

  1. I'd like to pass the track number to play as a variable. If I create an variable "uint16_t tracknum(1);" and use that on the play "myMP31.play(tracknum);" is that ok? I think it works, but need to reformat & reload the sd card to be sure of the file sequence.

  2. Is it possible for the MP3 player "myMP31" to be a variable also? If so, how please? This would mean I can avoid having the MP3 calls three times in the sketch. Not a big deal, but would be nice.

Thanks again for this great library.

PH4256:
My final application is a model railway where various sensors trigger sounds at differnt parts of the layout. I plan to have this master Uno linked to three others that monitor various sensors. Using I2C network, I want them to pass commands to the master to play sounds on one of three MP3 players lnked to speakers in different locations.

Cool project! I hope you'll post YouTube vids once complete.

PH4256:

  1. I'd like to pass the track number to play as a variable. If I create an variable "uint16_t tracknum(1);" and use that on the play "myMP31.play(tracknum);" is that ok? I think it works, but need to reformat & reload the sd card to be sure of the file sequence.

Yes, you can pass the track number as a variable.

PH4256:
2) Is it possible for the MP3 player "myMP31" to be a variable also? If so, how please? This would mean I can avoid having the MP3 calls three times in the sketch. Not a big deal, but would be nice.

"myMP31" is a class object, not a variable. If you have 3 MP3 players, you will need 3 individual "myMP3" class objects. You can, however, make an array of these classes and loop through each of them whenever you need to play the same track on each of the MP3 modules:

DFPlayerMini_Fast myMP3s[3];

Hello forum members and Power_Broker,

since I've been experimenting a bit with the DFPlayer Mini, I've always had the problem that I can't jump from one loop to another.

Both with the "DFRobotDFPlayerMini.h" and the "DFPlayerMini_Fast" library.

So for example something like this:

switch (range)
{
case 0:myDFPlayer.loop(1);
break;

case 1:myDFPlayer.loop(2);
break;
}

With the .play() statement this works.

Does anyone have an idea about this, or can it be fixed in the library?

Thanks in advance :slight_smile:

Hi, I tried your code and it works excellently! Super! Thank you very much!

I would like to ask, is it possible if we play a song and at the same time we do a LED fading-in and -out several times? This LED is to match the tempo of the song played.

My simple LED fading-in and -out code is just:

// 1 cycle is 102 iteration. 5 cycle = 102*5 = 510
for (int i = 0; i<510; i++){

// set the brightness of pin 9:
analogWrite(ledTop, brightness);

// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;

// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
// wait for 17 milliseconds to see the dimming effect
delay(17);
}

Does it need parallel processing? Do you have any solution?
Thanks!

How do you plan on sync this up to the length of the audio clip?

My understanding is there is no 'feedback' on the length of the clip currently being played.. (just if it is still being played or not.. which is suspect in itself)

xl97:
How do you plan on sync this up to the length of the audio clip?

My understanding is there is no 'feedback' on the length of the clip currently being played.. (just if it is still being played or not.. which is suspect in itself)

Hi xl97,

thank you for your answer.

The individual loops are single engine sounds at different speeds.

I cut them with "Audacity" so that it is not noticeable when a loop ends and starts all over again.

I read out the PWM signal from an RC receiver and defined value ranges that should play the respective MP3 file depending on the signal that is sent to the DFPlayer Mini via Serial1.

The request is also sent only once, because otherwise the MP3 file starts all par milliseconds from the beginning if the value range does not change.