The DFPlayer Mini is a compact MP3 player module that plays audio files from a micro-SD card. It features a built-in DAC and amplifier, UART serial control, and direct speaker outputs — ideal for makers, hobbyists, educators, and professionals building talking props, smart-home alerts, toys, or installations.
| Pin | Description |
|---|---|
| VCC | 3.2V–5V Power Input (5V recommended if driving speaker) |
| GND | Ground (common ground with MCU required) |
| RX | Serial Receive (connect to MCU TX; add ~1kΩ resistor if MCU is 5V) |
| TX | Serial Transmit (connect to MCU RX) |
| SPK1 / SPK2 | Speaker outputs — connect a small 3W speaker (bridge) |
| DAC_L / DAC_R | Line-level outputs for external amp |
| IO1 / IO2 | Hardware trigger pins (tie to GND to trigger in IO mode) |
Fast setup. Big sound. Zero fuss. Load your audio files to a micro-SD card, plug the DFPlayer Mini into your controller and speaker, and you’re ready to play. No extra amplifier needed for small speakers and a wealth of control options (serial commands, hardware IO, folder playback) make it incredibly flexible for hobby or professional use.
Every order includes clear wiring instructions, a downloadable wiring diagram, and complete sample code for Arduino and ESPHome so you can get prototype time to production faster.
/*
DFPlayer Mini - Arduino UNO example (SoftwareSerial)
Full-featured: init, play file, play folder, volume, next/prev, stop, loop, random,
buttons for IO1/IO2 emulate, serial debug feedback.
Requires:
- DFRobotDFPlayerMini library
- SoftwareSerial
Wiring (example):
UNO 5V -> DFPlayer VCC
UNO GND -> DFPlayer GND
UNO D10 -> DFPlayer RX (through 1k resistor recommended)
UNO D11 -> DFPlayer TX
Speaker -> SPK1 / SPK2
*/
#include <SoftwareSerial.h>
#include "DFRobotDFPlayerMini.h"
SoftwareSerial dfSerial(10, 11); // RX (to DFPlayer TX), TX (to DFPlayer RX)
DFRobotDFPlayerMini player;
const int buttonPlayPin = 2; // momentary button to play/pause
const int buttonNextPin = 3; // next track
const int buttonPrevPin = 4; // prev track
const int ledPin = 13;
unsigned long lastDebounce[3] = {0,0,0};
const unsigned long debounceDelay = 50;
void setup() {
pinMode(buttonPlayPin, INPUT_PULLUP);
pinMode(buttonNextPin, INPUT_PULLUP);
pinMode(buttonPrevPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
dfSerial.begin(9600);
Serial.println(F("Initializing DFPlayer..."));
if (!player.begin(dfSerial)) {
Serial.println(F("Unable to begin DFPlayer. Check wiring and SD card."));
while(true) { digitalWrite(ledPin, !digitalRead(ledPin)); delay(300); } // blink
}
Serial.println(F("DFPlayer online."));
player.volume(20); // volume 0-30
player.EQ(DFPLAYER_EQ_NORMAL);
player.play(1); // play 0001.mp3
}
void loop() {
if (player.available()) {
DFRobotDFPlayerMini::ErrorType type = player.readType();
if (type == DFRobotDFPlayerMini::ErrorType::TrackFinished) {
Serial.print(F("Track finished: "));
Serial.println(player.read());
} else if (type == DFRobotDFPlayerMini::ErrorType::CardOnline) {
Serial.println(F("Card inserted."));
} else if (type == DFRobotDFPlayerMini::ErrorType::CardRemoved) {
Serial.println(F("Card removed."));
}
}
// Buttons (simple debounced)
handleButton(buttonPlayPin, 0, [](){ // play/pause toggle
static bool playing = true;
if (playing) { player.pause(); Serial.println("Paused"); }
else { player.start(); Serial.println("Resumed"); }
playing = !playing;
});
handleButton(buttonNextPin, 1, [](){ player.next(); Serial.println("Next track"); });
handleButton(buttonPrevPin, 2, [](){ player.previous(); Serial.println("Previous track"); });
// Serial commands from USB Serial monitor
if (Serial.available()) {
String cmd = Serial.readStringUntil('\\n');
cmd.trim();
if (cmd == "stop") { player.stop(); Serial.println("Stopped"); }
else if (cmd == "vol+") { static int v=20; v = min(30, v+2); player.volume(v); Serial.print("Vol "); Serial.println(v); }
else if (cmd == "vol-") { static int v=20; v = max(0, v-2); player.volume(v); Serial.print("Vol "); Serial.println(v); }
else if (cmd.startsWith("play ")) {
int n = cmd.substring(5).toInt();
player.play(n);
Serial.print("Playing: "); Serial.println(n);
}
else if (cmd == "rand") {
int r = random(1, 10); // example range
player.play(r);
Serial.print("Playing random: "); Serial.println(r);
} else {
Serial.println("Unknown command");
}
}
}
// Generic button handler with lambda action
void handleButton(int pin, int idx, void (*onPress)()) {
static bool lastState[3] = {HIGH, HIGH, HIGH};
bool reading = digitalRead(pin);
if (reading != lastState[idx]) {
lastDebounce[idx] = millis();
}
if ((millis() - lastDebounce[idx]) > debounceDelay) {
if (reading == LOW && lastState[idx] == HIGH) { // pressed (active low)
onPress();
}
}
lastState[idx] = reading;
}
/*
Use hardware serial (Serial1) on boards that have it (Mega, Leonardo, Micro).
Wiring:
Mega Serial1 TX (pin 18) -> DFPlayer RX (through 1k resistor)
Mega Serial1 RX (pin 19) <- DFPlayer TX
*/
#include "DFRobotDFPlayerMini.h"
DFRobotDFPlayerMini player;
HardwareSerial &dfSerial = Serial1;
void setup() {
Serial.begin(115200);
dfSerial.begin(9600);
if (!player.begin(dfSerial)) {
Serial.println("DFPlayer not found");
while(true) delay(1000);
}
player.volume(25);
player.playFolder(1, 1); // play folder 01 track 01
}
void loop() {
// Repeat an announcement every 15 seconds for demo
static unsigned long t = 0;
if (millis() - t > 15000) {
t = millis();
player.play(2);
}
}
/*
ESP32 example using Serial2 (more reliable than SoftwareSerial)
Wiring:
ESP32 GPIO17 (U2TX) -> DFPlayer RX (with 1k resistor if needed)
ESP32 GPIO16 (U2RX) <- DFPlayer TX
*/
#include "DFRobotDFPlayerMini.h"
DFRobotDFPlayerMini player;
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, 16, 17); // RX, TX
delay(200);
if (!player.begin(Serial2)) {
Serial.println("DFPlayer init failed");
while(true) delay(1000);
}
player.volume(18);
player.play(1);
}
void loop() {
static unsigned long last = 0;
if (millis() - last > 60000) {
last = millis();
player.play(3); // periodic announcement
}
}
esphome:
name: dfplayer_doorbell
platform: ESP32
board: esp32dev
wifi:
ssid: "YOUR_SSID"
password: "YOUR_PASS"
logger:
level: DEBUG
uart:
id: uart_dfp
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
dfplayer:
id: dfp
uart_id: uart_dfp
on_card_online:
then:
- logger.log: "DFPlayer card online"
on_card_offline:
then:
- logger.log: "DFPlayer card removed"
sensor:
- platform: dfplayer
dfplayer_id: dfp
type: device_info
name: "DFPlayer Device Info"
switch:
- platform: template
name: "DFPlayer Play 0001"
turn_on_action:
- dfplayer.play_mp3:
dfplayer: dfp
file: 1
- platform: template
name: "DFPlayer Stop"
turn_on_action:
- dfplayer.stop: dfp
- platform: template
name: "DFPlayer Volume +"
turn_on_action:
- dfplayer.set_volume:
dfplayer: dfp
volume: 25
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: True
name: "Play Button"
on_press:
- dfplayer.play_mp3:
dfplayer: dfp
file: 2
number:
- platform: template
name: "Random Track Number"
id: random_number
optimistic: true
min_value: 1
max_value: 10
step: 1
initial_value: 1
script:
- id: play_random
then:
- lambda: |-
int r = (int) (id(random_number).state);
ESP_LOGD("dfplayer", "Playing random file %d", r);
- dfplayer.play_mp3:
dfplayer: dfp
file: !lambda 'return (int)id(random_number).state;'
on_boot:
priority: 600
then:
- delay: 2s
- dfplayer.play_mp3:
dfplayer: dfp
file: 1