Forum >DFPlayer mini + gets stuck in loop when it shouldnt.
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)
