0

I just played around using a MP3-TF-16P module, aka DFPlayer mini. The library and the examples I used as a basis can be found here.

My current setup contains a button (NC, normally closed), which is connected to Pin D2 and has an interrupted attached to it. The button input is debounced by using a time difference inside the ISR. The code (based on getStarted example) can be found below.

Using the button to play the next song works as expected. However, when trying to get the total number of tracks located on the SD card by calling Serial.println(player.readFileCounts()) as shown in the FullFunction example the board does neither print anything nor respond to any further commands. Even using the FullFunction example does not print anything.

Could someone please double-check this behaviour? Is this a module-related ore a library-related problem, since I am using a MP3-FT-16P module which might be a cheap clone of the original DFPlayer mini module? Does this work with other MP3-FT-16P modules out there meaning that mine is faulty?

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

#define interruptPin 2
#define softSerialRx 10
#define softSerialTx 11
#define debounceDelayMillis 1000


volatile uint32_t lastInterruptTime = 0;
volatile bool interruptOccured = false;

SoftwareSerial softSerial(softSerialRx, softSerialTx);
DFRobotDFPlayerMini player;


void setup() {
  softSerial.begin(9600);
  Serial.begin(115200);

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, FALLING);

  Serial.println(F("Initing player ..."));
  // `player.begin(stream)` returns true when module is initialized
  if (!player.begin(softSerial)) {
    Serial.println(F("... failed"));
    while(true) {
      // never leave this loop since initialization went wrong
    }
  }
  Serial.println(F("... ready."));

  // volume: 0 ... 30
  player.volume(30);

  // when using `player.readFileCounts()` player module does not respond to further commands
  // Serial.println(player.readFileCounts());
}


void loop() {
  // read status messages from DFPlayerMini on its software serial port when available
  if (player.available()) {
    printPlayerStatus(player.readType(), player.read());
  }

  if (interruptOccured) {
    Serial.println("Button pressed");
    player.next();
    interruptOccured = false;
  }
}


void interruptHandler() {
 uint32_t interruptTime = millis();
 if (interruptTime - lastInterruptTime > debounceDelayMillis) {
   interruptOccured = true;
 }
 lastInterruptTime = interruptTime;
}


void printPlayerStatus(uint8_t type, uint16_t 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;
  }
}
2

These DFPlayer modules are more difficult to drive than the examples suggest. Whenever you send a command to the DFPlayer (such as player.setVolume(30)) the module will return some sort of acknowledgement or a status command. You need to be calling the player.available() method and then player.readType() and player.read() continually in loop() to keep the SoftwareSerial buffer free before you try sending commands. So calling player.setVolume(30) and then player.readFileCounts() in setup() may be overfilling the buffer before you start clearing it and the buffer will contain unread messages that are not the expected file count reply thus confusing the library. The other thing to consider is that it takes the module a second or two to initialise the SD card after .begin() and you really need to wait for the DFPlayerCardOnline status message to come in before you can ask for file counts.

I've written a more comprehensive library to drive these but it's not mature enough to share yet.

  • Tried to implement your suggestions, but without any success. Do you have some similar hardware available in order to try my code with your suggestions added to it? – albert Jul 1 '18 at 16:11
0

OK... For those who are looking for the answer, I found it in a complicated way, reading the library file. When the begin() task is executed, within the parameters, the COM port is required, but two more parameters are also allowed: ACK and doReset. Then begin(com_player, false, true); the ACK parameter blocks the responses of the serial parse.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.