DFPlayer Mini

Reliable information about this player is hard to come by. According to several people the official docs and data sheet are not entirely accurate. There’s also a lot of posts that provide partial information. So I’ve tried to gather together the best of the info I’ve found online.

If you find any errors in the following please create an issue on this site’s GitHub page (GitHub account required)

To date, the main info I’ve found has been in a post by Ype Brada (aka Yerke?) on 6 April 2015 that was formerly on the banggood forums, but has now disappeared. It has now been re-posted on PasteBin as Yerke Post about DF Player mini commands.

I’ve formatted and and lightly tweaked that a part of that post and re-published it below.

Opinions also seem to vary about how best to wire up the DFPlayer Mini. Having tried a few suggestions, I’ve published a diagram of the circuit that works best me at the bottom of the page.

Finally, I've included some example source code for the DFPlayer Mini published by DFRobot.


DF Player Mini Commands (after Ype Brada)

The main content of this section is entirely the work of Ype Brada.

The information was all taken from the second post on the PasteBin page, i.e. the one from 04 April 2015.

Edits have been largely confined to those needed for readability – formatting into tables and lists – along with some clarifications and spelling etc. corrections. All the content from here on in comes from the comments in the source code that accompanied the code, followed by the source code itself.

Why post it here? Two reasons. Firstly, as mentioned the lack of formatting on Paste Bin makes the content hard to read. Secondly, one post has already been taken down – I don’t want to risk this valuable info disappearing again.

DF Player mini command discovery

[This] program is meant to discover all the possibilities of the command structure of the DFPlayer mini. No special libraries are needed. Program is very easy to understand and can be the basis for your own mp3 player sketch.

Note: Commands are not always correctly described in the manual. I tried to fix it, but there is still something to do. The commands recoverd so far are listed below.

Use of sketch: Enter three ([comma] separated) decimal numbers in the Serial Monitor with no end of line character.

  • First number : Command
  • Second number: First (High Byte) parameter
  • Third number : Second (Low Byte) parameter

E.g.: 3,0,1 will play the first track on the TF card

Very important: Use serial 1KΩ resistors or a level shifter between module RX and TX and Arduino to suppress noise

  • Connect Sound module board RX to Arduino pin 11 (via 1KΩ resistor)
  • Connect Sound module board TX to Arduino pin 10 (via 1KΩ resistor)
  • Connect Sound module board Vcc to Arduino Vin when powered via USB (preferably 3.0) else use seperate 5V power supply
  • Connect Sound module board GND to Arduino GND

General DF Player mini command structure

 
Byte # Function Value Notes
0 Start Byte 0x7E  
1 Version Info 0xFF Don’t know why it’s called Version Info
2 Number of bytes 0x06 Always 6 bytes
3 Command 0x__ See below for list of commands
4 Command feedback 0x00 or 0x01 Value 0x00 ⇒ no feedback;
Value 0x01 ⇒ feedback required: returns info with command 0x41
5 Parameter 1 [DH] 0x__ Value depends on Command
6 Parameter 2 [DL] 0x__ Value depends on Command
7 Checksum high 0x__ See explanation below and function execute_CMD in following source code
8 Checksum low 0x__ See explanation below and function execute_CMD in following source code
9 End command 0xEF

Checksum calculation: Checksum = -Sum(byte(1..6)) (2 bytes, notice minus sign!)

Commands

Key to following tables:

  • Status column: * ⇒ Confirmed command; ? ⇒ Unknown, not clear or not validated
  • Parameters columns: X ⇒ Value not used (set to zero?)
Commands without returned parameters
CMD Function Status Parameters (2 x 8 bit) Description
Hex Dec Hi Byte [DH] Lo Byte [DL]
0x01 1 Next * X X Next file in current folder. Loops when last file played
0x02 2 Previous * X X Previous file in current folder. Loops when last file played
0x03 3 Specify track to play back * highByte(track-number) lowByte(track-number) Track number must be in range 1~2999 Playing order is order in which the numbers are stored. File name and folder name are arbitrary, but when named starting with an increasing number and in one folder, files are played in that order and with correct track number. e.g. 0001-Joe Jackson.mp30348-Lets dance.mp3
0x04 4 Increase volume * X X Increase volume by 1
0x05 5 Decrease volume * X X Decrease volume by 1
0x06 6 Specify volume * X volume Valid values for volume are 0-0x30. The default is 0x30
0x07 7 Specify Equalizer * X eq-code Valid values for eq-code are 0..5 where 0 ⇒ Normal, 1 ⇒ Pop, 2 ⇒ Rock, 3 ⇒ Jazz, 4 ⇒ Classic, 5 ⇒ Base
0x08 8 Specify repeat * highByte(track-number) lowByte(track-number) Repeat the specified track number
0x09 9 Specify playback source ? X source-id Unknown. Seems to be overridden by automatic detection. According to datasheet valid values for source-id are 0..4 where 0 ⇒ U, 1 ⇒ TF, 2 ⇒ AUX, 3 ⇒ SLEEP, 4 ⇒ FLASH
0x0A 10 Enter into standby – low power loss * X X Works, but no command found yet to end standby (inserting TF-card again will end standby mode)
0x0B 11 Normal working (per datasheet) ? ? ? No error code, but no function found
0x0C 12 Reset module * X X Resets all (Track set to 0x01, Volume set to 0x30) Will return 0x3F initialization parameter (0x02 for TF-card). “Clap” sound after executing command (no solution found)
0x0D 13 Play * X X Play current selected track
0x0E 14 Pause * X X Pause track
0x0F 15 Specify folder and file to playback * folder-number file-number Important: Folders must be named 01~99, files must be named 001~255
0x10 16 Volume adjust set (per datasheet) ? ? ? No error code. Does not change the volume gain.
0x11 17 Loop play * X 0x01:play
0x00:stop
Loop play all the tracks. Start at track 1.
0x12 18 Play mp3 file specified by number in /mp3 folder * highByte(file-number) lowByte(file-number) Play mp3 file in folder named /mp3 in your TF-card. File format exact 4-digit number (0001~2999) e.g. 0235.mp3
0x13 19 Unknown ? ? ? Returns error code 0x07
0x14 20 Unknown ? ? ? Returns error code 0x06
0x15 21 Unknown ? ? ? Returns no error code, but no function found
0x16 22 Stop * X X Stop playing current track
0x17 23 Loop Folder 01 * X 1~255 Loops all tracks in folder named tt.
(Cahamo’s query: if we’re looping all tracks in folder 01 then what is the purpose of the lo parameter?)
0x18 24 Random play * X X Random play all tracks, always starts at track 1
0x19 25 Single loop * 0 0 Loops the track that is playing.
0x1A 26 Pause * X 0x01:pause
0x00:release pause
 
Commands with returned parameters
CMD Function Status Parameters (2 x 8 bit) Description
Hex Dec Hi Byte [DH] Lo Byte [DL]
0x3A 58 Medium inserted * 0 1:U-disk
2:TF-card
 
0x3B 59 Medium ejected * 0 1:U-disk
2:TF-card
 
0x3C 60 Finished track on U-disk * highByte(track-number) lowByte(track-number) Not validated. Returns track number when song is finished on U-Disk
0x3D 61 Finished track on TF-card * highByte(track-number) lowByte(track-number) Returns track number when song is finished on TF
0x3E 62 Finished track on Flash * highByte(track-number) lowByte(track-number) Not validated. Returns track number when song is finished on Flash
0x3F 63 Initialization parameters * 0 0 ~ 0x0F. Returned code when Reset (0x12) is used. Each bit represents one device in the low-four bits (see datasheet: 0x02 is TF-card). Error 0x01 when no medium is inserted.
0x40 64 Error ? 0 0~7 Error code (returned codes not yet analyzed)
0x41 65 Reply ? 0 0~? Return code when command feedback is high. 0x00 ⇒ No error. Other returned codes not known.
0x42 66 The current status * device-number 0:no play
1:play
 
0x43 67 The current volume * 0 volume volume is in the range 0..30
0x44 68 The current EQ * 0 eq-code Values for eq-code are 0..5 where 0 ⇒ Normal, 1 ⇒ Pop, 2 ⇒ Rock, 3 ⇒ Jazz, 4 ⇒ Classic, 5 ⇒ Base
0x45 69 The current playback mode * 0 0x00:CMD 0x08 not used
0x02: CMD 0x08 used
Not useful
0x46 70 The current software version * 0 version-number Yerke’s version was 5
0x47 71 The total number of U-disk files * highByte(number-of-files) lowByte(number-of-files) Not validated
0x48 72 The total number of TF-card files * highByte(number-of-files) lowByte(number-of-files)  
0x49 73 The total number of flash files * highByte(number-of-files) lowByte(number-of-files) Not validated
0x4A 74 Keep on ? ? ? Unknown - see datasheet. No returned parameter.
0x4B 75 The current track of U-Disk * highByte(track-number) lowByte(track-number) Current track on all media
0x4D 77 The current track of Flash * highByte(track-number) lowByte(track-number) Current track on all media
0x4C 76 The current track of TF card * highByte(track-number) lowByte(track-number) Current track on all media
0x4E 78 Folder "01" [DH]=x, [DL]=1 * 0 number-of-files Change to first track in folder "01" Returns number of files in folder "01"
(Cahamo’s query: if we’re querying only track "01" then what is the purpose of the lo parameter?)
0x4F 79 The total number of folders * 0 number-of-folders Total number of folders, including root directory

Additional info can be found on the DFRobot site, but is not very reliable. Additional info: http://www.dfrobot.com/index.php?route=product/product&product;_id=1121

Source Code

#include "SoftwareSerial.h"
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]

SoftwareSerial mySerial(10, 11);    // RX pin = 10, TX pin = 11

void setup () {
  Serial.begin(9600);
  mySerial.begin (9600);
  execute_CMD(0x3F, 0, 0); // Send request for initialization parameters
  while (mySerial.available()<10) // Wait until initialization parameters are received (10 bytes)
  delay(30); // Pretty long delays between succesive commands needed (not always the same)
  // Initialize sound to very low volume. Adept according used speaker and wanted volume
  execute_CMD(0x06, 0, 5); // Set the volume (0x00~0x30)
}

void loop () {
  if (Serial.available())
  {
    // Input Serial monitor: Command and the two parameters in decimal numbers (NOT HEX)
    // E.g. 3,0,1 (or 3 0 1 or 3;0;1) will play first track on the TF-card
    byte Command = Serial.parseInt();
    byte Parameter1 = Serial.parseInt();
    byte Parameter2 = Serial.parseInt();
    // Write the input at the screen
    Serial.print("Command : 0x");if (Command < 16) Serial.print("0"); Serial.print(Command, HEX);
    Serial.print("("); Serial.print(Command, DEC);
    Serial.print("); Parameter: 0x");if (Parameter1 < 16) Serial.print("0");Serial.print(Parameter1, HEX);
    Serial.print("("); Serial.print(Parameter1, DEC);
    Serial.print("), 0x");if (Parameter2 < 16) Serial.print("0");Serial.print(Parameter2, HEX);
    Serial.print("("); Serial.print(Parameter2, DEC);Serial.println(")");
    // Excecute the entered command and parameters
    execute_CMD(Command, Parameter1, Parameter2);
  }

  if (mySerial.available()>=10)
  {
    // There is at least 1 returned message (10 bytes each)

    // Read the returned code
    byte Returned[10];
    for (byte k=0; k<10; k++)
      Returned[k] = mySerial.read();
    // Wtite the returned code at the screen
    Serial.print("Returned: 0x"); if (Returned[3] < 16) Serial.print("0"); Serial.print(Returned[3],HEX);
    Serial.print("("); Serial.print(Returned[3], DEC);
    Serial.print("); Parameter: 0x"); if (Returned[5] < 16) Serial.print("0"); Serial.print(Returned[5],HEX);
    Serial.print("("); Serial.print(Returned[5], DEC);
    Serial.print("), 0x"); if (Returned[6] < 16) Serial.print("0"); Serial.print(Returned[6],HEX);
    Serial.print("("); Serial.print(Returned[6], DEC); Serial.println(")");
  }
}

void execute_CMD(byte CMD, byte Par1, byte Par2)
  // Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
      Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
  //Send the command line to the module
  for (byte k=0; k<10; k++)
  {
    mySerial.write( Command_line[k]);
  }
}

DFPlayer Mini Wiring

Here’s a possible circuit to drive the DFPlayer Mini from an Arduino Uno.

I derived this circuit from one described in detail by Markus Wobisch. My circuit assumes you can provide a regulated 5V to it, while while Markus’ circuit uses 6 × 1.2V rechargable AA batteries and voltage regulator, and provides an alternative for driving stereo speakers via a PAM8403 2×3W.

While I’ve had success with this circuit, I’m not claiming it’s the best available. And there are absolutely no guarantees it won’t damage your DFPlayer. Use at your own risk!

Circuit diagram for DFPlayer Mini with Arduino Uno

Components are as follows:

  • 5V DC regulated power supply
  • DFPlayer Mini
  • Arduino Uno or similar
  • 2 × 1kΩ resistors (¼W is sufficient)
  • 470µF electrolytic capacitor
  • Diode: any diode with ≈ 0.8V forward voltage (I used an IN4001)
  • 8 Ω speaker

Notes

  1. The orientation of the DFPlayer Mini’s pins as shown in the circuit diagram is correct when the module’s “dimple” is at the top:

    DFPlayer Mini pinout

  2. The reason for the diode is to drop the voltage supplied to the DFPlayer Mini from 5V to about 4.2V. The theoretical voltage range for the DFPlay Mini is 3.3-5.0V, but there are reports that the component is happier at around 4.2V.
  3. The Arduino has to send commands and receive responses from the DFPlayer Mini by means of serial communication. The circuit implies the use of the SoftwareSerial library configured with pin 10 as its RX pin and pin 11 as the TX pin. Pin 12 gets notifications from the DF Player Mini’s BUSY pin. This has the advantage of leaving the Arduino’s hardware serial pins 0 and 1 free.
  4. You could try leaving out the smoothing capacitor - I got acceptable results without it.

DFRobot's Example Source Code

A copy of the entire exmaple source for the DFPlayer Mini is available from my Google Drive account as DFRobotDFPlayerMini-1.0.3. It is released under the GNU Lesser General Public License.

I can't recall where I found it and thought I'd make it available, like Ype Brada's notes, just to make sure it survives on the net.