DFPlayer without delay

hey, I ran into some problems while using the DFPlayer mini-module for the first time. I want to build a device where I can select a specific song with an encoder and play that song on a DFPlayer when I press a button.

I experimented already a bit with some example sketches and already have the encoder bit, but I can't figure out how to play a song without a delay. I saw in almost all examples that the song is played by the myDFPlayer.play(); ( changes with every library ) command followed by a delay. but my songs will warry in length so I cant set a specific delay, and if I am waiting for the delay I can't stop the song because the Arduino is still waiting for the delay.

I hope someone can help me.

Best regards from Germany, Lorenz

I ran into a similar problem a couple of years ago with one of my own projects. Turns out the default library is absolutely horridly written and unnecessarily inefficient.

So I decided to write my own DFPlayerMini library.

Although you'll still have slight delay before the song plays, it will be a large improvement over the standard library. The reason for the slight delay is due to the MP3 player having to do some preprocessing (I think decompression?) before playing the song - no library can fix that.

thank you so much for your replay, but that was not the problem that I was having. My problem is that I want to send a command to play a song and not have to put in a delay for how long it should play. So I want to say "start playing" and it should play until I tell it to stop. I know there is a busy pin on the DFPlayer, maybe I can youse that, but I can't really figure out how to use it. Maby someone has an idea and can help me.

best regards, Lorenz

Ohhh, I see now. Well, in the linked library, there is a member function called trackIsPlaying() that will return true or false based on if the module is playing a song or not.

thank you very much, I will trie that out :wink:

hey, I just tried the command but I get an error that says “trackIsPlaying() was not declared in the scope”.
this is the code that I tried it with:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

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

  myMP3.begin(mySerial);
  
  Serial.println("Setting volume to max");
  myMP3.volume(30);
  delay(20);
   

}

void loop()
{
 if(trackIsPlaying() == true) {
   myMP3.play(1);
 }
 

}

maybe somebody could help me, that would be really nice :wink:

That’s because trackIsPlaying() is a member function. As in it’s a member of the DFPlayerMini_Fast class.

Try this:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

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

  myMP3.begin(mySerial);
 
  Serial.println("Setting volume to max");
  myMP3.volume(30);
  delay(20);
   

}

void loop()
{
 if(myMP3.trackIsPlaying() == false) {
   myMP3.play(1);
 }
 

}

yeaaaaaah, it is working. thank you so mutch :)

Hi! I'm encountering the same issue.

The library has been updated recently and the "trackIsPlaying()" function is gone.

I used the older version to run the code above and I got intermittent audio.

Is it possible to play some random mp3 files without delay in the latest library?

kevin020792: The library has been updated recently and the "trackIsPlaying()" function is gone.

Yes, I updated it to "isPlaying()"

kevin020792: Is it possible to play some random mp3 files without delay in the latest library?

Yes, you can use "randomAll()". You can also use "numTracksInFolder(uint8_t folder)" and/or "numSdTracks()" to determine how many files you have, generate a random file number, and then play that file.

A full API listing is on the GitHub readme, but I'll post it below for ease of reference:

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);

Also, files play faster if you save them as uncompressed WAV files

Hi! Great thanks to your reply!

To play the audio files randomly, the “randomAll()” function must be written inside the setup() function, previous than the loop() function.
For instance:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

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

  myMP3.begin(mySerial);
  
  Serial.println("Setting volume to 5/30");
  myMP3.volume(5);
  delay(20);
  
  

  Serial.println("Random play");
  myMP3.randomAll(); //Play all randomly
}

void loop()
{
  //do nothing
}

I found this is one of the easiest way to play all of the mp3 files randomly.

For now I’m trying to control the specific songs that I want to play with some buttons.

Therefore I went back to square one to see if the member functions can be used in the loop() function, I’ve tried the code like this:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

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

  myMP3.begin(mySerial);


  Serial.println("Setting volume to 5/30");
  myMP3.volume(5);
  delay(20);
 
  
}

void loop()
{
 if (myMP3.isPlaying() == false){
  myMP3.play(1);
 }

}

The code didn’t work, nor the blue LED indicator on the DFPlayer mini would light up.

I want to switch to specific songs with buttons.

In my imagination I thought I can control the DFPlayer mini as follows:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

int songPlay;

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

  myMP3.begin(mySerial);

  pinMode(3, INPUT); //Button for play song 1
  pinMode(4, INPUT); //Button for play song 2
  // no input = loop song 3 at the beginning

  Serial.println("Setting volume to 5/30");
  myMP3.volume(5);
  delay(20);
 
  
}

void loop()
{
 if (digitalRead(3) == HIGH){
 songPlay = 1; 
 }
 else if (digitalRead(4) == HIGH){
 songPlay = 2;
 }
 else {
songPlay = songPlay;
 }

if (songPlay == 1){ 
  if (myMP3.isPlaying() == false){
     myMP3.play(1);
     }
  else{
    if (myMP3.currentSdTrack() != 1){
    myMP3.play(1); 
   }
  }
}
else if (songPlay == 2){ 
  if (myMP3.isPlaying() == false){
     myMP3.play(2);
     }
  else{
    if (myMP3.currentSdTrack() != 2){
    myMP3.play(2); 
   }
  }
 }
else {
  if (myMP3.isPlaying() == false){
     myMP3.loop(3);
     }

 }
}

The code is a no-go.
It would be very nice to know what’s wrong with the codes above.

I have some problem, I want play music without delay but I'am using YX5300 not DFPplayer. the question is can i use that library to my yx5300?

I believe the YX5300 is the chip used in the DFPlayer Mini. The library should work for your MP3 player.

okay thx for the reply, i will try it

i’ve tried it, but it cannot playing properly. I dont know whats the problem of my code. here my code:

void loop(){

myMP3.isPlaying() == false;

if ( analogRead(A0) < 300 ){
myMP3.play(1);

}
if ( analogRead(A0) > 300 ){
myMP3.play(2);
}

}

The scenario is, when the sensor is detecting white it would play song number1 if the sensor is detecting black it would play song number 2. But in the reality, the song only plays 1 second and continues to repeat even though the duration of the song is 3 minutes and when the sensor detects another, mp3 can play different songs but have the same problem as explained earlier. could you see whats my mistake in the code ?

A. This is not your code, this a snippet of the code. Please post the entire code so we can see the whole thing. For instance, you don’t have the library installed here nor is there a void setup() field.

B. Please use code tags when you post. Looks like this <> in the reply options.

davehyder:
The scenario is, when the sensor is detecting white it would play song number1 if the sensor is detecting black it would play song number 2. But in the reality, the song only plays 1 second and continues to repeat even though the duration of the song is 3 minutes and when the sensor detects another, mp3 can play different songs but have the same problem as explained earlier. could you see whats my mistake in the code ?

I’m having a real hard time understanding what you’re trying to say here. That being said, you might be able to fix the problem by using the class member function myMP3.isPlaying() to determine if a song is being played.

For example, the following code will play all of track 1 and then immediately play track 2. However, note that track 2 will loop:

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

SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;

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

  myMP3.begin(mySerial);
  
  myMP3.volume(30);
  delay(20);
  
  myMP3.play(1);
  
}

void loop()
{
  if(!myMP3.isPlaying())
    myMP3.play(2);
}

halloweenrick:
A. This is not your code, this a snippet of the code. Please post the entire code so we can see the whole thing. For instance, you don’t have the library installed here nor is there a void setup() field.

B. Please use code tags when you post. Looks like this <> in the reply options.

Im sorry sir i dont know. Its the first time I join this forum :). however, in this below is my code. so, I build line follower robot and i want to add mp3 to my project. the scenario is, when my robot is moving , the mp3 would play song number 1. and if my robot stop, the mp3 would play song number 2. I simulate with 1 sensor line tracking first before i applicate it in my line follower

//code rearranged by Javier Muñoz 10/11/2016 ask me at javimusama@hotmail.com
#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>


DFPlayerMini_Fast myMP3;




#define ARDUINO_RX 5//should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6//connect to RX of the module
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);//init the serial protocol, tell to myserial wich pins are TX and RX

////////////////////////////////////////////////////////////////////////////////////
//all the commands needed in the datasheet(http://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf)
static int8_t Send_buf[8] = {0} ;//The MP3 player undestands orders in a 8 int string
                               //0X7E FF 06 command 00 00 00 EF;(if command =01 next song order) 
#define NEXT_SONG 0X01 
#define PREV_SONG 0X02 

#define CMD_PLAY_W_INDEX 0X03 //DATA IS REQUIRED (number of song)

#define VOLUME_UP_ONE 0X04
#define VOLUME_DOWN_ONE 0X05
#define CMD_SET_VOLUME 0X06//DATA IS REQUIRED (number of volume from 0 up to 30(0x1E))
#define SET_DAC 0X17
#define CMD_PLAY_WITHVOLUME 0X22 //data is needed  0x7E 06 22 00 xx yy EF;(xx volume)(yy number of song)

#define CMD_SEL_DEV 0X09 //SELECT STORAGE DEVICE, DATA IS REQUIRED
              #define DEV_TF 0X02 //HELLO,IM THE DATA REQUIRED
              
#define SLEEP_MODE_START 0X0A
#define SLEEP_MODE_WAKEUP 0X0B

#define CMD_RESET 0X0C//CHIP RESET
#define CMD_PLAY 0X0D //RESUME PLAYBACK
#define CMD_PAUSE 0X0E //PLAYBACK IS PAUSED

#define CMD_PLAY_WITHFOLDER 0X0F//DATA IS NEEDED, 0x7E 06 0F 00 01 02 EF;(play the song with the directory \01\002xxxxxx.mp3

#define STOP_PLAY 0X16

#define PLAY_FOLDER 0X17// data is needed 0x7E 06 17 00 01 XX EF;(play the 01 folder)(value xx we dont care)

#define SET_CYCLEPLAY 0X19//data is needed 00 start; 01 close

#define SET_DAC 0X17//data is needed 00 start DAC OUTPUT;01 DAC no output
////////////////////////////////////////////////////////////////////////////////////


void setup()
{

Serial.begin(115200);//Start our Serial coms for serial monitor in our pc
mySerial.begin(9600);//Start our Serial coms for THE MP3
delay(500);//Wait chip initialization is complete 
myMP3.begin(mySerial);
myMP3.volume(30);
pinMode(A0,INPUT);


}
void loop()
{

Serial.print(analogRead(A0) );
Serial.println();


myMP3.isPlaying() == false;

if ( analogRead(A0) < 300  ) // robot move
{

myMP3.play(1);
}

if ( analogRead(A0) > 300   ) // robot stop
{

myMP3.play(2);
}

}
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for(uint8_t i=0; i<8; i++)//
{
 mySerial.write(Send_buf[i]) ;//send bit to serial mp3
 Serial.print(Send_buf[i],HEX);//send bit to serial monitor in pc
}
Serial.println();
}

Why don't you use tabs in your code???? (hint: ctrl+a, ctrl+t)