Giter Club home page Giter Club logo

dfplayermini_fast's Introduction

DFPlayer Mini Fast

GitHub version arduino-library-badge

Fast and easy to understand Arduino library to use the DFPlayer Mini MP3 module from DFRobot.com. This is a huge improvement (both in terms of execution speed and simplicity) to the standard library provided by DFRobot.com.

> See the documentation <

Important Notes

If you use the playFromMP3Folder() or playAdvertisement() functions, the files to be played must be organised in an extremely precise manner. The "MP3 Folder" must be in the root of the storage device (such as a MicroSD card) and it must be called "mp3". The folder name is probably not case-sensitive. Likewise, the "Advertisement" folder used for short interruptions to main audio playback must also be in the root of the storage device, and it must be called "advert". In addition, audio filenames must be prepended by a zero-padded 4-digit number if the files are in the root or "mp3" folders. If the files are played from folders other than root or "mp3", the folder names must be zero-padded 2-digit numbers while their contents must be audio files with names prepended by a zero-padded 3-digit number.

If you are using multiple DFPlayers with SoftwareSerial, it is necessary to make your SoftwareSerial instance listen (i.e. SoftwareSerial.listen()) before calling queries such as .isPlaying() or .currentVolume().

Library API:

bool begin(Stream& stream, bool debug, unsigned long threshold=100);

void playNext();
void playPrevious();
void play(uint16_t trackNum);
void stop();
void playFromMP3Folder(uint16_t trackNum);
void playAdvertisement(uint16_t trackNum);
void stopAdvertisement();
void incVolume();
void decVolume();
void volume(uint8_t volume);
void EQSelect(uint8_t setting);
void loop(uint16_t trackNum);
void playbackSource(uint8_t source);
void standbyMode();
void normalMode();
void reset();
void resume();
void pause();
void playFolder(uint8_t folderNum, uint8_t trackNum);
void playLargeFolder(uint8_t folderNum, uint16_t trackNum);
void volumeAdjustSet(uint8_t gain);
void startRepeatPlay();
void stopRepeatPlay();
void repeatFolder(uint16_t folder);
void randomAll();
void startRepeat();
void stopRepeat();
void startDAC();
void stopDAC();
void sleep();
void wakeUp();

bool isPlaying();
int16_t currentVolume();
int16_t currentEQ();
int16_t currentMode();
int16_t currentVersion();
int16_t numUsbTracks();
int16_t numSdTracks();
int16_t numFlashTracks();
int16_t currentUsbTrack();
int16_t currentSdTrack();
int16_t currentFlashTrack();
int16_t numTracksInFolder(uint8_t folder);
int16_t numFolders();

void setTimeout(unsigned long threshold);
void findChecksum(stack& _stack);
void sendData();
void flush();
int16_t query(uint8_t cmd, uint8_t msb=0, uint8_t lsb=0);
bool parseFeedback();

void printStack(stack _stack);
void printError();

DFPlayer Mini Pinout:

550px-Miniplayer_pin_map

DFPlayer Mini Pin Description:

Pin_map_desc_en

Example Wiring Diagram:

550px-PlayerMini

For more info: https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299

dfplayermini_fast's People

Contributors

jandelgado avatar kshoichi avatar powerbroker2 avatar ultravioletnanokitty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dfplayermini_fast's Issues

playFolder don´t play, but playNext work

Hello!
Please. I wold like to know if the instructions to make SD folders still valid at this form:

 Pasta de E:\01

26/02/2020  18:35    <DIR>          .
26/02/2020  18:35    <DIR>          ..
19/12/2016  20:25           126.967 0000.mp3
30/11/2016  09:38            86.738 0001.mp3
30/11/2016  09:42            91.426 0002.mp3
30/11/2016  09:46            78.960 0003.mp3
20/12/2016  18:58            99.307 0004.mp3
20/12/2016  19:01           172.487 0005.mp3
30/11/2016  12:43           167.056 0006.mp3
30/11/2016  09:44            87.566 0007.mp3
20/12/2016  19:02           153.182 0008.mp3
30/11/2016  10:09            90.980 0009.mp3
07/11/2016  14:18            93.207 0010.mp3
20/12/2016  19:05            93.740 0011.mp3
20/12/2016  19:06            81.500 0012.mp3
20/12/2016  19:09            68.231 0013.mp3
20/12/2016  19:11           107.460 0014.mp3
20/12/2016  19:16            72.587 0015.mp3
20/12/2016  19:15           114.659 0016.mp3
31/12/2016  19:58           283.143 0017.mp3
12/01/2017  13:46           166.137 0018.mp3
22/12/2016  20:36           514.161 0019.mp3
              20 arquivo(s)      2.749.494 bytes
               2 pasta(s)    7.902.806.016 bytes disponíveis

because, this Works,

//***********************************************
SoftwareSerial    mySerial(-1, 2);
//***********************************************
//****************************************************************************/
void setup()
//****************************************************************************/
{
 //*********************************************** 
  mySerial.begin(9600);
  myDFPlayer.begin(mySerial);
  //***********************************************
  //***********************************************
  myDFPlayer.playNext();
  delay(2000);
  //***********************************************

but, this is ignored, and don´t play..

//***********************************************
SoftwareSerial    mySerial(-1, 2);
//***********************************************
//****************************************************************************/
void setup()
//****************************************************************************/
{
 //*********************************************** 
  mySerial.begin(9600);
  myDFPlayer.begin(mySerial);
  //***********************************************
  //***********************************************
  myDFPlayer.playFolder(1, 0);
  delay(2000);
  //***********************************************

I have ESP8266 and last lib. Please, what may be wrong here?
I am use 0000.mp3 and folder 01 names..

Can't play songs in correct order

Hello, thanks for the great tool!
I'm having some issues playing the songs in the correct order. I've ordered the songs per the screenshot below, all in the root directory of the SD card. You can see the timestamp of date creation too, if that is relevant.
Screenshot 2022-04-29 at 21 18 41

In my code below, I simply loop through all the ints 0-15 and and play the relevant song. However, the songs play in this order (wrong order, some repeat, and some dont play at all):
0004
0004
0012
0015
0013
0004
0000
0003
0005
0006
0010
0008
0009
0010

Im using the following code with the following debug trace. Any ideas? Thank you!

// audio player
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFPlayerMini_Fast.h"

SoftwareSerial mySoftwareSerial(4, 5); // RX, TX
DFPlayerMini_Fast DFPlayer;


void play_song() {
  for (int i = 0; i < 15; i++) {
    Serial.print("setting new idx: "); Serial.println(i);
    delay(500);
    DFPlayer.stop();
    delay(500);
    DFPlayer.play(i);
    delay(3000);
  }
}

void setup() {
  Serial.begin(9600);
  mySoftwareSerial.begin(9600);
  Serial.print("Initializing DFPlayer");
  while (!DFPlayer.begin(mySoftwareSerial, true)) {
    delay(500); Serial.print(".");
  }
  Serial.println(" DFPlayer Mini online!");
  DFPlayer.volume(20);  //Set volume value. From 0 to 30
  DFPlayer.setTimeout(2000);
  Serial.println("Ready for action!");
}


void loop() {
  play_song();
}
14:50.096 -> Sent Stack:
21:14:50.096 -> 7E FF 6 16 0 0 0 FE E5 EF
21:14:50.131 -> 
21:14:50.616 -> Sent Stack:
21:14:50.616 -> 7E FF 6 3 0 0 0 FE F8 EF
21:14:50.616 -> 
21:14:53.621 -> setting new idx: 1
21:14:54.126 -> Sent Stack:
21:14:54.126 -> 7E FF 6 16 0 0 0 FE E5 EF
21:14:54.126 -> 
21:14:54.654 -> Sent Stack:
21:14:54.654 -> 7E FF 6 3 0 0 1 FE F7 EF
21:14:54.654 -> 
21:14:57.637 -> setting new idx: 2
21:14:58.148 -> Sent Stack:
21:14:58.148 -> 7E FF 6 16 0 0 0 FE E5 EF
21:14:58.148 -> 
21:14:58.660 -> Sent Stack:
21:14:58.660 -> 7E FF 6 3 0 0 2 FE F6 EF
21:14:58.660 -> 
21:15:01.652 -> setting new idx: 3
21:15:02.163 -> Sent Stack:
21:15:02.163 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:02.246 -> 
21:15:02.675 -> Sent Stack:
21:15:02.675 -> 7E FF 6 3 0 0 3 FE F5 EF
21:15:02.753 -> 
21:15:05.666 -> setting new idx: 4
21:15:06.175 -> Sent Stack:
21:15:06.175 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:06.260 -> 
21:15:06.685 -> Sent Stack:
21:15:06.685 -> 7E FF 6 3 0 0 4 FE F4 EF
21:15:06.774 -> 
21:15:09.676 -> setting new idx: 5
21:15:10.218 -> Sent Stack:
21:15:10.218 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:10.218 -> 
21:15:10.728 -> Sent Stack:
21:15:10.728 -> 7E FF 6 3 0 0 5 FE F3 EF
21:15:10.728 -> 
21:15:13.721 -> setting new idx: 6
21:15:14.231 -> Sent Stack:
21:15:14.231 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:14.231 -> 
21:15:14.741 -> Sent Stack:
21:15:14.741 -> 7E FF 6 3 0 0 6 FE F2 EF
21:15:14.741 -> 
21:15:17.722 -> setting new idx: 7
21:15:18.269 -> Sent Stack:
21:15:18.269 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:18.269 -> 
21:15:18.755 -> Sent Stack:
21:15:18.755 -> 7E FF 6 3 0 0 7 FE F1 EF
21:15:18.789 -> 
21:15:21.743 -> setting new idx: 8
21:15:22.294 -> Sent Stack:
21:15:22.294 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:22.294 -> 
21:15:22.780 -> Sent Stack:
21:15:22.780 -> 7E FF 6 3 0 0 8 FE F0 EF
21:15:22.813 -> 
21:15:25.795 -> setting new idx: 9
21:15:26.309 -> Sent Stack:
21:15:26.309 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:26.309 -> 
21:15:26.823 -> Sent Stack:
21:15:26.823 -> 7E FF 6 3 0 0 9 FE EF EF
21:15:26.823 -> 
21:15:29.788 -> setting new idx: 10
21:15:30.301 -> Sent Stack:
21:15:30.301 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:30.335 -> 
21:15:30.849 -> Sent Stack:
21:15:30.849 -> 7E FF 6 3 0 0 A FE EE EF
21:15:30.849 -> 
21:15:33.820 -> setting new idx: 11
21:15:34.331 -> Sent Stack:
21:15:34.331 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:34.369 -> 
21:15:34.842 -> Sent Stack:
21:15:34.842 -> 7E FF 6 3 0 0 B FE ED EF
21:15:34.880 -> 
21:15:37.847 -> setting new idx: 12
21:15:38.357 -> Sent Stack:
21:15:38.357 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:38.357 -> 
21:15:38.875 -> Sent Stack:
21:15:38.875 -> 7E FF 6 3 0 0 C FE EC EF
21:15:38.875 -> 
21:15:41.881 -> setting new idx: 13
21:15:42.398 -> Sent Stack:
21:15:42.398 -> 7E FF 6 16 0 0 0 FE E5 EF
21:15:42.398 -> 
21:15:42.893 -> Sent Stack:
21:15:42.893 -> 7E FF 6 3 0 0 D FE EB EF
21:15:42.893 -> 
21:15:45.870 -> setting new idx: 14
21:15:46.419 -> Sent Stack:
21:15:46.419 -> 7E FF 6 16 0 0 0 FE E5 EF

Start Track at Certain Time

Does the lib have functions to start a track at a certain time and play a track for a certain time?

playTrackAt(5, 3500); // Start Track 5 at 3500ms
playTrackAt(5, 3500, 3000); // Start Track 5 at 3500ms and play it for 3000ms

Number of tracks in the "MP3" folder

Hi,

Just like the function to get the number of tracks from a "numbered" folder ( int16_t numTracksInFolder(uint8_t folder); ), is there a way to get the number of tracks BUT from the folder named "MP3" or "mp3" ?
From documentation the "numTracksInFolder" can only use an integer from 0 to 255.

My intention is to play a random track from the "mp3" folder (and not from a numbered folder nor from the root)

example of usage:

void playRandomSongFromMp3Folder () {
long randomInt;
nbTracksMP3 = myMp3.numTracksInFolder('MP3'); // will not work !
randomInt = random(nbTracksMP3);
myMp3.playFromMP3Folder(randomInt);
}

-> Is there a trick to use the "numTracksInFolder" function for that, or does it need to implement a new dedicated function ?

Thanks.

Thank-you PowerBroker2! - Im using this to send DTMF/touch tones

Huge thanks for you work on this.
I have used your library for quickly creating a DTMF encoder/generator. Its fast enough to be able to play the tones I need for my IOT over radio project with the decoder module MT8870.
I am using tones downloaded from here:
https://www.audiocheck.net/audiocheck_dtmf.php
and playing 8K wav files perfectly with the DFplayer module.
And off course I have the added option to play voice announcements and other control tones such as ANI and maybe even 1200 bell packets..

Example not working for me

What should I hear when I run your example please?
https://github.com/PowerBroker2/DFPlayerMini_Fast/blob/master/examples/example/example.ino

I expected a constant repetition of the first track on my SD card, 0001.mp3, but I get nothing.

Meanwhile I made the minor edit shown below, adding two Play commands to the previously empty loop, and reducing the volume to 5 instead of 30. Why does that not change the volume? And why only repeating track 1 and not playing track 2?

Is there another example that reliably delivers audio and perhaps shows more functions please?

`#include <DFPlayerMini_Fast.h>

#if !defined(UBRR1H)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
#endif

DFPlayerMini_Fast myMP3;

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

#if !defined(UBRR1H)
mySerial.begin(9600);
myMP3.begin(mySerial, true);
#else
Serial1.begin(9600);
myMP3.begin(Serial1, true);
#endif

delay(1000);

Serial.println("Setting volume to max");
myMP3.volume(5);

Serial.println("Looping track 1");
myMP3.loop(1);

}

void loop()
{
myMP3.play(1);
delay(100);

while (myMP3.isPlaying())
{
//do nothing
}

myMP3.play(2);
while (myMP3.isPlaying())
{
//do nothing
}

}`

DFPlayer mini with different chip

Hi,

i have multiple version dfplayer mini with different decoder chip (AC20BXXXX...), when using with this library the other than the original DFplayer (AA19XXX..) can receive tx command (play/pause/stop) but did not transmit on rx such as volume and track number. is there any way i could debug the code and insert new type of byte code to use with different DF player version? how can i start?

thanks @PowerBroker2

Checksum calculation

I've tried to use you library and failed. For example playFromMP3Folder() or playTrackFromFolder() doesn't work. The problem is in findChecksum(). To fix it:

  1. Replace all sendStack.paramLSB = 1; with sendStack.paramLSB = 0; in DFPlayerMini_Fast.cpp
  2. Change findChecksum() code to this
void DFPlayer::findChecksum(stack& _stack)
{
  int16_t checksum = 0 - (_stack.version + _stack.length + _stack.commandValue + _stack.feedbackValue + _stack.paramMSB + _stack.paramLSB);

  _stack.checksumMSB = checksum >> 8;
  _stack.checksumLSB = checksum & 0x00FF;
}

Volume command not working

I can't get the volume command on my dfplayer to work.
My current main loop is

void loop() {
  static unsigned long timer = millis();
  if (millis() - timer > 3000) {
    timer = millis();
     delay(30);
     myDFPlayer.volume(5);
     mySerial.flush();
     delay(500);
     Serial.println(myDFPlayer.currentVolume());
     Serial.println(F("playing next"));
    myDFPlayer.randomAll();  //Play next mp3 every 3 second.
  }

It does play a random different mp3 every few seconds but at full volume. Also the call to currentVolume (inserted as diagnostic) returns -1.

Also if I replace the call to randomAll() with playNext() nothing plays.

My files are /mp3/001.mp3, /mp3/002.mp3, /mp3/003.mp3

numTracksInFolder return value if folder empty

what is the intended return value if the folder does not contain any mp3?

for testing purposes, i left the folder 05 empty, but numTracksInFolder(5) return 6 somehow.

i'm using the following code to keep track of how many songs are in each playlist:

    const int playlistLimit = 10; 
    int16_t  folderCount[playlistLimit];

    for (byte i = 0; i < playlistLimit; i += 1) {
        folderCount[i] = DFP.numTracksInFolder(i+1); 
        Serial.print(F("Playlist "));
        Serial.print(i+1);
        Serial.print(F(" contains"));
        Serial.print(folderCount[i]);
        Serial.println(F(" songs"));
    }

What am i missing?

Using the busy pin never seems to work

Not too sure whats going on but I've had this working before on another project but right now it seems to be buggy.

Simply trying reading in PIN_16 or the busy pin to check to see if anything is currently playing before starting an idle track just keeps trying to put the idle track in an endless loop. When I check the serial inputs I see the correct inputs when something is playing but when I run this simple code to check I see inputs flippings from 0,1 over and over again. I figure play this track if there is nothing else playing and it should work... Is there something I am missing?

Thanks!

    if (digitalRead(ISPLAYING_OUT) == true)
    {
      myDFPlayer.loop(idleTrack);
    }

.volume() doesn’t send data on first call unless debug interface is turned on

This is a really strange bug I'm experiencing. I have my code set up to read a potentiometer value for the volume. It checks the volume every x milliseconds in the loop() function, as well as one time immediately after the DFPlayer is initialized in the setup() function.

For some reason, the initial volume setting doesn't occur unless I have the debug interface set to true when I initialize the DFPlayer. If it set it to false, it stops working. Subsequent calls to the volume() command do work.

Because I'm keeping track of the current volume and only sending volume() commands when the volume changes, the result is that the volume will be incorrect until I turn the potentiometer, at which point the player volume jumps to the correct setting. I confirmed that the code is being reached, because there I print a message to the Serial buffer in the lines immediately before and after the volume() call.

isPlaying() always returns 0 when multiple instances are active

Other functions such as .volume, .play, and .stop all work fine with multiple instances. Tested and confirmed using this code:

#include "Arduino.h"
#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>

//audio hardware
SoftwareSerial mySerial1(A0, A1); // RX, TX
SoftwareSerial mySerial2(A2, A3); // RX, TX
SoftwareSerial mySerial3(2, 3); // RX, TX
SoftwareSerial mySerial4(4, 5); // RX, TX
DFPlayerMini_Fast DFP1;
//DFPlayerMini_Fast DFP2;
//DFPlayerMini_Fast DFP3;
//DFPlayerMini_Fast DFP4;

void setup()
{
  Serial.begin(115200); 
  Serial.println(F("Booting Up..."));
  Serial.println(F("Init mySerial 1"));
  mySerial1.begin(9600);
  //mySerial2.begin(9600);
  //mySerial3.begin(9600);
  //mySerial4.begin(9600);

  DFP1.begin(mySerial1);
  //DFP2.begin(mySerial2);
  //DFP3.begin(mySerial3);
  //DFP4.begin(mySerial4);
  DFP1.play(1); 
}


void loop()
{
  Serial.println(DFP1.isPlaying());  
}

Volume won't change

I'm using the library with a DFPlayer Mini module and an Arduino Nano. It is a clone, but unlike some does respond to serial commands. I am not able to lower the volume using the simple sketch below. I tried adding a 10MS delay before the volume change as mentioned in one of the other issues concerning this, but that didn't work. The module responds to other commands just fine. Any ideas? The module works fine with other libraries including the official DFRobot library. Here is my serial monitor output:

Setting volume to 4
Sent Stack:
7E FF 6 6 0 0 4 FE F1 EF

playtrack 1
Sent Stack:
7E FF 6 3 0 0 1 FE F7 EF

And the code:

#include <DFPlayerMini_Fast.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

DFPlayerMini_Fast myMP3;

void setup()
{
  Serial.begin(9400);

  mySerial.begin(9600);
  myMP3.begin(mySerial, true);
  
  Serial.println("Setting volume to 4");
delay(10);
myMP3.volume(4);
  
  Serial.println("playtrack 1");
  myMP3.play(1);
}

play the second music after the first music is finished

Hello, I want the second music to play after the first music plays completely under one condition. How can I do that?

I have one more question. I have two buttons and when I press the first button I want to play the first music and when I press the second button I want to mute the first music and play the second song.

if (verilerim[0] == 1 && !player.isPlaying()) {
player.play(1);
delay(100);
player.play(2);
} else if (verilerim[1] == 1 && player.isPlaying()){
player.play(1);
stop();
player.play(3);
}

Play files in a folder randomly

Thanks for this library!

Is it possible to randomly play the content of a specific folder?
I currently have this, but maybe there is an easier way:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include <DFPlayerMini_Fast.h>
int currentFolder = 0;
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFPlayerMini_Fast MP3_player;
void setup(){
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  //Initialize a a randomseed for the random number generator
  randomSeed(analogRead(0));
}
void loop(){
  playFolder(6);
  if(MP3_player.isPlaying()){
    Serial.print("Currently playing track");
    Serial.println(MP3_player.currentSdTrack());
  }else if (currentFolder != 0){
    //If playing is over and playing a folder, play the next random track
    playFolder(currentFolder);
  }
  delay(1000);
}
void playFolder(int folder){
  currentFolder = folder;
  int folderSize = MP3_player.numTracksInFolder(folder);
  MP3_player.playFolder(folder, random(1,folderSize+1));
}

return -1 in numSdTracks()

Hi!

I'm trying to play a track but when I start the program it returns "-1" in the number of tracks. On the sdcard is the folder "mp3" with the files renamed to "0001.mp3, 0002.mp3" and so on.

Using the original library(https://github.com/DFRobot/DFRobotDFPlayerMini) I get the same value as "-1" but as I go forward the tracks are played.

Does anyone know what can it be?

#include <DFPlayerMini_Fast.h>
#include <Arduino.h>


HardwareSerial mySerial(1);
DFPlayerMini_Fast myMP3;

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

#if !defined(UBRR1H)
  mySerial.begin(9600, SERIAL_8N1, 18, 19);
  myMP3.begin(mySerial, true);
#else
  Serial1.begin(9600);
  myMP3.begin(Serial1, true);
#endif
  delay(1000);
  myMP3.setTimeout(1000);
  Serial.print(F("File found in SD: "));
  Serial.println(myMP3.numSdTracks());
  Serial.println("Setting volume to max");
  myMP3.volume(10);
  myMP3.playFromMP3Folder(1);
  delay(5000);
  Serial.println("Looping track 1");
  myMP3.loop(1);
}

void loop()
{
  char choice = Serial.read();
    if (choice == 'a')
  {
    Serial.println("---Advance---");
    myMP3.playNext();
    Serial.print(myMP3.currentSdTrack());
    Serial.print('/');
    Serial.println(myMP3.numSdTracks());
  }
}

playFolder not working

playFolder function is not working. All other functions such as playRandom work. I have 3 folders on the SD (01, 02, 03) and 112 MP3s in each folder (0001 to 0112). Fat 32 file, all formatted correctly IAW DFplayer instructions. Am I mission something? I simplified the code for inclusion below:

#include <arduino.h>
#include <DFPlayerMini_Fast.h>
#if !defined(UBRR1H)
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
#endif
DFPlayerMini_Fast myMP3;
const byte pinDfpBusy = 12;  

void setup()
{
  Serial.begin(115200);
  Serial.begin(9600);
 
#if !defined(UBRR1H)
  mySerial.begin(9600);
  myMP3.begin(mySerial);
#else
  Serial.begin(9600);
  myMP3.begin(Serial1);
#endif
  
  myMP3.volume(20);
  delay(5); 

  myMP3.playFolder (1,2)
}

void loop()
{
  
}

What' the purpose of startDAC() and stopDAC() methods?

If I will use an amplifier (PAM8406, for example) with the DFPlayer. I'll use the DAC_R pin (in mono mode) instead of SPK+ and SPK- pins.
What's the difference between running the DFPlayer with an amplifier without calling startDAC() in the code and running the DFPlayer with an amplifier with calling startDAC() in the code?

function isPlaying not working.

Hey there. Thanks a lot for the library!

I currently have a project that queues music automatically when an RFID card is tapped (edit: and it's non blocking, so it allows scans even though a music is currently playing). When the song currently playing is finished, the next music in queue will be played.

I tried using the DFRobotDFPlayerMini library, used the readType function to check whether the DFPlayer has finished playing, but the results are not accurate, making the program fail.

When googling around, I found out that your library has a isPlaying function that should check whether a song is currently being played, and so I tried using your library, it worked fine in terms of playing music, but the isPlaying function isn't working (always returns false / 0) even though a music is currently playing.

Here's my sketch:

LiquidCrystal_I2C lcd(0x27, 16, 2);

bool firstPlay = false;

QueueDFPlayer QMusic;

HardwareSerial hwSerial(1);

DFPlayerMini_Fast myMP3Player;

const char* wifiName = “SSID”;
const char* wifiPass = “PASS”;

RFID rfid(SS_PIN, RST_PIN);

void setup() {

  hwSerial.begin(9600, SERIAL_8N1, DFPLAYER_TX, DFPLAYER_RX);  // speed, type, TX, RX
  Serial.begin(115200);

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

  SPI.begin();
  rfid.init();

  pinMode(LED_PIN, OUTPUT);

  lcd.clear();

  lcd.begin();

  lcd.backlight();

  if (!myMP3Player.begin(hwSerial)) {
    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(("DFPlayer Mini online."));

  myMP3Player.setTimeout(500); //Set serial communictaion time out 500ms

  myMP3Player.volume(30);

  Serial.println();

  Serial.print("Connecting to ");
  Serial.println(wifiName);

  lcd.setCursor(1, 0);
  lcd.print("Initialization");
  lcd.setCursor(2, 1);
  lcd.print("Connecting...");

  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(wifiName, wifiPass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());   //You can get IP address assigned to ESP
}

void loop() {

  if (ModeAlat != "SCAN")
    return;

  rfid.halt();

  digitalWrite(LED_PIN, HIGH);
  delay(500);
  digitalWrite(LED_PIN, LOW);
  
  int tPlayMusic = 0;

  Serial.print("Is Playing State: ");
  Serial.println(myMP3Player.isPlaying());

  if (!myMP3Player.isPlaying()) {
    tPlayMusic = QMusic.getMusic();
    if (tPlayMusic != 0)
      myMP3Player.playFromMP3Folder(tPlayMusic);
  } else {
    Serial.print("Is Playing State: ");
    Serial.println(myMP3Player.isPlaying());
  }


  if (!rfid.isCard() || !rfid.readCardSerial()) {
    lcd.setCursor(0, 0);
    lcd.print("System Available");
    lcd.setCursor(0, 1);
    lcd.print("Scan your card>>");
    return;
  }

  digitalWrite(LED_PIN, HIGH);

  Serial.println("Card found");

  String RFID = String(rfid.serNum[0], HEX) + "-" + String(rfid.serNum[1], HEX) + "-" + String(rfid.serNum[2], HEX) + "-" + String(rfid.serNum[3], HEX) + "-" + String(rfid.serNum[4], HEX);

  tone(Buzzer, NOTE_E7, 100, BUZZER_CHANNEL);

  Serial.print("RFID: ");
  Serial.println(RFID);
  Serial.println("");

  String host = hostSCAN;
  host += "&rfid=";
  host += RFID;
  HTTPClient https;
  Serial.print("Request Link:");
  Serial.println(host);
  Serial.println("");

  https.begin(host);

  int httpCode = https.GET();            //Send the GET request
  String payload = https.getString();    //Get the response payload from server

  https.end();

  Serial.print("Response Code:"); //200 is OK
  Serial.println(httpCode);       //Print HTTP return code
  Serial.println("");

  Serial.print("Returned data from Server: ");
  Serial.println(payload);    //Print request response payload
  Serial.println("");

  if (httpCode != 200) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Dismissal System");
    lcd.setCursor(0, 1);
    lcd.print("HTTP: " + httpCode);
    return;
  }

  DynamicJsonDocument doc(1024);

  auto error = deserializeJson(doc, payload);

  if (error) {
    Serial.print(F("deserializeJson() failed with code "));
    Serial.println(error.c_str());
    return;
  }

  String responStatus = doc["status"].as<String>();
  String responKeterangan = doc["ket"].as<String>();
  String responNama = doc["nama"].as<String>();
  String responMusic = doc["music_file"].as<String>();

  Serial.println();
  Serial.print("Status: ");
  Serial.println(responStatus);

  Serial.print("Keterangan: ");
  Serial.println(responKeterangan);

  Serial.print("Name: ");
  Serial.println(responNama);

  Serial.print("Music File No.: ");
  Serial.println(responMusic);

  Serial.println("-------------------");
  Serial.println();

  tone(Buzzer, NOTE_E7, 100, BUZZER_CHANNEL);
  delay(80);
  noTone(Buzzer, BUZZER_CHANNEL);
  tone(Buzzer, NOTE_E7, 100, BUZZER_CHANNEL);

  if (responStatus != "success") {
    lcd.clear();
    lcd.print("Please register");
    lcd.setCursor(2, 1);
    lcd.print("an account.");
    return;
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Please wait.....");
  lcd.setCursor(0, 1);
  lcd.print("Calling " + responNama);

  int music_file = atoi(responMusic.c_str());
  
  Serial.print("Music retrieved from database: ");
  Serial.println(music_file);

  int playMusic = 0;
  if (!myMP3Player.isPlaying()) {
    QMusic.addMusic(music_file);
    playMusic = QMusic.getMusic();
    if (playMusic != 0)
      myMP3Player.playFromMP3Folder(playMusic);
  } else {
    Serial.print("Is Playing State: ");
    Serial.println(myMP3Player.isPlaying());
    QMusic.addMusic(music_file);
  }    
  Serial.println("Scan another card.");

  delay(1000);
  
}

An image of the problem: https://imgur.com/a/gAxSzfb

Any help is appreciated.

Read files from SPI Flash

Hi, first, thanks for the nice work done on the library. I've tested it with the DFPlayer and your library worked better than the original one.

I have a project in mind, that needs do fit in a very narrow piece, where the Dfplayer wont fit.

Do you think your library could be able to read the wav files from a SPI Flash (like winbond chips)? I'm looking for various libraries and projects using arduino and struggling to get it running nice.

Thanks in advance

DFPlayer mini volume level in all new chipsets

Hi PowerBroker, I just wanted to share what I figured out with the volume setting. With all these new chipsets coming out, I was unable to set the volume level in software and which you helped me work on a few months ago. I solved the issue, just increased the delay after the mp3.begin() in the setup from my 20ms to 1000 and now the volume is working again! Just wanted to share and say thank you for all your help too!

void setup() {
Serial.begin(9600);
mySerial.begin(9600);
myMP3.begin(mySerial);
delay(1000);
myMP3.volume(SPEAKER_VOLUME);
}

.volume() function not working at all, always set to the highest level

I have tried 5 different brands of mp3 dfmini players and now just in the past few weeks, I have noticed that after uploading to the arduino and playing sounds, the sounds is always at the highest volume. The volume() function is almost ignored now. I even set delays before and after setting the volume and nothing, always plays any mp3 at the highest level distorting sound. Just a few weeks ago, been using .volume(24) and working fine. Even tried setting the volume to 10, still no change in volume. Any ideas what is going on with the DFPLAYER MINI FAST library? Does not seem to matter which mp3 player, the volume is always maxed out, so it looks to be a software bug. Thank you!

Lag and sound cut produced after library update

Hi @PowerBroker2 ,

I encounter lagged and sound cut on the latest lib update running on esp32. The player seems to stop from doing its current task when getting other play request concurrently. Not have this issue on the previous version.
I have add timers to reduce the call, do the pin busy check but still getting the issue once the timer countdown ends.

Thank you

query() not working

At least on the noname DFPlayer I have, the query() method always returns -1. I found two problems:

  1. The recChar variable in parseFeedback() needs to be an uint8_t (or unsigned char, obviously) for the state machine to get anywhere since VER=0xFF
  2. The 'cmd' parameter in the call to getStatus() within query() needs to be dfplayer::REPLY - clearly, the received response stack uses 0x41 as the cmd value.

Setting the volume is not working correctly

Setting the volume to 10 and then retrieving the volume shows it has been set to 24, the sound is also not reduced in volume. I'm using an ESP32 with hardware serial port on non-default pins (16,4). I have used other libraries (DFRobotDFPlayerMini) and they work setting the volume. Any chance you could have a look. Thanks John.

#include <Arduino.h>
#include <DFPlayerMini_Fast.h>

DFPlayerMini_Fast myMP3;

#define DFPLAYER_RX 16
#define DFPLAYER_TX 4

void setup()
{
  Serial.begin(115200); //ESP32 USB Port
  Serial.flush();

  Serial1.begin(9600, SERIAL_8N1, DFPLAYER_RX, DFPLAYER_TX);

  myMP3.begin(Serial1,750);

  if (!myMP3.begin(Serial1))
  {
    Serial.println("DFPlayer error");

    delay(1000);
    ESP.restart();
  }

  myMP3.volume(10);
  delay(30);

  int16_t v = myMP3.currentVolume();

  Serial.print("Volume:");
  Serial.println(v);

  int16_t fileCounts = myMP3.numSdTracks();

  if (fileCounts == -1)
  {
    Serial.println("DFPlayer no files found");

    delay(1000);
    ESP.restart();
  }
  else
  {
    Serial.print("Found ");
    Serial.print(fileCounts);
    Serial.println(" files");
  }

  //play the mp3
  myMP3.play(random(1, 10));
}

void loop()
{
}

Provide example of querying commands

Would it be possible to provide an example of the query commands? How to use query, getStatus, parseFeedback, printStack?

Thanks for the awesome library. I tried using the DFRobots library, but I couldn't get it to reliably detect when a track had stopped. I'm hoping this library will be able to. #

Get list of files or count files

I have an Arduino with two buttons connected. The first button selects a file and the second button plays the currently selected file.

At the moment the button increases the value of a variable whenever it is pressed. For example:

int selectedSong = 1;

selectSongButtonState = digitalRead(selectSongButton);
if (selectSongButtonState == HIGH) {
  selectedSong++;
}

playSongButtonState = digitalRead(playSongButton);
if (playSongButtonState == HIGH) {
  dfPlayer.play(selectedSong);
}

But I don't know how many files are stored on the SD card. So let's say there are only 3 files. In that case, whenever the first button is pressed, the selectedSong variable needs to be increased until it reaches a value of 3 then it needs to start at 1 again.

Is there a way to find out how many files there currently are?

Play specific tracks one after another without delay

Thanks for your help with my volume issue. I now have that working but there is one more thing I'm struggling with. I need to play specific files one after another, without a delay but without the files being cut off. I've tried using isPlaying but I can't seem to figure this out. The busy pin would be an ideal solution but there is a time delay between the player stopping and the pin status changing. Essentially, I want to be able to:

mp3.play(1);
mp3.play(22);
mp3.play(28);

one after another

I'd be really grateful if you could point me in the right direction or provide an example of how I might achieve this. Thanks for a really awesome library!

No Sound

Hi, I wantet to use the Library for my DfPlayer Mini but there is no Sound coming out. The wiring is correct, I formatet the SD Card and I named the folder and the Tracks correctly. When I try to use the standart DFRobot Library ist says: Check the Connection, Insert the SD Card. I cant figure it out. I tried to find it out myself but after a month its time to get some help ^^

Functions did not work

Can you please explain how I can get the Volume or Number of files at SD-Card? I ever get a 0. It would be superb if you add these lines to your example if the functions are working. Thanks for that library!

wierd play error

Hi

when i use the example code & if i have the serial monitor open i get the following ....

the myMP3.play() command plays the 1st part of the previous mp3 followed by 1st part of the current mp3 then the full current mp3...

wierd.mp4

if the serial monitor is NOT open this does not happen

Any clues as to what may be happening would be appreciated!

Arduino UNO
Arduino 1.8.15
DFPlayer Fast v1.2.4

Sound isn't looping seamlessly

I have this very simple code:

#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>


SoftwareSerial mySerial(10, 11); // RX, TX
DFPlayerMini_Fast myDFPlayer;


void setup()
{
  Serial.begin(115200);
  mySerial.begin(9600);
  
  myDFPlayer.begin(mySerial);

  myDFPlayer.volume(30); //set volume low
  myDFPlayer.setTimeout(2000);
  myDFPlayer.loop(3); //loop mp3 file with leading identifier "0002"
}


void loop()
{

}

The sound stops after each time for 100ms or so, and then loops again, how can I make it loop seamlessly?

Problem compiling for the nano 33 ble

Compiling for the nano 33 ble gives an error when GET_STATUS is used, this seems to be because GET_STATUS is defined some ware in the Arduino mbed stuff, it can be fixed by changing it to GET_Satus in your library.

Is there a way to play certain tracks?

The idea is that I am putting several albums by one artist in a file. I would like to start at the first track of the album and end on the last. I was looking at playFolder, but I am not sure if this would work for my implementation. So I would like to start with folder 1, 001,mp3 and play through to 12. But maybe later I want to listen to the second album so I want to play folder 1 starting at 0013.mp3 and listen through the next 11 songs.

Fantastic job with the library by the way!

**EDIT Just a little more background, I am using an mfrc522 rfid reader and storing the folder, starting track and ending track as integers on the card. I can get it to play by using playFolder and passing the folder value and starting track value. I am just unsure of how to get to a certain track number.

isPlaying() always returns false

Firstly, thank you for your work, I'm leaving the official library for some reasons you know, and yours seems a good option.

I'm looking for a way to know when a track is complete to manage a playing queue. For that, I used isPlaying().
The problem is this method always returns false, even when the module is playing.

Do you have any idea why?
Regards.

loop a track in a folder

is it possible to loop a track inside a folder?

what i've tried is this and it didnt work:

mp3.playFolder(1, 2);
mp3.startRepeat();

i dont think i can use the mp3.loop() function with a folder.

thanks so much for the help and for the great library!!

Question: how to check if the dfplayer was initialized?

i have a function that call dFPlayerMini.play() directly. if the df was not initialize using begin() it will trigger panic exception and the mcu was restarted.

how to check if df player was initialized? simple check without need to provide the parameters in begin?

function STOP

Hello. The library does not have the STOP command, the variable is declared const uint8_t STOP = 0x16;, and the function is not present.
EQ Values I think I need to take out for the namespace dfplayer block, otherwise for example the command myMP3.EQ Select(EQ_NORMAL); not declared

Library update effors

Just updated the library on the INO and I now get the following error: Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

C:\Users\EJMOR\AppData\Local\Temp\cc1JJQ42.ltrans0.ltrans.o: In function `setup':

C:\Users\EJMOR\OneDrive\Documents\Arduino\Gideon/Gideon.ino:51: undefined reference to `DFPlayerMini_Fast::begin(Stream&, bool, unsigned long)'

collect2.exe: error: ld returned 1 exit status

exit status 1

Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Ardiuno Code with such library 'not compiling'.

This is my code that I got off of instructables;

#include <DFPlayerMini_Fast.h>
#include <Wire.h>
#include <SoftwareSerial.h>

//-----Declare MP3
SoftwareSerial mp3Serial(2,3); // RX, TX
DFPlayerMini_Fast mp3;
byte mp3vol;

//-----Constant bytes
const byte potiIN = A7;
const byte pirIN = A6;

//###################################
//###################################

void setup() {
pinMode(potiIN, INPUT);
pinMode(pirIN, INPUT);

Serial.begin(9600);
Wire.begin();

//Start mp3 and set volume from Poti
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
mp3vol = map(analogRead(potiIN), 0, 1023, 0, 30);
mp3.volume(mp3vol);
}

//================================

void loop() {
//Set volume from poti
mp3vol = map(analogRead(potiIN), 0, 1023, 0, 30);
mp3.volume(mp3vol);

// --> Adjust the number of tracks on your SD card here: random(1, YOURVALUE);
if(analogRead(pirIN)>5 && !mp3.isPlaying()) mp3.playFromMP3Folder(random(1, 10)); //Alternative: random(1, mp3.numSdTracks()+1));

delay(2000);
}

Can you possibly help me realize why or suggest reasons why the code wouldn't be compiling properly, I have tried reinstalling Ardunio, this library.

Incase you want more context to what it is for project wise I am basing it off of this:
https://www.instructables.com/Relaxing-Sounds-BOX-motion-Sensitive-3D-Printed/

Thanks.

IRremote conflict

I am having trouble compiling a sketch. Maybe a conflict with the IRremote library? My sketch was previously working with the DFRobotDFPlayerMini library. I am getting the following error:

Arduino: 1.8.12 (Linux), Board: "Arduino Pro or Pro Mini, ATmega328P (5V, 16 MHz)"

In file included from /home/Arduino/remote_codes/remote_codes.ino:1:0:
/home/Arduino/libraries/IRremote/src/IRremote.h:188:16: error: expected unqualified-id before numeric constant
#define REPEAT 0xFFFFFFFF

/home/Arduino/libraries/DFPlayerMini_Fast/src/DFPlayerMini_Fast.h:99:16: note: in expansion of macro 'REPEAT'
const uint8_t REPEAT = 0;

exit status 1
Error compiling for board Arduino Pro or Pro Mini.

Cannot compile when using ATTiny85

I was directed to this library because it does a better job with sleep. When giving it a try on an ATTiny85 I'm having an issue. Below is the error. Also, here is a link to someone with the same issue that PowerBroker2 responded to but the OP never returned a message.

https://www.reddit.com/r/arduino/comments/eeau2e/is_it_possible_to_use_the_dfplayermini_fast/

/Users/garnold/Documents/Arduino/libraries/DFPlayerMini_Fast-master/src/DFPlayerMini_Fast.cpp: In member function 'void DFPlayerMini_Fast::printStack(DFPlayerMini_Fast::stack)':
/Users/garnold/Documents/Arduino/libraries/DFPlayerMini_Fast-master/src/DFPlayerMini_Fast.cpp:1108:2: error: 'Serial' was not declared in this scope
  Serial.println("Stack:");
  ^~~~~~
/Users/garnold/Documents/Arduino/libraries/DFPlayerMini_Fast-master/src/DFPlayerMini_Fast.cpp:1108:2: note: suggested alternative: '_serial'
  Serial.println("Stack:");
  ^~~~~~
  _serial
exit status 1
Error compiling for board ATtiny25/45/85.

Question about performance

Hi @PowerBroker2 ,
thank you for your work. I would ask which optimization you had applied to improve execution speed, as claimed in the description. Just curiosity :) About simplicity I have no doubt, it is clearer than others.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.