DFPlayerMini_Fast
DFPlayerMini_Fast copied to clipboard
Play specific tracks one after another without delay
Thanks for your help with my volume issue. I now have that working but there is one more thing I'm struggling with. I need to play specific files one after another, without a delay but without the files being cut off. I've tried using isPlaying but I can't seem to figure this out. The busy pin would be an ideal solution but there is a time delay between the player stopping and the pin status changing. Essentially, I want to be able to:
mp3.play(1);
mp3.play(22);
mp3.play(28);
one after another
I'd be really grateful if you could point me in the right direction or provide an example of how I might achieve this. Thanks for a really awesome library!
I usually suggest people use the busy pin since people have found it to be more reliable than the isPlaying() method. Unless you want to add external circuitry (i.e. an envelope detector circuit), you'll need to get either the busy pin or isPlaying() method to work.
To give a little context: play() simply forms and sends a serial command to the MP3 player over UART and doesn't have "built-in" way of blocking the code until the track is done.
My suggestion is to try the following:
- Use .wav files
- After each
play(), add a small delay (10ms or so) - Then call
while(mp3.isPlaying());orwhile(!digitalRead(busy_pin));after the delay - Make sure to run the code in debug mode
- Post the debug printouts and I can take a look at what's going on
Thanks for a really awesome library!
Thanks! Stars are always appreciated 😉😄
Thanks for the suggestions. I tried the code below with no luck. With a 10MS delay the files don't play, with a 100MS delay the first file gets cut off by the second.
I wonder if it would be possible to implement a function in the library perhaps called playThisNext(), which would implement the routines for detecting the end either using the busy pin if specified or the isPlaying function. One would then call for example mp3.playThisNext(track) to play the specified track once the current is finished. Anyway...
Code:
#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>
SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myMP3;
void setup()
{
Serial.begin(9400);
mySerial.begin(9600);
myMP3.begin(mySerial, true);
Serial.println("Setting volume to 4");
myMP3.volume(4);
Serial.println("Looping track 1");
delay(50);
myMP3.play(2);
delay(10);
while(myMP3.isPlaying()) {
//do nothing
}
myMP3.play(12);
while(myMP3.isPlaying()) {
//do nothing
}
}
Serial output:
Setting volume to 4
Sent Stack:
7E FF 6 6 0 0 4 FE F1 EF
Looping track 1
Sent Stack:
7E FF 6 3 0 0 2 FE F6 EF
Sent Stack:
7E FF 6 42 0 0 0 FE B9 EF
Rec: 7E
State: find_start_byte
Rec: FF
State: find_ver_byte
Rec: 6
State: find_len_byte
Rec: 42
State: find_command_byte
timeout error
Sent Stack:
7E FF 6 3 0 0 C FE EC EF
Sent Stack:
7E FF 6 42 0 0 0 FE B9 EF
Rec: 7E
State: find_start_byte
Rec: FF
State: find_ver_byte
Rec: 6
State: find_len_byte
Rec: 42
State: find_command_byte
timeout error
Sent Stack:
7E FF 6 42 0 0 0 FE B9 EF
Rec: 7E
State: find_start_byte
Rec: FF
State: find_ver_byte
Rec: 6
State: find_len_byte
Rec: 42
State: find_command_byte
timeout error
That's not good. For some reason your MP3 player is only getting 4 bytes out of a 10 byte packet. Try increasing the timeout using mp3.setTimeout(2000); and see if that doesn't improve things for you.
I modified as you suggested with no luck. I added a missing delay before the second call to while() and improved the serial feedback. The second file now gets played but not the first. Serial output:
Setting volume to 4
Sent Stack:
7E FF 6 6 0 0 4 FE F1 EF
Playing track 1
Sent Stack:
7E FF 6 3 0 0 2 FE F6 EF
Sent Stack:
7E FF 6 42 0 0 0 FE B9 EF
Rec: 7E
State: find_start_byte
Rec: FF
State: find_ver_byte
Rec: 6
State: find_len_byte
timeout error
Playing track 2
Sent Stack:
7E FF 6 3 0 0 C FE EC EF
Sent Stack:
7E FF 6 42 0 0 0 FE B9 EF
timeout error
I used the following code with larger delays and isPlaying() worked fine for me:
#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>
DFPlayerMini_Fast myMP3;
void setup()
{
Serial.begin(115200);
Serial1.begin(9600);
myMP3.begin(Serial1, true);
delay(1000);
Serial.println("Setting volume to 4");
myMP3.volume(4);
Serial.println("Looping track 1");
delay(1000);
myMP3.play(1);
delay(1000);
while (myMP3.isPlaying()) {
//do nothing
}
myMP3.play(2);
while (myMP3.isPlaying()) {
//do nothing
}
}
void loop()
{
}
Setting volume to 4
21:27:37.239 -> Sent Stack:
21:27:37.239 -> 7E FF 6 6 0 0 4 FE F1 EF
21:27:37.239 ->
21:27:37.239 -> Looping track 1
21:27:38.217 -> Sent Stack:
21:27:38.217 -> 7E FF 6 3 0 0 1 FE F7 EF
21:27:38.217 ->
21:27:39.242 -> Sent Stack:
21:27:39.242 -> 7E FF 6 42 0 0 0 FE B9 EF
21:27:39.242 ->
21:27:39.242 -> Rec: 7E
21:27:39.242 -> State: find_start_byte
21:27:39.242 -> Rec: FF
21:27:39.242 -> State: find_ver_byte
21:27:39.242 -> Rec: 6
21:27:39.242 -> State: find_len_byte
21:27:39.242 -> Rec: 42
21:27:39.242 -> State: find_command_byte
21:27:39.242 -> Rec: 0
21:27:39.242 -> State: find_feedback_byte
21:27:39.242 -> Rec: 2
21:27:39.242 -> State: find_param_MSB
21:27:39.288 -> Rec: 1
21:27:39.288 -> State: find_param_LSB
21:27:39.288 -> Rec: FE
21:27:39.288 -> State: find_checksum_MSB
21:27:39.288 -> Rec: B6
21:27:39.288 -> State: find_checksum_LSB
21:27:39.288 -> Rec: EF
21:27:39.288 -> State: find_end_byte
21:27:39.288 ->
21:27:39.288 -> Sent Stack:
21:27:39.288 -> 7E FF 6 42 0 0 0 FE B9 EF
21:27:39.288 ->
21:27:39.288 -> Rec: 7E
21:27:39.288 -> State: find_start_byte
21:27:39.288 -> Rec: FF
21:27:39.288 -> State: find_ver_byte
21:27:39.288 -> Rec: 6
21:27:39.288 -> State: find_len_byte
21:27:39.288 -> Rec: 42
21:27:39.288 -> State: find_command_byte
21:27:39.288 -> Rec: 0
21:27:39.288 -> State: find_feedback_byte
21:27:39.288 -> Rec: 2
21:27:39.288 -> State: find_param_MSB
21:27:39.288 -> Rec: 1
21:27:39.288 -> State: find_param_LSB
21:27:39.288 -> Rec: FE
21:27:39.288 -> State: find_checksum_MSB
21:27:39.288 -> Rec: B6
21:27:39.336 -> State: find_checksum_LSB
21:27:39.336 -> Rec: EF
21:27:39.336 -> State: find_end_byte
21:27:39.336 ->
21:27:39.336 -> Sent Stack:
21:27:39.336 -> 7E FF 6 42 0 0 0 FE B9 EF
21:27:39.336 ->
21:27:39.336 -> Rec: 7E
21:27:39.336 -> State: find_start_byte
21:27:39.336 -> Rec: FF
21:27:39.336 -> State: find_ver_byte
21:27:39.336 -> Rec: 6
21:27:39.336 -> State: find_len_byte
21:27:39.336 -> Rec: 42
21:27:39.336 -> State: find_command_byte
21:27:39.336 -> Rec: 0
21:27:39.336 -> State: find_feedback_byte
21:27:39.336 -> Rec: 2
21:27:39.336 -> State: find_param_MSB
21:27:39.336 -> Rec: 1
21:27:39.336 -> State: find_param_LSB
21:27:39.336 -> Rec: FE
21:27:39.336 -> State: find_checksum_MSB
21:27:39.336 -> Rec: B6
21:27:39.336 -> State: find_checksum_LSB
21:27:39.336 -> Rec: EF
21:27:39.336 -> State: find_end_byte
Thanks. That does work, but unreliably with files still getting cut off. I'm wondering if using the busy pin might be a better idea. Would it be possible to implement a function into the library to monitor the busy pin for this purpose? Perhaps a queue function could be implemented that would use a specifiable busy pin to play tracks 1 after the other. Thoughts? Thanks for your continued help.
I've been thinking some more on this. Is there a way to get the length of the currently playing file? I couldn't see anything in the data sheet but might have missed it. Perhaps this would be a more reliable alternative.
Hi. Still struggling getting this to work. Any further ideas? Switching to genuine DFPlayer modules helped a lot, but I'm still wondering if it would be possible to implement a function directly to manage this which would make the code a lot cleaner. I.E playWhenFinished(file).