MP3 DFPlayer notes: clones, noise, speakers, wrong file plays and no library

2 combined clock and timer projects using the DFPlayer modules

I’ve used the DFPlayer mp3 player in a number of projects now, not as a music player, rather just for playing brief announcements in a timer and clock projects. The DFRobot site lists applications and they all appear to be for announcements, so theoretically it should be what I need. I’m looking at other alternatives, in particular for the ESP32 that takes advantage of I2S and allows the audio files to be stored within the board’s onboard memory. I haven’t got that to work yet. In the meantime, I have a few DFPlayer modules and they are still useful and do have their benefits.

I have had a few issues with them and have tried a few things and managed to solve or at least improve some of them. I thought I was doing really well and had a decent understanding of most of the issues and then I bought another batch of modules. These didn’t behave the same and that is when I discovered there are multiple versions of the board with different chips. Looking at the module in the first project I made using them I found they had a different chip again. So it looked like some of my modules were clones, in fact they all may be. I have three different types and they all have some differences in behaviour. The most important thing I’ve learned is to be more careful about who I buy from and not simply go on price.

Just because I have an oscilloscope and a blog doesn’t mean I’m an expert. I’m just a hobbyist and there may be inaccuracies here, so keep that in mind.

Versions of the board and chips

I’ve discovered there are different board layouts and many different chips beings sold. I’m not confident that boards received from sellers will necessarily match the descriptions or images in the advertisements. I found a few discussions about different boards here DF Player warning! and on Reddit problem with the MP3-TF-16P mini MP3 player found (?). Looking at other posts I have found online these are different chips mentioned; YX5200-24SS, FN5201-24SS, MH2024K-16SS, MH2024K-24SS, AA19HEW496-94, AA19HFF859-94, AA1128CJ5M2U.1-94, AA19HEW456-94, AA1838CJ691F.1-94, AA1844HER406-94, AA1841CJ691F.1-94

There is this good analyser sketch to test your module DFPlayerAnalyzer It is simple to set up and gives details about supported features and a summary. 

YX5200-24SS

The original boards that I ordered many years ago look like this and are marked:

Module: DFPlayer Mini
MP3 IC: YX5200-24SS
Amp IC: No markings

These modules have been ok. The audio is reasonable although they do pick up a bit of interference from the rest of the circuitry but that may have more to do with my layout. I found I can play multiple short (about one second) files one after the other and by monitoring the busy pin can have the result play together. This one seems to have the shortest delay after play starts before the busy pin status changes. Otherwise, I am happy with this module. The summary from the DFPlayerAnalyzer is below.

-------------------------------------------------------
 Profile of this DFPlayer device
-------------------------------------------------------
The following devices have been discovered:
   -> SD, announced on reset, discovered by getTotalTrackCount
Does NOT react on setPlaysourceFlash
Reacts on 0x3F queries, reply : 2 -> SD
getFolderTrackCount...
   -> for SD returned 2 files in Folder /01/ 
GetCurrentTrack for SD returns correct value 199ms after start of track
Sends 2 callback(s) on SD track end
Continue playback after Ad for SD works
Wakeup from sleep by reset does NOT work
Wakeup from sleep by setting playsource SD works

AA19HFF859-94

The next batch that I ordered a couple of years ago look like this and are marked:

Module: DFPlayer Mini
MP3 IC: AA19HFF859-94
Amp IC: No markings

These modules have been ok. The audio is reasonable. Again, with this one I found I can play multiple short files one after the other. I had to wait about 350 milliseconds after playing a track before checking the busy pin as there is a delay in it changing state after the start of play.

-------------------------------------------------------
 Profile of this DFPlayer device
-------------------------------------------------------
The following devices have been discovered:
   -> SD, announced on reset, discovered by getTotalTrackCount, announced on setPlaysourceFlash
Does NOT react on 0x3F queries
getFolderTrackCount...
   -> for SD returned 2 files in Folder /01/ 
GetCurrentTrack for SD returns correct value 300ms after start of track
Sends 2 callback(s) on SD track end
Continue playback after Ad for SD works
Wakeup from sleep by reset does NOT work
Wakeup from sleep by setting playsource SD works

MH2024K-24SS

The last batch I received a week ago have a different board layout, markings and chips:
Module: MP3-TF-16P V3.0
MP3 IC: MH2024K-24SS
Amp IC: 8002A

These have been disappointing. They seem to use the same commands, or at least the few commands that I use, however if I don’t wait for at around 2 seconds between commands it can skip commands, in particular sending 2 commands with insufficient time between than can result in only the second command working. For some projects I could work around this, but for bursts of short tracks one after the other I’m going to be looking for a different module. The DFPlayerAnalyzer failed to complete with this module, but SchneHa commented reported on Feb 21 for a module marked with the same MH2024K-24SS chip this summary. Notice the “GetCurrentTrack for SD returns correct value 1600ms after start of track”. That 1600ms seems to be the delay for commands.

-------------------------------------------------------
 Profile of this DFPlayer device
-------------------------------------------------------
The following devices have been discovered:
   -> SD, discovered by getTotalTrackCount
Does NOT react on setPlaysourceFlash
Does NOT react on 0x3F queries
getFolderTrackCount...
   -> for SD returned 2 files in Folder /01/
GetCurrentTrack for SD returns correct value 1600ms after start of track
Sends 1 callback(s) on SD track end
Continue playback after Ad for SD works
Wakeup from sleep by reset does NOT work
Wakeup from sleep by setting playsource SD does NOT work

When not using an 8 ohm speaker and power supply

This datasheet indicates 4 ohm speaker can be used. Having said that the amplifier chips on my boards may not be the same as the one used in the original datasheet. I had issues with anything less than 8 ohms. It often failed with a loud buzzing when play starts sounding like this.

I believe this is a power issue. On the breadboard setup I was powering the module from a the Arduino Nano’s 5V output. I believe the module or amplifier was not getting enough power and going into power cycling. The module seems to pull significant current particularly when starting. Powering it directly to the same 5v supply as the Nano solved this issue.

Before I discovered this was the issue when I have used a 4 ohm speaker in projects I placed a 22 ohm resistor in series with the speaker. That was a pretty hacky workaround and may have consequences, but it did reliably play. I had to increase the volume but that had the added bonus of reducing the volume of white noise when nothing was playing.

Another forum suggested adding a large value electrolytic capacitor in series with the speaker. This was to fix a perceived issue with the 8002 audio amplifier chip.

However, according to this 8002 IC datasheet I found here it says “No output coupling capacitors, snubber networks or bootstrap capacitors required” and the typical circuit diagram does not include a capacitor in series with the speaker. If I understand correctly it doesn’t need one, but I’m not sure what amplifier IC my generic modules are using so who knows. Does adding one cause any issues? Again, not sure but I found adding a 330uF capacitor I had on hand in series with the speaker stopped the playback issue. Now that I found that the issue was a power one this workaround should not be necessary. If you try this beware of the polarity of the capacitor. SPK1 (pin 6 on the module) is positive.

White noise/hiss while files are not playing

I’ve found that a quiet hiss is always audible when files are not playing. As it is very quiet, I expect others in noisier environments may not have noticed it. I’ve seen quite a few people report this but most times those responding to this have assumed the person was talking about buzzing or clicking noise from other interference.

I’ve tried a few things to solve this:

1. Following the instructions here DFPlayer MP3 module – high quiescent power consumption and clicks when power applied and removed – FIX! I found this 8002 datasheet supports this mod, “the 8002 contains advanced pop & click circuitry which eliminates noise which would otherwise occur during turn-on and turn-off transitions.” I thought that doing this would power down the amp when nothing was playing, giving silence. It did, but with my DFPlayer it made audible clicks at the start and end of each file. Others have seemed to have success with this so quite likely the audio IC on the DFPlayer module I tried doesn’t support this.

2. Powering the player down when not playing. I created a sketch to keep the whole module powered down when not playing. When a request to play is sent it would start the player, wait a bit for it to start, play the file and then remove power from the module when playing ended. It solved the hiss but I still got clicks when the player started and shutdown so while it may be a solution in some scenarios, I have not used it in a project.

3. A resistor in series with the speaker. As mentioned above about speakers, placing a resistor in series with the speaker reduces the overall volume including the hiss. It is hacky and not sure why I mention it again, but I have used it.

Other noise

The only thing I have really tried is  adding a large electrolytic capacitor across the ground and power pins near the DFPlayer. This reduced some noise. In the current project I’m using a 1000uF 10v capacitor. I’m happy with the results for use with announcements.

Speaker polarity

It’s worth noting that the datasheet indicates that the speaker connections are marked positive and negative. While it may not matter all that much, connecting the speaker the right way should mean that the speaker cone is pushed outward with signal. On my modules pin 8 is SPK2 and is negative and pin 6 is SPK1 and is positive.

The wrong file plays

I’ve read of others having the wrong files play and I got caught with this and found it very frustrating. When it has occurred, I’ve had trouble figuring out why and reproducing it until I found as others have reported that the files were playing in order they were added to the SD card and not by filename numbering.

There seems to be 4 ways to set up folders and name files:

I’ve read of others having the wrong files play and I got caught with this and found it very frustrating. When it has occurred, I’ve had trouble figuring out why and reproducing it until I found as others have reported that the files were playing in order they were added to the SD card and not by filename numbering.

There seems to be 4 ways to set up folders and name files:

  1. In folders numbered 01 – 99. File names with 3 digit prefixes 001 – 255. Command 0x0F
  2. In a folder named MP3 (or perhaps mp3). File names with 4 digit prefixes 0001 to 3000. Command 0x12
  3. In the root directory. File names with 4 digit prefixes 0001 to 3000. Command 0x03
  4. In folders named 01 – 15. File names with 4 digit prefixes 0001 – 3000. Command 0x14

While they may all appear good options, I ended up using method 1. When using method 3 the files just appear to play in the order they were added to the SD card and the digits were ignored. Methods 2 and 4 may be ok, but I found it more complicated when not using a library. Method 1 has been working well in a couple of projects for a few years. Filenames can include other characters but must have a space after the number: 001[space]filename.mp3

Not using a library

I started using these modules after watching Ralph Bacon’s video #40 Let the music play! Arduino based MP3 Player for music (or announcements). Ralph didn’t use a library and I decided to try that method as well. I wanted to learn what the code was doing and in this case it wasn’t too complicated. Ralph included the ability to get a response back from the player using the serial interface, but I have not used that. I’m just monitoring the busy pin to check when play ends. It may not be the best way but has worked for me.

The modules support a lot of features, but I’m only interested in a few:

  • Set the volume
  • Set the Equalizer
  • Play a specific file
  • Doesn’t add significant delays to the sketch

And ideally

  • Ability to queue files
  • Clear the queue

The reason I am interested in queueing files is that I wanted to be able to play blocks of speech made from a number of files. For example, for my talking clock the time is made up of “The time is” <hour> <minutes> <am/pm>, so that’s 4 files. While these are playing, I don’t want the clock display to stop so I got around this with a queue. The basic code below doesn’t support queueing. I do have some that does but it needs to be cleaned up before sharing.

This is the basic code I am using. It provides the basic features.

// ==================================================================
//                 Demo sketch for MP3 DFPlayer module
// ==================================================================
/*  
   Based on sketch by Ralph Bacon MP3-Player-DFPlayer https://github.com/RalphBacon/MP3-Player-DFPlayer/blob/master/MP3_Player.ino

   Connections
   ===========
   DFPlayer ground pin 7 and/or 10
   DFPlayer power pin 1 to 3.3 - 5V VCC
   Arduino TX (pin 9) - DFPlayer RX (pin 2) via 1k resistor
   Arduino RX (pin 10) - DFPlayer TX (pin 3) Only needed to receive responses back from player. Not connected or used in this example
   Arduino pin 8 - DFPlayer BUSY (pin 16) - Optional. Monitors if track is playing. Low level when playing. High when in standby. 

   DFplayer Output
   --------------
   Speaker to pin 6 (speaker +) and 8 (Speaker -)
   OR
   Audio output right channel - pin 4
   Audio output left channel - pin 5

   Audio files
   ===========
   This demo requires 2 files with names starting with 001 and 002 in a folder names 01

   Delays
   ======
   The 2000 ms delays in this sketch are this length for my slowest player. Try reducing or removing for other players
*/
   
#include <SoftwareSerial.h>   // For cummunication with DFPlayer

// DFPlayer audio module
#define mp3Busy 8             // MP3 Playback monitor
#define mp3RxPin 10           // Player pin for sending commands (Player pin 3)
#define mp3TxPin 9            // Player pin for receiving commands (Player pin 2) - Not used
 
// Set up software serial instead of serial to allow serial monitor to be used
SoftwareSerial mp3(mp3RxPin, mp3TxPin);

  
// ------------------------------------------------------------------
//                                SETUP
// ------------------------------------------------------------------
void setup() {

  // Open the serial port. This is just for debugging using the serial monitor
  Serial.begin(9600);

  pinMode(mp3Busy, INPUT); // MP3 busy monitor

	// NB For comms to MP3 player not USB
	mp3.begin(9600);

  // Wait for player to initialize
  delay(2000);

	// Set volume (otherwise will be full volume) 0 - 30
	sendCommand(0x06, 0, 10); // Using Hex,

  delay(2000);

	// Set equalizer  Normal = 0 / Pop = 1 / Rock = 2 / Jazz = 3 / Classic = 4 / Bass = 5
	sendCommand(0x07, 0, 5);    // Bass

  delay(2000);

  Serial.println("Finished setup");

  Serial.println("Play track 1 in folder 1 for 5 seconds");
  sendCommand(0x0F, 1, 1);
  Serial.println("Track 1 started");
  delay(5000); 

  Serial.println("Play all of track 2 in folder 1");
  sendCommand(0x0F, 1, 2); 
  Serial.println("Track 2 started");
  
  // Monitor player and loop until playing has completed
  delay(2000); // Wait for the track to start playing before checking play status. reduce to 400ms for some modules
  while (digitalRead(mp3Busy) == LOW) {
  }
  Serial.println("Track 2 finished");
 
}

// ------------------------------------------------------------------
//                             MAIN LOOP
// ------------------------------------------------------------------
void loop() {

}

// ------------------------------------------------------------------
//                    SEND COMMANDS TO DFPLAYER
// ------------------------------------------------------------------
void sendCommand(byte Command, byte Param1, byte Param2) {
  // Format command including checksum and send to DFPlayer 

  // For DFPlayer communication
  const byte startByte = 0x7E;    // Start Command
  const byte versionByte = 0xFF;  // Version info
  const byte dataLength = 0x06;   // Fixed 0x06 Data length not including parity
  const byte infoReq = 0x00;      // Get info back from module - 0x00 = no info, 0x01 = return info
  const bool isDebug = false;     // Debug mode - Off in this sketch
  const byte endByte = 0xEF;      // Fixed end Command

	// Calculate the checksum
	unsigned int checkSum = -(versionByte + dataLength + Command + infoReq + Param1 + Param2);

	// Construct the command line
	byte commandBuffer[10] = { startByte, versionByte, dataLength, Command, infoReq, Param1, Param2,
			highByte(checkSum), lowByte(checkSum), endByte };

  // Send to player
	for (int cnt = 0; cnt < 10; cnt++) {
		mp3.write(commandBuffer[cnt]);
	}

	// Delay needed between successive commands
	delay(30);
}

Commands are made up of 3 parameters. The first is the command. The second is the highbyte and the third the lowbyte for the values. For the commands that I use the second parameter is always 0 except for playing a file. In that case the folder number is used.

These are the commands based on the info from the datasheet.

Commands
========   
Commands can have hex or decimal (in brackets). Watch out for errors if prefixed with 0 without 0x
sendCommand(0x01, 0, 0);  // Next
sendCommand(0x02, 0, 0);  // Previous
sendCommand(0x03, 0, 4);  // Plays files with 4-digit prefixes in the media root folder. eg. track 4
sendCommand(0x04, 0, 0);  // Volume up
sendCommand(0x05, 0, 0);  // Volume down
sendCommand(0x06, 0, 10); // Set volume 0 - 30 e.g. volume at 10
sendCommand(0x07, 0, 0);  // Equalizer
sendCommand(0x08, 0, 0);  // Playback mode (0/1/2/3/4) Repeat / Folder repeat / Single repeat / Random
sendCommand(0x0A, 0, 0);  // Enter into standby
sendCommand(0x0B, 0, 0);  // Normal working - Not tested
sendCommand(0x0C, 0, 0);  // Reset module - Not tested 
sendCommand(0x0D, 0, 0);  // Play current track
sendCommand(0x0E, 0, 0);  // Pause 
sendCommand(0x0F, 1, 2);  // Specify playback folder 01 - 99. Use 3 digit file names prefixes 001 - 255
sendCommand(0x12, 0, 0);  // Specify playback from MP3 folder. Use 4 digit prefixes 0001 to 3000
sendCommand(0x14, 0, 0);  // Specify playback folder 01 - 15. Use 4 digit file names prefixes 0001 - 3000

In practice I just use these:

Volume

sendCommand(0x06, 0, );
Where is a number between 0 and 30. E.g. sendCommand(0x06, 0, 30); is full volume

Equalizer

sendCommand(0x07, 0, );
The options are: Normal = 0, Pop = 1, Rock = 2, Jazz = 3, Classic = 4, Bass = 5. So setting rock is sendCommand(0x07, 0, 2);

Play a file

This uses method 1 above as it is easy and I have found it to be reliable
sendCommand(0x0F, , );
Where folder is between 01 – 99 and files have a 3 digit file names prefixes and are in the range 001 – 255. sendCommand(0x0F, 1, 3); will play track 3 in folder 1.

If I get the queueing code cleaned up I’ll do a post about that and add an update here.

I hope this is of help to someone. Let me know if you believe any info is incorrect or have something to add.

Resources

Using Text to Speech online tools to create audio files for Arduino projects

I’ve made a couple of projects that play audio alerts using a dfplayer and MP3 files. One in a clock that plays announcements and the other a countdown timer. When I did those, I used onlinetonegenerator.com to convert text to speech. I liked the voices but it doesn’t have an option to save the audio as an MP3 file. I ended up using Audacity to record the computers audio. It worked but was very tedious. Since then, I’ve been looking for a simpler way.

The important criteria in a text to speech service for me is:

  • Ability to enter text, listen to the converted audio in the browser and then download it as an mp3 file.
  • Sufficient audio quality.
  • Volume level ok.
  • Suitable lead in and end dead time to allow multiple files to be played in sequence with the  result sounding as a smooth sentence. For example these four files together; “The time is”, “eleven”, “thirty two”, “am”.
  • A suitable voice. They don’t all have the same voices. I prefer some more than others.
  • Free or good value.
  • Ability to change speed, pitch and emphasis a bonus.

Here are a few I’ve looked at.

Online Tone Generator (onlinetonegenerator.com/voice-generator.html)

This is the first one I used. Its:

  • Free.
  • Has a good range of voices; mostly Google, plus a few Microsoft ones I presume are built into my Windows PC. I particularly like Google français.
  • Lots of other audio tools, including; noise generator, sweep generator, DTMF signals.
  • But, no MP3 download.

From Text To Speech (fromtexttospeech.com)

I briefly looked at this one. It is:

  • Free.
  • Has a 50 000 character limit per file.
  • I’m unable to listen in browser. No play button displays until a file is created and then the player presented appears to use flash and is blocked by my browser. The file can be downloaded and used.
  • MP3 download.
  • Different speed and voices.

TTSMP3 (ttsmp3.com)

This is the one that I am intending to use in my next project. Lots of features, MP3 file output and a fair amount of free usage. It is:

  • Free for 3,000 characters (~375 words) per day.
  • Lots of different voices.
  • Supports speed, pitch and other effects using tags.
  • Multiple voices can be used in the one piece of text by using tags.
  • MP3 file download.

TTSMP3 uses Amazon Polly and comes with quite a few voices and features. Additional effects can be used by using tags in your text. More info about tags is available on this Amazon page.

Here is an example of the voices.

That audio file was created by pasting the text below into the converter. Beware if you do this it will use up most of your daily 3000 word limit.

[speaker:Zeina] Hi, I'm Arabic Zeina
[speaker:Russell] Hi, I'm Russell Australian English Russell
[speaker:Nicole] Hi, I'm Australian English Nicole
[speaker:Camila] Hi, I'm Brazilian Portuguese Camila
[speaker:Ricardo] Hi, I'm Brazilian Portuguese Ricardo
[speaker:Vitória] Hi, I'm Brazilian Portuguese Vitória
[speaker:Emma] Hi, I'm British English Emma
[speaker:Amy] Hi, I'm British English Amy
[speaker:Brian] Hi, I'm British English Brian
[speaker:Chantal] Hi, I'm Canadian French Chantal
[speaker:Enrique] Hi, I'm Castilian Spanish Enrique
[speaker:Lucia] Hi, I'm Castilian Spanish Lucia
[speaker:Conchita] Hi, I'm Castilian Spanish Conchita
[speaker:Zhiyu] Hi, I'm Chinese Mandarin Zhiyu
[speaker:Mads] Hi, I'm Danish Mads
[speaker:Naja] Hi, I'm Danish Naja
[speaker:Ruben] Hi, I'm Dutch Ruben
[speaker:Lotte] Hi, I'm Dutch Lotte
[speaker:Céline] Hi, I'm French Céline
[speaker:Léa] Hi, I'm French Léa
[speaker:Mathieu] Hi, I'm French Mathieu
[speaker:Vicki] Hi, I'm German Vicki
[speaker:Marlene] Hi, I'm German Marlene
[speaker:Hans] Hi, I'm German Hans
[speaker:Karl] Hi, I'm Icelandic Karl
[speaker:Dóra] Hi, I'm Icelandic Dóra
[speaker:Aditi] Hi, I'm Indian English Aditi
[speaker:Raveena] Hi, I'm Indian English Raveena
[speaker:Carla] Hi, I'm Italian Carla
[speaker:Giorgio] Hi, I'm Italian Giorgio
[speaker:Bianca] Hi, I'm Italian Bianca
[speaker:Takumi] Hi, I'm Japanese Takumi
[speaker:Mizuki] Hi, I'm Japanese Mizuki
[speaker:Seoyeon] Hi, I'm Korean Seoyeon
[speaker:Mia] Hi, I'm Mexican Spanish Mia
[speaker:Liv] Hi, I'm Norwegian Liv
[speaker:Ewa] Hi, I'm Polish Ewa
[speaker:Jan] Hi, I'm Polish Jan
[speaker:Maja] Hi, I'm Polish Maja
[speaker:Jacek] Hi, I'm Polish Jacek
[speaker:Inês] Hi, I'm Portuguese Inês
[speaker:Cristiano] Hi, I'm Portuguese Cristiano
[speaker:Carmen] Hi, I'm Romanian Carmen
[speaker:Maxim] Hi, I'm Russian Maxim
[speaker:Tatyana] Hi, I'm Russian Tatyana
[speaker:Astrid] Hi, I'm Swedish Astrid
[speaker:Filiz] Hi, I'm Turkish Filiz
[speaker:Joey] Hi, I'm US English Joey
[speaker:Kimberly] Hi, I'm US English Kimberly
[speaker:Salli] Hi, I'm US English Salli
[speaker:Ivy] Hi, I'm US English Ivy
[speaker:Matthew] Hi, I'm US English Matthew
[speaker:Kendra] Hi, I'm US English Kendra
[speaker:Joanna] Hi, I'm US English Joanna
[speaker:Justin] Hi, I'm US English Justin
[speaker:Miguel] Hi, I'm US Spanish Miguel
[speaker:Lupe] Hi, I'm US Spanish Lupe
[speaker:Penélope] Hi, I'm US Spanish Penélope
[speaker:Gwyneth] Hi, I'm Welsh Gwyneth
[speaker:Geraint] Hi, I'm Welsh English Geraint

Comparisons

Compared with the original audio files that I created by using Audacity to record the PC audio and onlinetonegenerator.com, ttsmp3.com had lower volume. I may have had the record level a bit high when I used Audacity so not sure that the ttsmp3 level is too low.

The bit rate is also different, with the Audacity ones higher. That’s probably because I unnecessarily chose a higher bitrate in Audacity. TTSMP3 was 48kbs.

And that affected the file size. The TTSMP3 is much smaller.

Here are a couple of examples for comparison. For each I created four separate files and then joined them together to see how smooth the transition was. The four files were “The time is”, “11”, “32”, “AM”. I had to be a bit creative with the AM for French Celine as it was pronounced as “am”.

onlinetonegenerator.com Voice is Google français. I like this voice. It has added a lot of character to my speaking clock.

ttsmp3.com Voice is French Celine. It was much easier to create and the timing between files is ok, but the voice doesn’t have the same character to the one above in my opinion

ttsmp3.com This is British Amy. This was just for comparison to see how the same text would sound with an English voice.

Do you have other methods? Let me know.

Update 13/4/2021: I have added a post with info about how to increase the audio level in a batch of files Batch processing files with Audacity