Good day! There is one Student project which uses DFPlayer Mini and Arduino.
We need to create array which contain filenames (0001.mp3-9999.mp3) in special (selected) folder - which is mostly not more than 65 files.
Need create array which contain filenames as array item.
Then, need randomly select one from that array and do tasks with it in our code.
Welcome to the forum
I assume that this is urgent because the project is due to be handed in soon but you should have started creating the solution earlier
What have you tried so far ?
So you know how to declare an array ?
Do you know how to populate the array with filenames ?
Do you know how to generate a random number ?
Where are you stuck ?
the DFPlayer Mini actually does not care about the file names on the SD card. It cares about the order in which the files were copied over the SD card.
Assuming you use the DFRobot library, when you ask to play song number 5 with mp3_play (5);
you are not really playing the file mp3/0005.mp3
but the 5th file that was copied over whatever its name.
The name is just a convention because most OS will copy files in alphabetical order when you move them to the SD card, thus copying first 0001.mp3 and then 0002.mp3 etc
that being said, is this still a necessary request ?
do you really need it ? can't you just draw a random number between 1 and 65 (or whatever is the count of files in that directory)?
As I explained above the DFPlayer does not care about the file names. What matters is the order used when copying the files over the SD card.
say you copy first "mysong.mp3
" and then "0001.mp3
" if you ask the library mp3_play (1);
you'll play "mysong.mp3
"
I am not familiar with the library, but I would have expected it to play "0001.mp3
" because to me "mysong.mp3
" is the first file in the folder and hence has an index of zero while "0001.mp3
" has an index of 1
Are you saying that the files have alphanumeric names such as sound01.mp3, sound02.mp3, bang.mp3, creek.mp3 etc?
Is that because you need a lookup table to to convert the alphanumeric track name into its equivalent file number?
I think they start counting at 1 but I might be wrong - long time since I did not read their weirdly translated Chinese user manual
You are reading the status microseconds after asking the module to play something, the serial command might not even have gone through yet and the module might not have started. Add a flush and a small pause before checking the status.
As said above twice already the file name does not matter.
The DFRobot’s library has functions calls that seem to have an interesting name… I would explore those
int readFileCounts(uint8_t device);
int readCurrentFileNumber(uint8_t device);
int readFileCountsInFolder(int folderNumber);
int readFileCounts();
int readFolderCounts();
int readCurrentFileNumber();
Seen this?
As The file name does not matter (x3) so you just need the count of files. You don’t need an array.
That's correct. With the oddity that play(0) also plays the first track.
If I had more info (&& if your student project deadline hasn't already passed) I could probably help you, as I have used arrays and randomness with that player in several projects.
In addition to some of the questions already raised by @UKHeliBob and @J-M-L , where is your code? That will first tell us what library you are using. Based on the extract you've posted, it's certainly not the 'official' one from DFR. That's what I use and recommend, after investigating several others.
But it might also help us better understand what you mean by:
"We need to create array which contain filenames (0001.mp3-9999.mp3) in special (selected) folder - which is mostly not more than 65 files." To me, that appears self-contradictory?
From your latest post, am I right in assuming that you sometimes want to play a random file (over the range 1 to 3000?) but sometimes a specific file?
Please also show us a screenshot of the micro-SD file structure.
I don’t see why your case is special.…
if you know you have 7 files in the directory then
- You play the first file with number 1
- You play the second file with number 2
…. - You play the last file with number 7
➜ the numbers go from 1 to the number of files, that’s it.
And The first file could be named file2.mp3 whilst the second could be file1.mp3…. Names do not matter, or the 0003 index does not matter unless you know exactly in which order the files where copied n the SD…
Just use that
byte fileIndexes[100];
for(byte n=0; n<100;n++) fileIndexes[n] = n;
Replace 100 by the file count in the target directory
OK! From begining.
I have several folders, that contain up to 64 files.
Filenames are 0001.mp3 to 0064.mp3 but not in sequence.
There can be 10 files, 20 file, 30, 50 or even all 65 files. (excluding 0000.mp3 and 0065.mp3 files).
As user, I do not know, that kind of SD card other part will provide, but they know rules of 64 files in folder.
I need to make array of that 64 files and know max amount of files (can get with single commands, but better to know length of elements in array).
In one of games, I need to chose random number and play file with that random name. But, because of there is not all files, system returning error and I need to find another random number and check that file exsistance again.
If that file exists, I'm playing it.
Why I need array?
Becouse, using just random, in case, when tere is 20 files, they continously repeat same file, and it annoying. And beside, choosing existing files takes users time.
We had other part of code which works well and everything works well.
Just when we cchoosing random files, that glitch happens, which takes time to find existing file and also playing same file repeatedly.
When we will have massive, at least, we can creat 2nd similar massive which we'll store already played file number and will not repeat it before 10 different songs will play.
Note what @J-M-L said
So, if you had 7 files named
4.mp3
5.mp3
6.mp3
3.mp3
2.mp3
11.mp3
7.mp3
in that order in a folder, then playing file number 1 would play 4.mp3 and playing file number 2 would play 5.mp3 and so on. The actual filenames are irrelevant to DFPlayer. Only their order in the folder matters
If you want to play files in a different order then you need an array of filenames indexed by their position in the folder. You search the array for the required filename, get its index number and play that file number
Either that or you save them on the SD card in the order that you want to play them regardless of their name
I've had no reply to my post #17 so I'm guessing. But I think the OP knows that, and is looking for something like this example:
int folderSize;
// Suppose we have 10 test folders for this example
// As all their sizes are known, put them in an array
const int folderSizes[10] {20, 4, 2, 4, 1, 4, 3, 4, 37, 26};
int trackArray[65]; // Max folder size for eventual project
int i;
void setup()
{
randomSeed(analogRead(6) * analogRead(7));
// To choose a random folder
int randNumberF = random(1, 11); // Choose random folder 1-10
// Or comment out the above line and instead test a specific folder
randNumberF = 2;
folderSize = folderSizes[randNumberF - 1];
Serial.begin(115200);
delay(200);
createTrackArray();
i = 0;
}
void createTrackArray()
{
// As all folder sizes are known, an array of its original
// track numbers can be created, from 1 to folderSize
for (i = 0; i < folderSize; i++)
{
trackArray[i] = i + 1;
}
// Randomise (shuffle) the folder tracks
for (int i = 0; i < folderSize; i++)
{
int pos = random(folderSize);
int t = trackArray[i];
trackArray[i] = trackArray[pos];
trackArray[pos] = t;
}
// Print for debugging after randomising
Serial.println("Printing check of trackArray");
for (int i = 0; i < folderSize; i++)
// for (int i = 0; i < folderSize; i++)
{
Serial.print("trackArray[");
Serial.print(i);
Serial.print("] = ");
Serial.println(trackArray[i]);
}
delay(1000);
i = 0;
}
void loop()
{
}
/*
* Output for specified folder 2
*
16:14:39.241 -> Printing check of trackArray
16:14:39.241 -> trackArray[0] = 3
16:14:39.241 -> trackArray[1] = 4
16:14:39.241 -> trackArray[2] = 2
16:14:39.241 -> trackArray[3] = 1
16:14:39.241 -> trackArray[4] = 0
16:14:39.241 -> trackArray[5] = 0
16:14:39.241 -> trackArray[6] = 0
16:14:39.241 -> trackArray[7] = 0
16:14:39.241 -> trackArray[8] = 0
16:14:39.241 -> trackArray[9] = 0
*/
Doesn't look like the OP is still interested, but for anyone curious why the debugging print in my sketch looked odd I've just noticed a typo. This line is now correct:
for (int i = 0; i < folderSize; i++)
- Using the API, Ask for the numbers of files in the target directory, say it’s 15
- create a byte array with 15 entries and populate it with numbers from 1 to 15
byte fileIndexes[15];
for(byte n=0; n<15;n++) fileIndexes[n] = n+1;
-
use a shuffling algorithm (like Fisher–Yates shuffle - Wikipedia) to shuffle the 15 entries
-
then go through the array (0 to 14) to play all the songs in random order
@J-M-L
That’s what I did in my sketch of post #22.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.