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.mp3 … 0348-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!
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
- 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:
- 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.
- 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.
- 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.