DFR MP3 Mini Player: How to print folder & file number?

I'm hoping that an experienced user of this popular module can answer a specific question please, as I’ve been struggling with it for over a week.

With the original DFRobot library (DFRobotDFPlayerMini.h) my program uses the play() or playMp3Folder() functions when the micro-SD uses the simple, flat structure modes like:
\mp3\0001.mp3, etc.
And in those, for debugging, I can successfully show the file number that's playing by using readCurrentFileNumber()

But I have 4000 or so music files in 12 categories, so I want to use the alternative folder structure:
01\001.mp3, 01\002.mp3...
02\001.mp3, 02\002.mp3...
etc

I can correctly play file 123 in folder 6 with playFolder(6, 123). But does anyone know of a command (or neat function) that will print the folder and file numbers actually playing please?

I've probably trawled through several hundred sketches and not found one relevant example. Otherwise I will reluctantly have to use the flat mp3 structure, with serious loss of flexibility for future content changes.

As you are telling the MP3 player which folder to use and which file to play, do you not already know this information?

1 Like

Thanks Mark, but no! The key words were "..actually playing ".
This is a debugging tool I need.

I'm not understanding the issue. If you are commanding a specific file to be played from a specific folder, then you have the information. You can monitor the BUSY pin to see when that specific file has finished playing. The player is either playing the file or it has stopped.

Or have I completely misunderstood the issue.

1 Like

No, you haven't misunderstood. For a single play action you're quite right; play(F, f) will play file f in folder F. But it's quite a complex project and I deliberately didn't get into all its detail in my post.

Briefly, I'm using a dozen buttons and a couple of switches to control a music box. And by also using the OneButton library, that means some 20 operations under user control. (Via double-click and long-click.) As soon as a known file finishes playing and some operation like Next, Previous, Jump 10 Forward, etc, or even just automatically playing after switching to Random mode, I really would like to print the file that is playing to develop my further code.

I'm very interested in your suggestion about using the module's Busy pin (and sacrificing a UNO pin, if I can find one not otherwise used). I've seen several posts saying it's unreliable, and introduces unwanted delays. What has been your experience? Can you share some code using it please? Or even better, my preferred approach using _isAvailable() and/or _isSending()? What about 'bool available()' as well? When does that need to be applied?

This is an aspect of the DFR library that I'm struggling with. IOW, where and when I need to make my logic conditional on the state of the module. Ideally avoiding the Busy pin for the time being.

I've not had a problem with the BUSY pin. I was helping out another forum member and put together a simple bit of code that monitored the pin. Have a look at post #68 in the following discussion:

FYI I have a clone DFPlayer Mini.

There's mention of the BUSY pin going either High or Low when playing. That may be down to clones working slightly differently.

BUSY pin is SLOW. and not something to rely on if you want fast/quick reactions.

A long time ago we had some discussions here about using the built in function of when the audio clip was done. I think it ended up being a bit buggy (with a dup output or something?... again this was a while back).. and someone posted a quick code approach/work around.

Because the DFPlayer mini uses the audio clip index on the SD card.. and can not technically read from the SD card.. I dont think you'll ever be able to get an actual file name? (unless you create some sort of lookup list/table in your sketch perhaps?

Try readCurrentFileNumber. It returns an int. If you're really lucky, one byte would be the folder and the other the file number. If that doesn't do it, I can't see how it can be done.

Thanks Mark, studying that this morning.

Given my hope to avoid using the BUSY pin (reinforced by the post this morning from xl97), do you or anyone have an example of code using the inbuilt library commands please?

I'll have another crack at it today, but have previously got myself in knots with isAvailable, for example.

At present my dozen or so play calls look like this:

void singleclickmozart()  //MOZART button 12 is single clicked
{
  Serial.println("MOZART single click"); // pin 12
  myDFPlayer.playFolder(3, 1); // MOZART 1227
  delay(btnGrpDelay);
}

void doubleclickmozart()   //MOZART button 12 is double-clicked
{
  Serial.println("MOZART double click"); // pin 12
  myDFPlayer.playFolder(10, 1); // Easy Listening/Ambient/etc
  delay(btnGrpDelay);
}

Although they appear to work, I suspect that there may be problems because they are 'unconditional'.

Interesting idea, thanks. But testing a few specified and actual prints I see no such match. Of course, my call to Serial.println() might itself be wrongly timed, and I'm exploring that.

Thanks, yes, I recall reading similar and I'll see if I can find it again.

Note that I'm not expecting to read names, just folder and file (track) within that.

Another possible approach, with two assumptions:

  1. I can get the Serial.println(); call correctly located in my code, so that it is actually reporting the track playing (as a single int).
  2. That single int is the 'indexed' position using all tracks.

So for example if folder 1 holds 100 files and folder 2 holds 200, and I specify (2,1), then the print would be 101. A neat function, knowing all the folder file counts, should then be able to return "2,1"

Do you have any experience of using isAvailable please?

Mark,

Not sure I properly understand your BUSY pin demo code in that example you referenced. It seems that logically this would only allow you to play a fresh track only when the currently playing track had finished? IOW, when the module not be busy.

Correct, that was the idea for the bit of code that was asked for in another thread.

You can still look at the state of the BUSY pin as that will tell you when the module is not busy. How you react to the state of the BUSY pin is up to your code.

@markd833

Thanks Mark, appreciate the fast response, as I'm working on it right now.

As you probably gathered from my previous posts, I want a change of track as soon as a button is pressed. My existing code does appear to work OK. In setup() I use

myDFPlayer.enableLoopAll(); //loop all mp3 files
etc

to start playing successive tracks in sequence. If I then press say the MOZART button, this code

void singleclickmozart()  //MOZART button 12 is single clicked
{
  Serial.println("MOZART single click"); // pin 12
  myDFPlayer.playLargeFolder(3, 1); // MOZART 1227
  delay(btnGrpDelay);
}

does so, jumping to play that track. However, it's then silent. I'm struggling with how to get it to automatically resume playing successively from that new file onwards. Any ideas please?

It may just be that you're asking too much from what looks like a fairly primitive library. You might want to check out Adafruit's VS1053-based Boards.

Their VS1053 Library knows how to handle real file names on the SD card and has many more functions available.

As you saw from the photo I posted up thread, I already have the hardware and panel. That’s from my earlier project using DFR’s 1201S USB module (128 MB capacity). I’m now changing the UNO to program the 32 GB micro SD version.

No intention of starting again! Especially with a much more expensive module and a library that looks very complicated and poorly documented, And I see its only GitHub example was described as ‘doesn’t work…’.

Hardware / library works for me. In fact, I modified library to integrate with the PJRC Teensy Audio Library. Enables the VS1053's I2S outputs to provide digital audio all the way to Class D I2S power amp:
https://github.com/gfvalvo/VS1053_Demo

Thanks, but although an experienced electronics hobbyist I’m still a relative novice with both Arduino programming and microprocessors in general.

If anyone is curious, I did eventually solve that outstanding problem, crucial to continuing the project. For each of the button actions, the code looks like this:

void singleclickegcs()  //EGCS/Choirs button 4 is single clicked
{
  Serial.println("EGCS single click");
  myDFPlayer.playLargeFolder(1, 1); //
  delay(btnGrpDelay); // Currently set to 500 ms
  myDFPlayer.next();
  delay(500); // orig = 1000
  myDFPlayer.enableLoopAll();
  delay(500); // orig = 1000
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.