Building a Music Player with ESP32 and DFPlayer Mini

In this blog, we’ll explore how to create a simple yet functional music player using the ESP32 microcontroller, DFPlayer Mini module, and three buttons to control the playback. This project is a great way to understand the basics of serial communication and how to interface audio modules with microcontrollers. We’ll dive into the hardware setup, code, and the communication protocol used between the ESP32 and DFPlayer Mini.

Introduction to Components

  1. ESP32

The ESP32 is a powerful microcontroller with integrated Wi-Fi and Bluetooth, making it ideal for IoT projects. With its dual-core processor and a wide range of GPIO pins, the ESP32 can handle multiple tasks simultaneously.

  1. DFPlayer Mini

The DFPlayer Mini is a small, low-cost MP3 player module that can play music from a microSD card. It can be controlled via a serial interface, making it easy to integrate with microcontrollers like the ESP32. The DFPlayer Mini has an onboard DAC and amplifier, allowing it to directly drive small speakers.

  1. Push Buttons

We’ll use three push buttons for user input: one for play/pause, one for skipping to the next track, and one for returning to the previous track. These buttons will be connected to the GPIO pins of the ESP32.

Communication Protocol: UART

The communication between the ESP32 and the DFPlayer Mini is handled via UART (Universal Asynchronous Receiver/Transmitter). UART is a simple, robust serial communication protocol widely used in embedded systems.

How UART Works

Why Use UART for DFPlayer Mini?

The DFPlayer Mini supports various modes of communication, including UART, AD key mode, and IO mode. UART is preferred because it offers greater control over playback functions, including the ability to select tracks, control volume, and manage the playback state (play, pause, stop, etc.). This flexibility is essential for creating a responsive music player.

Hardware Setup

Components Needed

Circuit Diagram

Here’s how to wire everything together:

  1. DFPlayer Mini to ESP32:
    • TX (DFPlayer Mini) -> RX (ESP32)
    • RX (DFPlayer Mini) -> TX (ESP32)
    • VCC (DFPlayer Mini) -> 5V (ESP32)
    • GND (DFPlayer Mini) -> GND (ESP32)
    • SPK_1 and SPK_2 (DFPlayer Mini) -> Speaker
  2. Buttons to ESP32:
    • Play/Pause Button: One side to GPIO 13, other side to GND
    • Next Track Button: One side to GPIO 12, other side to GND
    • Previous Track Button: One side to GPIO 14, other side to GND

Explanation

Writing the Code

Libraries Required

To get started, you’ll need the DFPlayerMini_Fast library, which simplifies communication with the DFPlayer Mini. You can install it via the Arduino IDE’s Library Manager.

Code Explanation

Here’s the complete code for the project:

#include <Arduino.h>

#include “DFRobotDFPlayerMini.h”

 

#define PLAY_PAUSE_PIN 13

#define NEXT_TRACK_PIN 12

#define PREV_TRACK_PIN 14

 

HardwareSerial mySoftwareSerial(1); // Use Hardware Serial port 1

DFRobotDFPlayerMini myDFPlayer;

 

int songNumber = 1;

int songsCount = 1;

bool isPlaying = true;

 

void nextSong();

void prevSong();

void checkButtons();

 

void setup() {

pinMode(PLAY_PAUSE_PIN, INPUT_PULLUP);

pinMode(NEXT_TRACK_PIN, INPUT_PULLUP);

pinMode(PREV_TRACK_PIN, INPUT_PULLUP);

 

mySoftwareSerial.begin(9600, SERIAL_8N1, 16, 17);  // Speed, type, RX, TX

Serial.begin(115200);

 

Serial.println();

Serial.println(F(“DFRobot DFPlayer Mini”));

Serial.println(F(“Initializing DFPlayer … (May take 3~5 seconds)”));

 

while (!myDFPlayer.begin(mySoftwareSerial)) {

Serial.println(F(“Unable to begin”));

delay(500);

}

Serial.println(F(“DFPlayer Mini online.”));

 

songsCount = myDFPlayer.readFileCountsInFolder(1);

myDFPlayer.volume(20); // Set initial volume

myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);

myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);

myDFPlayer.playFolder(1, songNumber);

}

 

void loop() {

if (myDFPlayer.available()) {

uint8_t type = myDFPlayer.readType();

if (type == DFPlayerPlayFinished) {

nextSong();

}

}

checkButtons();

}

 

void nextSong() {

songNumber = (songNumber % songsCount) + 1;

myDFPlayer.playFolder(1, songNumber);

}

 

void prevSong() {

songNumber = (songNumber – 2 + songsCount) % songsCount + 1;

myDFPlayer.playFolder(1, songNumber);

}

 

void checkButtons() {

if (digitalRead(NEXT_TRACK_PIN) == LOW) {

nextSong();

delay(500); // Debounce delay

}

 

if (digitalRead(PREV_TRACK_PIN) == LOW) {

prevSong();

delay(500); // Debounce delay

}

 

if (digitalRead(PLAY_PAUSE_PIN) == LOW) {

isPlaying = !isPlaying;

if (isPlaying) {

myDFPlayer.start();

} else {

myDFPlayer.pause();

}

delay(500); // Debounce delay

}

}

 

Code Breakdown

Steps to Make the IoT Music Player Project

Step 1: Gather the Components

Step 2: Connect the Hardware

  1. DFPlayer Mini:
    • VCC to 5V on ESP32
    • GND to GND on ESP32
    • RX to GPIO 16 (TX of ESP32)
    • TX to GPIO 17 (RX of ESP32)
    • SPK1 and SPK2 to a speaker
  1. Buttons:
    • Play/Pause Button: Connect to GPIO 13.
    • Next Track Button: Connect to GPIO 12.
    • Previous Track Button: Connect to GPIO 14.
    • Other Pin of Each Button to GND.

Step 3: Prepare the Code

  1. Open the Arduino IDE and install the DFRobotDFPlayerMini library.
  2. Copy the provided code into a new sketch.

Step 4: Upload the Code to ESP32

  1. Connect the ESP32 to your computer via USB.
  2. Select the correct board and port in the Arduino IDE.
  3. Upload the code.

Step 5: Test Your Music Player

  1. Insert the SD card with MP3 files into the DFPlayer Mini.
  2. Power up your ESP32.
  3. Use the buttons to play/pause, switch to the next track, or go back to the previous track.

Conclusion

This project is a great way to learn about interfacing the ESP32 with peripheral devices using UART communication. By combining the ESP32, DFPlayer Mini, and some basic buttons, we’ve created a functional music player with play/pause, next, and previous track controls.

Extending the Project

Once you’ve mastered this basic setup, you can extend the project in various ways. For instance, you could add a display to show the current track or integrate a remote control for easier navigation. You might even consider designing a custom PCB to house all the components neatly. When it comes to producing the final version of your project, working with a reliable PCBA manufacturing service ensures that your PCB assembly is handled with precision and quality.

This project not only enhances your understanding of UART communication but also provides a solid foundation for more complex embedded systems projects.

Happy building!