TF-16P DFPlayer mini doesn't play on trigger

Hi
I have modified basic code from the library site:
https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#Connection_Diagram
by adding push-button and trigger play sound.
In the original code, everything seems to work fine (commented part in void loop), but my part (if (!digitalRead(sw1)) ) doesn't work.
It's connected to Arduino Nano, as a diagram from the library side plus additional one input and one output for LED, which lights when sw1 is pressed.
Mp3 files on SD card are correct and named in 0001.mp3 format, this works on original code.
I would be grateful for any help :face_with_monocle:

Serial monitor shows readVolume as -1, I can't find what this means, whole Serial monitor from boot below:

DFRobot DFPlayer Mini Demo
Initializing DFPlayer ... (May take 3~5 seconds)
DFPlayer Mini online.
-1
pressed button 1
3
-1

And the code is here:

/***********Notice and Trouble shooting***************
 1.Connection and Diagram can be found here
 <https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299#Connection_Diagram>
 ****************************************************/

//#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

int sw1 = 2;

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

void setup() {

  pinMode(sw1, INPUT_PULLUP);  //Define each button as input with pullup
  pinMode(4, OUTPUT);

  mySoftwareSerial.begin(9600);
  Serial.begin(9600);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial, false)) {  //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)
      ;
  }
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.volume(30);
  Serial.println(myDFPlayer.readVolume());
  myDFPlayer.play(1);  //Play the first mp3 ------------this doesn't work :(
}
//just a fucntion that we use to create delays in "ms" without using the delay() function
void waitMilliseconds(uint16_t msWait) {
  uint32_t start = millis();

  while ((millis() - start) < msWait) {
    // calling mp3.loop() periodically allows for notifications to be handled without interrupts -other library
    //myDFPlayer.enableLoop(); //enable loop. ??
    delay(1);
  }
}

void loop() {


  if (!digitalRead(sw1)) { // this doesn't work
    myDFPlayer.play(3);
    digitalWrite(4, HIGH);
    Serial.println(F("pressed button 1"));
    Serial.println(myDFPlayer.readVolume());
    Serial.println(myDFPlayer.readState());  //read mp3 state
    waitMilliseconds(1000);                  // 1s of delay
    digitalWrite(4, LOW);
  }


  // This works fine -plays all mp3 every 3 seconds
  /*
  static unsigned long timer = millis();
  if (millis() - timer > 3000) {
    timer = millis();
    myDFPlayer.next();  //Play next mp3 every 3 second.
   }

  if (myDFPlayer.available()) {
   printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
   } 
 */
}

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 DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      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;
  }
}

Your code will try to play song #3 every second if you hold that button down. You should look at the State Change Detection example in the IDE (File->examples->02.digital->State Change Detection) to learn how to detect when a button is pressed, not if a button is pressed.

Also, your waitMilliseconds() function is the same as delay() since the myDFPlayer.enableLoop() is commented out. I think that was the whole point of the function.

Thanks! @blh64
I've changed, what you said. I've applied change detection from an example and it works, reads every button state change.
However the main problem is still an issue, play command doesn't work either on the old reading and the new one. I've checked DFplayer state after play command by
Serial.println(myDFPlayer.readState());
and gives me -1, as below on Serial Monitor:

DFPlayer Mini online.
-1
**on**
**-1**
off

Any idea, what is going on?

new code below:

#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

const int  buttonPin = 2;
int buttonState = 0;         
int lastButtonState = 0;    

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

void setup() {

  pinMode(buttonPin, INPUT);  //Define each button as input with pullup
  pinMode(4, OUTPUT);

  mySoftwareSerial.begin(9600);
  Serial.begin(9600);
  
  if (!myDFPlayer.begin(mySoftwareSerial, false)) {  //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);
  }
  Serial.println(F("DFPlayer Mini online."));
  myDFPlayer.volume(30);
  Serial.println(myDFPlayer.readVolume());
  myDFPlayer.play(1);  //Play the first mp3 ------------this doesn't work :(
}

void loop() {
//This still doesn't work
buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      Serial.println("on");
      myDFPlayer.play(1);
      Serial.println(myDFPlayer.readState());
      digitalWrite(4, HIGH);
    } else {
      Serial.println("off");
      digitalWrite(4, LOW);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastButtonState = buttonState;
  
  // This works fine -plays all mp3 every 3 seconds
  /*
  static unsigned long timer = millis();
  if (millis() - timer > 3000) {
    timer = millis();
    myDFPlayer.next();  //Play next mp3 every 3 second.
   }

  if (myDFPlayer.available()) {
   printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
   } 
 */
}

It would appear your DFMiniplayer is not responding since you are getting -1 back when trying to read.

Personally, I'd switch libraries. There are several DFMini player libraries available within the Library Manager. Look for the FastDFMini or something similar and try out the examples.

1 Like

I've just isolated the problem.
That library plays only myDFPlayer.next(); command, any other play function gives error.
I'll try another library - Thanks a lot :+1: