DFPlayer Mini MP3 Player Module — Arduino / ESP32 / ESP8266 Audio Voice Board


Product Overview

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.

Key Features

    • DFPlayer Mini MP3 Player Module – Compact audio board compatible with Arduino, ESP32, ESP8266, Raspberry Pi, and other microcontrollers
    • Plays MP3 / WAV / WMA files directly from micro-SD card (supports FAT16/FAT32 up to 32GB)
    • Built-in DAC + amplifier with direct speaker output (no external amp required)
    • Ideal for sound effects, voice prompts, alarms, smart home audio, electronics projects, and animatronics
    • Easy serial control (UART) for play, pause, stop, volume, and track selection
    • Includes hardware-trigger inputs (IO1/IO2) for button-activated sound playback
    • Small 22×15 mm design — perfect for DIY, hobby projects, and embedded systems
    • Stable 3.2–5V input range; works with Arduino UNO, Nano, Mega, ESP32, ESP8266 and more
    • Great for prop-making, robotics, toys, Halloween effects, and model railways

  • Pinout

    PinDescription
    VCC3.2V–5V Power Input (5V recommended if driving speaker)
    GNDGround (common ground with MCU required)
    RXSerial Receive (connect to MCU TX; add ~1kΩ resistor if MCU is 5V)
    TXSerial Transmit (connect to MCU RX)
    SPK1 / SPK2Speaker outputs — connect a small 3W speaker (bridge)
    DAC_L / DAC_RLine-level outputs for external amp
    IO1 / IO2Hardware trigger pins (tie to GND to trigger in IO mode)

    Perfect For


    Why Buy This Module?

    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.


    Quick Specs


    Arduino Code Examples (Drop-in Ready)

    Arduino UNO — Full-featured (SoftwareSerial)
    /*
     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;
    }
        
    Arduino Mega / Leonardo — Hardware Serial (Serial1) example
    /*
     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 — Serial2 example (recommended for IoT)
    /*
     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 Example (Expanded)

    Click to show ESPHome YAML (ESP32)
    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
        

    What You Get