[Solved]DFPlayer Mini - Pause/Play problem

Hi Folks, Long time lurker, first time poster!

I’m building a ‘one button’ audiobook player for my Dad, who can barely see and therefore can’t use the traditional MP3 player/Smartphone type solutions for listening to audiobooks. I have a small amount of experience with simple Arduino projects, but this is my first time actually ‘making’ something that solves a problem.

Where I’m up to so far:

Using an Arduino Mega and DFPlayer Mini, I have successfully:

  1. Set the player to play automatically through headphones when powered on;
  2. Set it to play next track automatically at the end of each chapter;
  3. Set it to bookmark to EEPROM at the beginning of each track;
  4. Set it to play from the beginning of the last chapter when rebooting.

The problem I have seems to be the simplest part of the project, but is proving problematic. The play/pause button just won’t work. As it stands, the button (momentary push) will pause the playback, but then will not resume on second push - it just flickers and playback continues whilst the button is pressed down.

I know there’s something really simple I’m missing and would really appreciate your help in finding out what that is!

Thanks in advance,

Charles

CODE:

#include <EEPROM.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
# define ACTIVATED HIGH

int addr = 0;
int address= 0;
byte value;
int buttonPause = 4;
int LED = 7;
boolean isPlaying = false;


SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

void setup() {
pinMode(buttonPause, INPUT);
digitalWrite(buttonPause,HIGH);
pinMode (LED, OUTPUT);
mySoftwareSerial.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
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){
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  Serial.println(F("DFPlayer Mini online."));
  value = EEPROM.read(0);
  myDFPlayer.volume(18);  //Set volume value. From 0 to 30
  myDFPlayer.play(EEPROM.read(0));  //Play last bookmark
  }


void loop ()
{  if (digitalRead(buttonPause) == ACTIVATED)
   {
    if(isPlaying==true)
    {
     myDFPlayer.pause();
      digitalWrite(LED, HIGH);
      isPlaying=false;
      Serial.println("paused");
      }
 }else
    {
      isPlaying ==false;
      myDFPlayer.start();
      digitalWrite(LED, LOW);
      Serial.println("playing"); 
  }

 { if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }
  if (myDFPlayer.readType()==DFPlayerPlayFinished){
      myDFPlayer.next();} //detect if track has finished and play next
 }}
void printDetail(uint8_t type, int value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerUSBInserted:
      Serial.println("USB Inserted!");
      break;
    case DFPlayerUSBRemoved:
      Serial.println("USB Removed!");
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      EEPROM.write(addr, value+1); //write bookmark to EEPROM
      Serial.println(F(" Play Finished!"));
      
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
  
}

In this section I see two issues:

    if(isPlaying==true)
    {
     myDFPlayer.pause();
      digitalWrite(LED, HIGH);
      isPlaying=false;
      Serial.println("paused");
      }
 }else
    {
      isPlaying ==false;
      myDFPlayer.start();
      digitalWrite(LED, LOW);
      Serial.println("playing"); 
  }

The intent appears to be that the else clause is associated with the if(isPlaying==true), but it isn’t. There’s an extra closing brace before the else.

When that’s resolved, notice that in both the if and the else, you set isPlaying to false, which doesn’t seem right.

Thank you! You are absolutely right on both counts.

now code reads:

{  if (digitalRead(buttonPause) == ACTIVATED)
   { if (isPlaying == true)
      myDFPlayer.pause();
      digitalWrite(LED, HIGH);
      isPlaying=false;
      Serial.println("paused");
      
 }else
    {
      if(isPlaying == false){
      myDFPlayer.start();
      digitalWrite(LED, LOW);
      isPlaying=true;
      Serial.println("playing"); 
  }

Now what happens is that the player starts in pause mode (which is actually OK and quite desirable) and nothing will happen until I press the button. The track will then play, but only while I'm holding the button down. Releasing the button puts me back into pause mode.

Resolved by changing momentary push switch to toggle, which actually will be easier for my Dad to operate. It now does everything it's supposed to!! Thank you Wildbill, much appreciated!

You should separate the processings of the button and of the player:

First read the button : when it is pushed, change the value of isPlaying

isPlaying = !isPlaying;

Then set the player according to the value of isPlaying.

Edit : I see you solved it. Good !

Even though this is solved, keep in mind that there are better DFPlayer libraries out there.

Power_Broker - Thank you, I will bear that in mind for any future DFPlayer projects.

lesept - Thank you, your solution is far more elegant than my own and again will be borne in mind for future projects.

Update: I delivered the finished product to my Dad this afternoon. He was absolutely delighted with it and I am informed that he is currently sitting listening to the latest Jack Reacher audiobook as we speak.

It's a great feeling knowing that I've built something that will allow him to 'read' once again and I'm thankful to the community here for giving me the answer I needed to complete the project (although a little embarrassed as to how simple that solution was!) - Thanks all.