DFPlayer mini + gets stuck in loop when it shouldnt.
Where can we go to get help or talk about the DFPlayer? This forum seems pretty dead lately.. and most posts have 0 replies. (DFPlayer posts are almost ALL 0 replies!) LOL
I have have a sketch that is really nothing more than a button (switch) state checker/listener..
button is pressed = play power on (002.wav) sound clip (one time)
if button is STILL pressed after power on clip is complete, immediately play the thrust (003.wav) sound clip, in a LOOP..
when pressed is released, play power down (004.wav) sound clip..
I have found that while trying to check when a clip has completed playback... just using myDFPlayer.play(#).. makes the isFinished function/listener (same as printDetail() function,.. but trimmed down) IMMEDIATELY say the song is finished, even though I can hear is still playing.
If I put a disableLoop() and/or enableLoop() before/after the play() command... this -SEEMS- to allow for the isFinished() listener to accurately report when the song is complete...
WHY?
does the myDFPlayer.play(#); action NOT work for trying to detect when a song is complete?
My main concern is that when trying to transition form a regular .play() command, to a .loop(#) command.. my power on sound clip will sometimes get stuck in a loop.. when only the thrust (003.wav) should EVER be in a loop
What is the correct/appropriate way to:
1.) Be able to detect when a song is complete (my results have shown I need to enableLoop() for that to work or be accurate)..
2.) Transition from a .play(#) to a .loop(#) action seamlessly.. without the .play(#) file being accidentally being looped?
Some combination of enableLoop() & disableLoop() and their placement HAS to be the key here?
Please try this demo code..
you only need a button/switch on A5/D19.. and a DFPlayer with 4 .wav files on it..
001.wav - boot sound, only plays once time when powered up
002.wav - plays when button is pressed (one time)
003.wav - loops for as long as button is pressed (after 002.wav is finished playing)
004.wav - plays when the button is released
Here is my demo code:
I have have a sketch that is really nothing more than a button (switch) state checker/listener..
button is pressed = play power on (002.wav) sound clip (one time)
if button is STILL pressed after power on clip is complete, immediately play the thrust (003.wav) sound clip, in a LOOP..
when pressed is released, play power down (004.wav) sound clip..
I have found that while trying to check when a clip has completed playback... just using myDFPlayer.play(#).. makes the isFinished function/listener (same as printDetail() function,.. but trimmed down) IMMEDIATELY say the song is finished, even though I can hear is still playing.
If I put a disableLoop() and/or enableLoop() before/after the play() command... this -SEEMS- to allow for the isFinished() listener to accurately report when the song is complete...
WHY?
does the myDFPlayer.play(#); action NOT work for trying to detect when a song is complete?
My main concern is that when trying to transition form a regular .play() command, to a .loop(#) command.. my power on sound clip will sometimes get stuck in a loop.. when only the thrust (003.wav) should EVER be in a loop
What is the correct/appropriate way to:
1.) Be able to detect when a song is complete (my results have shown I need to enableLoop() for that to work or be accurate)..
2.) Transition from a .play(#) to a .loop(#) action seamlessly.. without the .play(#) file being accidentally being looped?
Some combination of enableLoop() & disableLoop() and their placement HAS to be the key here?
Please try this demo code..
you only need a button/switch on A5/D19.. and a DFPlayer with 4 .wav files on it..
001.wav - boot sound, only plays once time when powered up
002.wav - plays when button is pressed (one time)
003.wav - loops for as long as button is pressed (after 002.wav is finished playing)
004.wav - plays when the button is released
Here is my demo code:
Code: Select all
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
const int buttonPin = 19;
int buttonState = 0;
int lastButtonState = 1;
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 5; // the debounce time; increase if the output flickers
boolean doCompletionCheck = false;
int currentTrack = 0;
#define S_IDLE 1
#define S_POWERON 2
#define S_POWERDOWN 3
static int state = S_IDLE;
DFRobotDFPlayerMini myDFPlayer;
SoftwareSerial myDFPlayerSerialConn(7, 8);
void setup() {
//debug (monitor)
Serial.begin(115200);
//talk to DFPlayer
myDFPlayerSerialConn.begin(9600);
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
if (!myDFPlayer.begin(myDFPlayerSerialConn)) {
Serial.println(F("Unable to begin:"));
Serial.println(F(" - Please recheck the connection!"));
Serial.println(F(" - Please insert the SD card!"));
while (true);
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.setTimeOut(500);
myDFPlayer.volume(7);
myDFPlayer.EQ(DFPLAYER_EQ_ROCK);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
myDFPlayer.play(1);
delay(2000);
}
void loop() {
switch (state) {
case S_IDLE:
buttonState = digitalRead(buttonPin);
//if (buttonState != lastButtonState) {
if ((buttonState != lastButtonState) && (millis() - lastDebounceTime > debounceDelay)) {
lastDebounceTime = millis(); //update last time pressed/released
if (buttonState == LOW) {
state = S_POWERON;
}else {
state = S_POWERDOWN;
}
}else{
if(buttonState == LOW) {
if(currentTrack == 2 && doCompletionCheck == true){
if(myDFPlayer.available()) {
if(isFinished(myDFPlayer.readType(), myDFPlayer.read()) == 1){
//if(isFinished(myDFPlayer.readType(), myDFPlayer.read()) == 1 && myDFPlayer.readState() != 513){
//if(doCompletionCheck == true && currentTrack == 2 && myDFPlayer.readState() != 513 && isFinished(myDFPlayer.readType(), myDFPlayer.read()) == 1){
//if(myDFPlayer.readState() != 513){
Serial.println(F(">>> POWER ON PLAYBACK COMPLETE <<<"));
currentTrack = 3;
doCompletionCheck = false;
//myDFPlayer.stop();
//myDFPlayer.disableLoop();
//delay(10);//just a test!!!
myDFPlayer.loop(3);
//myDFPlayer.play(3);
//myDFPlayer.next();
//myDFPlayer.enableLoop();
}
}
}
}else{
if(currentTrack == 4 && doCompletionCheck == true){
if(myDFPlayer.available()) {
if(isFinished(myDFPlayer.readType(), myDFPlayer.read()) == 1){
Serial.println(F(">>> POWER OFF PLAYBACK COMPLETE <<<"));
doCompletionCheck = false;
}
}
}
}
}
lastButtonState = buttonState;
break;
case S_POWERON:
Serial.println(F("[POWER UP]"));
currentTrack = 2;
doCompletionCheck = true;
//myDFPlayer.disableLoop();
myDFPlayer.play(2);
//myDFPlayer.enableLoop();
state = S_IDLE;
break;
case S_POWERDOWN:
Serial.println(F("[POWER DOWN]"));
currentTrack = 4;
doCompletionCheck = true;
//myDFPlayer.disableLoop();
myDFPlayer.play(4);
//myDFPlayer.enableLoop(); //do not enable!
state = S_IDLE;
break;
}
}
//used to check when a track is done playing
int isFinished(uint8_t type, int value) {
switch (type) {
case DFPlayerPlayFinished:
return 1;
break;
//nothing
default:
break;
}
}
2018-05-30 22:14:43 Have you ever tried to just use one button to play one specific song, because there is no example about using a button to control a specific song by arduino code in the wiki(except for AD key mode), why don't you try 001.wav & 002.wav first. robert.chen
2018-05-25 12:47:11 ^bump (again)
Still on the look out for a TRIED -n- TRUE solution for reliably detecting when an audio clip is finished playing.
Especially with the example sketch above.
* press button -
* playing a clip using the .play(#) command... (clip #1)
* keep holding button down -
* sitting in a loop, constantly checking for this (clip #1) to be finished..
* Once playback complete is detected, start a .loop(#) command (clip #2)... that will loop until the button is released
* button release happens
* stops .loop(#) for clip #2
* automatically trigger .play(#) (clip #3)
...wait for button press/hold again..
Anyone show me proof where clip #1 doesnt randomly get stick in a LOOP! (that is only intended for clip #2 after clip #1 playback complete is detected) whispers007
Still on the look out for a TRIED -n- TRUE solution for reliably detecting when an audio clip is finished playing.
Especially with the example sketch above.
* press button -
* playing a clip using the .play(#) command... (clip #1)
* keep holding button down -
* sitting in a loop, constantly checking for this (clip #1) to be finished..
* Once playback complete is detected, start a .loop(#) command (clip #2)... that will loop until the button is released
* button release happens
* stops .loop(#) for clip #2
* automatically trigger .play(#) (clip #3)
...wait for button press/hold again..
Anyone show me proof where clip #1 doesnt randomly get stick in a LOOP! (that is only intended for clip #2 after clip #1 playback complete is detected) whispers007