ESP32 - Mini Mp3 Player Module
The ESP32 is a versatile 3.3V microcontroller with WiFi, Bluetooth, and multiple hardware serial ports. Combined with the DIYables Mini Mp3 Player module, you can build anything from a simple sound effect board to a WiFi-controlled jukebox.
This tutorial walks you through:
Connecting the Mini Mp3 Player to an ESP32 — directly, without a resistor.
Loading mp3 files onto the SD card correctly.
Playing, pausing, resuming, stopping, and skipping tracks.
Adjusting volume with physical buttons.
Repeating tracks, shuffling, and organizing audio into folders.
Monitoring playback status from your code.
Or you can buy the following kits:
Disclosure: Some of the links in this section are Amazon affiliate links, meaning we may earn a commission at no additional cost to you if you make a purchase through them. Additionally, some links direct you to products from our own brand,
DIYables .
No resistor required. The ESP32 operates at 3.3V — the same voltage the Mini Mp3 Player's UART expects.
The DIYables Mini Mp3 Player is a tiny board built on the YX5200-24SS chip. It decodes mp3 files from a micro SD card, and can directly drive a speaker through its built-in 3W amplifier. Alternatively, use the DAC pins to feed an external amplifier for louder output.
Everything is controlled via serial commands at 9600 baud:
Transport: play, pause, resume, stop, next, previous
Volume: 31 levels (0–30)
Equalizer: Normal, Pop, Rock, Jazz, Classic, Bass
Repeat: loop single track, loop folder, loop all tracks, random shuffle
Folders: play from numbered directories on the card
Advertisements: temporarily interrupt playback, then continue
Queries: read track number, volume, play state, track count
| Pin | Purpose |
| VCC | 3.2V to 5.0V power input |
| GND | Ground |
| RX | Serial data input (connect to ESP32 TX pin) |
| TX | Serial data output (connect to ESP32 RX pin) |
| SPK_1 | Speaker + (built-in amp, 3W max) |
| SPK_2 | Speaker − |
| DAC_R | Right channel line output |
| DAC_L | Left channel line output |
| BUSY | LOW = playing, HIGH = stopped |
| IO_1 | Short press → prev track; long press → vol down |
| IO_2 | Short press → next track; long press → vol up |
The ESP32 uses 3.3V logic natively, so you wire the serial lines directly — no level shifting or resistors needed.
We recommend using Serial2 (available by default on most ESP32 DevKit boards):
| Mini Mp3 Player | ESP32 | Notes |
| VCC | 3.3V | Or 5V from VIN if available |
| GND | GND | |
| RX | GPIO 17 (TX2) | Direct connection |
| TX | GPIO 16 (RX2) | Direct connection |
| SPK_1 | Speaker + | |
| SPK_2 | Speaker − | |

This image is created using Fritzing. Click to enlarge image
Tip: If your ESP32 variant does not expose GPIO 16/17 (some DevKit-C V4 boards use them for PSRAM), you can reassign Serial2 pins in code:
Serial2.begin(9600, SERIAL_8N1, 4, 5);
If you're unfamiliar with how to supply power to the ESP32 and other components, you can find guidance in the following tutorial: The best way to Power ESP32 and sensors/displays.
Format as FAT16 or FAT32.
Place mp3 files at the root:
/001.mp3
/002.mp3
/003.mp3
For organized playback, use numbered folders:
/01/001.mp3
/01/002.mp3
/02/001.mp3
Critical notes:
Track numbers start at 1.
The module indexes tracks by the order they were copied to the card, not by filename. Always format first, then copy sequentially.
Folder names: 01–99 (2-digit), file names: 001–255 (3-digit).
Connect the ESP32 to your computer.
In the Arduino IDE, select your ESP32 board variant and the correct port.
Open the Libraries manager.
Search "DIYables_MiniMp3" and install the library by DIYables.
Zero dependencies — works out of the box.
#include <DIYables_MiniMp3.h>
DIYables_MiniMp3 mp3;
void setup() {
Serial.begin(115200);
Serial2.begin(9600);
mp3.begin(Serial2);
delay(1000);
mp3.setVolume(25);
}
void loop() {
}
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(25);
Serial.println("Playing track 1...");
mp3.play(1);
}
void loop()
{
}
Load the SD card, wire the module, connect the ESP32 via USB.
Select your ESP32 board in the IDE and upload.
| Method | What Happens | Code Example |
| play(n) | Plays track number n | mp3.play(1) |
| playNext() | Moves to the next track | mp3.playNext() |
| playPrevious() | Goes back one track | mp3.playPrevious() |
| pause() | Freezes playback | mp3.pause() |
| resume() | Picks up where you left off | mp3.resume() |
| stop() | Ends playback completely | mp3.stop() |
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
int currentTrack = 1;
int totalTracks = 3;
unsigned long lastTrackTime = 0;
unsigned long trackDuration = 5000;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(20);
Serial.println("Playing track 1...");
mp3.play(currentTrack);
lastTrackTime = millis();
}
void loop()
{
if (millis() - lastTrackTime >= trackDuration)
{
currentTrack++;
if (currentTrack > totalTracks)
currentTrack = 1;
Serial.print("Playing track ");
Serial.println(currentTrack);
mp3.play(currentTrack);
lastTrackTime = millis();
}
}
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
const int BUTTON_VOL_UP = 1;
const int BUTTON_VOL_DOWN = 3;
int volume = 15;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
pinMode(BUTTON_VOL_UP, INPUT_PULLUP);
pinMode(BUTTON_VOL_DOWN, INPUT_PULLUP);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(volume);
mp3.loopTrack(1);
Serial.print("Volume: ");
Serial.println(volume);
}
void loop()
{
if (digitalRead(BUTTON_VOL_UP) == LOW)
{
if (volume < 30)
{
volume++;
mp3.setVolume(volume);
Serial.print("Volume: ");
Serial.println(volume);
}
delay(200);
}
if (digitalRead(BUTTON_VOL_DOWN) == LOW)
{
if (volume > 0)
{
volume--;
mp3.setVolume(volume);
Serial.print("Volume: ");
Serial.println(volume);
}
delay(200);
}
}
| Method | Action | Example |
| setVolume(v) | Jump to level v | mp3.setVolume(20) |
| volumeUp() | Increment by 1 | mp3.volumeUp() |
| volumeDown() | Decrement by 1 | mp3.volumeDown() |
| getVolume() | Read current level | mp3.getVolume() |
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
const int BUTTON_NEXT = 1;
const int BUTTON_PREV = 3;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
pinMode(BUTTON_NEXT, INPUT_PULLUP);
pinMode(BUTTON_PREV, INPUT_PULLUP);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(20);
mp3.play(1);
Serial.println("Press NEXT or PREV button to change track");
}
void loop()
{
if (digitalRead(BUTTON_NEXT) == LOW)
{
Serial.println("Next track");
mp3.playNext();
delay(300);
}
if (digitalRead(BUTTON_PREV) == LOW)
{
Serial.println("Previous track");
mp3.playPrevious();
delay(300);
}
}
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
const int BUTTON_PIN = 1;
bool paused = false;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(20);
mp3.play(1);
Serial.println("Playing. Press button to pause/resume.");
}
void loop()
{
if (digitalRead(BUTTON_PIN) == LOW)
{
if (paused)
{
mp3.resume();
Serial.println("Resumed");
}
else
{
mp3.pause();
Serial.println("Paused");
}
paused = !paused;
delay(300);
}
}
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(25);
mp3.setEQ(DIYables_MiniMp3::EQ_NORMAL);
Serial.println("Playing track 1 on loop...");
mp3.loopTrack(1);
}
void loop()
{
}
| Method | Behavior | Example |
| loopTrack(n) | Endlessly repeat track n | mp3.loopTrack(1) |
| loopFolder(f) | Repeat all tracks in folder f | mp3.loopFolder(1) |
| loopAll() | Repeat all tracks | mp3.loopAll() |
| stopLoop() | Cancel active loop | mp3.stopLoop() |
| shuffle() | Randomize playback | mp3.shuffle() |
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(20);
Serial.println("Playing folder 01, track 001...");
mp3.playFolder(1, 1);
delay(5000);
Serial.println("Playing folder 01, track 002...");
mp3.playFolder(1, 2);
delay(5000);
Serial.println("Playing folder 02, track 001...");
mp3.playFolder(2, 1);
}
void loop()
{
}
| Method | Description | Example |
| playFolder(f, t) | Play track t from folder f | mp3.playFolder(1, 1) |
| playLargeFolder(f, t) | Large folder (15 folders, 3000 tracks) | mp3.playLargeFolder(1, 2000) |
| playFromMP3Folder(t) | Play from /mp3 folder | mp3.playFromMP3Folder(1) |
#include <DIYables_MiniMp3.h>
#include <SoftwareSerial.h>
SoftwareSerial mp3Serial(25, 26);
DIYables_MiniMp3 mp3;
void setup()
{
Serial.begin(9600);
mp3Serial.begin(9600);
mp3.begin(mp3Serial);
delay(1000);
mp3.setVolume(20);
Serial.println("=== DIYables Mini Mp3 Player ===");
Serial.println("Commands:");
Serial.println(" 1-9 Play track number");
Serial.println(" + Volume up");
Serial.println(" - Volume down");
Serial.println(" p Pause");
Serial.println(" r Resume");
Serial.println(" s Stop");
Serial.println(" n Next track");
Serial.println(" b Previous track");
Serial.println(" ? Show status");
Serial.println("================================");
}
void loop()
{
if (Serial.available())
{
char cmd = Serial.read();
switch (cmd)
{
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
Serial.print("Playing track ");
Serial.println(cmd - '0');
mp3.play(cmd - '0');
break;
case '+':
Serial.println("Volume up");
mp3.volumeUp();
break;
case '-':
Serial.println("Volume down");
mp3.volumeDown();
break;
case 'p':
Serial.println("Paused");
mp3.pause();
break;
case 'r':
Serial.println("Resumed");
mp3.resume();
break;
case 's':
Serial.println("Stopped");
mp3.stop();
break;
case 'n':
Serial.println("Next track");
mp3.playNext();
break;
case 'b':
Serial.println("Previous track");
mp3.playPrevious();
break;
case '?':
{
Serial.println("--- Status ---");
int16_t vol = mp3.getVolume();
Serial.print("Volume: ");
Serial.println(vol);
int16_t track = mp3.getCurrentTrack();
Serial.print("Current track: ");
Serial.println(track);
bool playing = mp3.isPlaying();
Serial.print("Playing: ");
Serial.println(playing ? "Yes" : "No");
int16_t total = mp3.getTrackCount();
Serial.print("Total tracks: ");
Serial.println(total);
Serial.println("--------------");
break;
}
default:
break;
}
}
}
| Command | Effect |
| 1–9 | Play track |
| + / − | Volume |
| p / r / s | Pause / Resume / Stop |
| n / b | Next / Previous |
| ? | Status |
| Constant | ID | Character |
| DIYables_MiniMp3 | | EQ_NORMAL | 0 | Neutral |
| DIYables_MiniMp3 | | EQ_POP | 1 | Bright |
| DIYables_MiniMp3 | | EQ_ROCK | 2 | Punchy |
| DIYables_MiniMp3 | | EQ_JAZZ | 3 | Warm |
| DIYables_MiniMp3 | | EQ_CLASSIC | 4 | Balanced |
| DIYables_MiniMp3 | | EQ_BASS | 5 | Deep |
mp3.setEQ(DIYables_MiniMp3::EQ_BASS);
These functions block for up to 100 ms while waiting for the module's reply. They return −1 if no response arrives.
| Function | Return | Description |
| isPlaying() | bool | true during active playback |
| getVolume() | int16_t | Current volume (0–30) |
| getEQ() | int16_t | Active EQ (0–5) |
| getTrackCount() | int16_t | Total tracks on SD |
| getCurrentTrack() | int16_t | Track number playing now |
| getFolderCount() | int16_t | Total folders on SD |
| getTrackCountInFolder(f) | int16_t | Tracks in folder f |