ArduinoGeneral

New to DFPlayer (detect when audio clip has finished playing & loud pop upon power on/down)

userHead whispers007 2018-02-25 00:54:24 8693 Views6 Replies
I am new to my DFPlayer (mini's)..

I successfully set it up/connected to my Uno...

However.. now I have some minor questions on how to tackle some of the issues I am seeing.


1.) Hardware issue I assume? (although I'm hoping it may be a setting or the order of something in the code)..
When I power up my Uno, with connected DFplayer.. I hear a rather loud 'POP' when the DFplayer gets power.
*I hear the same when cutting power?

How can this be fixed/addressed?

2.) Since I'm just starting my code.. I havent played around too much yet.. but it wasnt clear to me on how (or best approach on how to) detect when an audio file is done playing? I'd like to automatically trigger/play a specific file after the currently trigger/playing file is complete...

Is there a specific function or callback for this in the library And f so.. is there an example of it in use?
2018-03-21 12:55:51 For anyone else searching for a solution the speaker 'pop' when using the DFRobot library...

https://github.com/DFRobot/DFRobotDFPlayerMini

There is a reset() call made in the begin() method.

file:
DFRobotDFPlayerMini.cpp


part of this method/function:
bool DFRobotDFPlayerMini::begin(Stream &stream, bool isACK, bool doReset){

line#:
103 (I believe)

this line: (comment it out)
//reset();


If anyone else reads about the resistor hack/mod for eliminating the speaker 'pop' by moving the 0R resistor on the bottom of the board, to the other side of the amp, where there are two open pads.

DO NOT TRY IT... it doesnt work...

The above works.
userHeadPic whispers007
2018-03-17 02:15:06 ^bump userHeadPic whispers007
2018-03-13 05:18:11
eleqsis wrote:
Tue Feb 27, 2018 10:07 am
The library already provides a function (printDetail > case DFPlayerPlayFinished) that fires if a track has ended. It's within the FullFunction.ino example.
I cant seem to get the built in function to work/detect when a song finishes accurately when its JUST a .play(#) command..

If its a loop() or I use dsiableLoop()/enableLoop() around a.play() command.. I get an accurate read every time..

however.. that seems to mess up the looping behavior of the DFPlayer.. (ie: track 002.wav gets stuck in a loop when it NEVER should... this happens randomly maybe 30% of the time.. other %70 it works as intended)

I posted some threads here asking about DFPLayer stuff.. in one them is an example sketch I invite anyone to try and see if they also get the erroneous looping issues!!

I also asked about checking and updating the DFPlayer firmware?? (Looks like I got an old batch from somewhere?)
userHeadPic whispers007
2018-02-27 21:12:33 Perhaps its my code that is the problem then? The way I am trying to use that then? Because I can NOT seem to get consistent results.. most of the time it doesnt fire at all..

Basically I'm trying to:

Upon power on..
play a boot up sound (001.wav)
waits/listens for button press/state
when the button is pressed down, it plays 002.wav file..
*** if by the time 002.wav file is done playing.. and the button is STILL pressed, .. automatically start to loop 003.wav file.***
when the button is released play 004.wav file.

Maybe you have an example of how it should be done?

heres a quick example where its not working for me:

Code: Select all
//import needed libraries
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"


//project vars
const int buttonPin = 19; //Pin (A5) the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button
int lastButtonState = 1; // previous state of the button
boolean doCompletionCheck = false;

//FSM state control/vars
#define S_IDLE 1
#define S_POWERON 2
#define S_POWERDOWN 3

//FSM init vars
static int state = S_IDLE; // initial state is 1, the "idle" state.

//instantiate class instances
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX (DFPlayer connections)
DFRobotDFPlayerMini myDFPlayer;

void setup() {

  //debug (monitor)
  Serial.begin(115200);

  //talk to DFPlayer
  mySoftwareSerial.begin(9600);

  //declare pin & state
  pinMode(buttonPin, INPUT); // initialize the button pin as a input
  digitalWrite(buttonPin, HIGH); //use interal pull up resistors

  //check on DFPlayer state (ready for use?)
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true); //keep checking,...repeat
  }
  Serial.println(F("DFPlayer Mini online."));

  //why?
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms

  //----Set volume----
  myDFPlayer.volume(9);  //Set volume value (0~30).
  Serial.print(F("CURRENT VOLUME: ")); //read current volume
  Serial.println(myDFPlayer.readVolume()); //read current volume

  //----Set different EQ----//
  myDFPlayer.EQ(DFPLAYER_EQ_ROCK);

  //----Set source device, we use SD as default----//
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);

  //play boot sound on power-up
  myDFPlayer.play(1);

  Serial.print(F("INTIT STATE: "));
  Serial.println(state);

  //delay to let boot sound play and start 'listening' for interaction
  delay(3000);
}

void loop() {

  //FSM state listener
  switch (state) {
    case S_IDLE:

      //check main button state
      buttonState = digitalRead(buttonPin);

      //** button state HAS changed (compare) **//
      if (buttonState != lastButtonState) {
       
        //-- button state changed and is: pressed (ie: down) --//
        if (buttonState == LOW) {
         
         //any time button is pressed down, trigger power on sound
          state = S_POWERON;

         
        //-- button state changed and is: not pressed (ie: up) --//
        }else {       
             
          //any time button is released, trigger power down sound     
          state = S_POWERDOWN;
                         
        }
       

      //** button state has NOT changed  **//     
      }else{
               
        //check if -still- pressed
        if(buttonState == LOW) {
          //Serial.println(F("READ STATE: "));
          //Serial.println(myDFPlayer.readState());
                   
         if(doCompletionCheck == true){     
            Serial.println(F("watching audio file for completion"));     
           
            //dedicated function attempt for checking track completion
            trackComplete(2, 3, 'l');             
           
            /*
            if(myDFPlayer.readType()==DFPlayerPlayFinished && myDFPlayer.readCurrentFileNumber()==2) { 
              Serial.println(F("audio finished..."));
             
              myDFPlayer.loop(3);
              doCompletionCheck = false;
            }
            */
          }

                                   
        }else{
          //Serial.println(F("BUTTON STILL -NOT- PRESSED........ "));   
        }
      }

      //update/save the current button state for next loop/cycle
      lastButtonState = buttonState;
    break;

    case S_POWERON:
      //play power up     
      myDFPlayer.play(2);     
      doCompletionCheck = true;     
     
      //return to button checking
      state = S_IDLE;
    break;

    case S_POWERDOWN:     
      myDFPlayer.play(4);
     
      //return to button checking
      state = S_IDLE;   
    break;
  }

}

//playMode options: p = play or l = loop
void trackComplete(int currTrack, int newTrack, uint8_t playMode) { 
  Serial.print(F("Current Track that is playing: "));
  Serial.print(myDFPlayer.read());
  Serial.print(F(" / "));
  Serial.println(myDFPlayer.readCurrentFileNumber());
 
  Serial.print(F("Checking for completetion of track: "));
  Serial.println(currTrack);
  Serial.println(F(""));
  Serial.println(F(""));
 
  //if(myDFPlayer.readType() == DFPlayerPlayFinished && myDFPlayer.read() == currTrack) {
  if(myDFPlayer.readType() == DFPlayerPlayFinished && myDFPlayer.readCurrentFileNumber() == currTrack) {
  //if(myDFPlayer.readType() == DFPlayerPlayFinished) {
   
    doCompletionCheck = false;
   
    Serial.print(F("TRACK MATCH: "));
    Serial.print(myDFPlayer.readCurrentFileNumber());
    //vs.
    Serial.print(F(" / "));
    Serial.println(myDFPlayer.read());       
   
    Serial.println(F("Setting completion listener off---->"));
    switch (playMode) {
      case 'p':
        myDFPlayer.play(newTrack);
      break;

      case 'l':
        delay(800);
        myDFPlayer.loop(newTrack);
      break;     
    } 
     
  }
  //back to button checking
  state = S_IDLE;
}

userHeadPic whispers007
2018-02-27 18:07:18 The library already provides a function (printDetail > case DFPlayerPlayFinished) that fires if a track has ended. It's within the FullFunction.ino example. userHeadPic eleqsis
2018-02-26 13:27:40 *Looks like the forum doesnt get much traffic any more? (shame)..

I tried to look in the .h files.. (but really only saw the raw HEX value/command being sent)..

If there are built in loop functions.... such as loop folder/directory..

There has to be a pretty efficient way to tell (callback? non blocking looping/function?) that the current files has ended, and do 'whatever' next........no?

How are others out there detecting how a file has completed playing?

Thanks.
userHeadPic whispers007