DFPlayer Mini Arduino: riprodurre MP3, scheda SD e altoparlante
Come usare il DFPlayer Mini con Arduino: resistenza da 1k su RX, scheda SD e nomi 0001.mp3, codice della libreria, pulsanti, altoparlante, ESP32 e Pico.
Il DFPlayer Mini è il modo più economico e semplice per riprodurre MP3 con Arduino: decodifica da solo i file audio di una scheda microSD, pilota direttamente un altoparlante con il suo piccolo amplificatore integrato e riceve i comandi da Arduino tramite un collegamento seriale a soli due fili. A differenza dei bip di un buzzer, può riprodurre canzoni, voce, melodie per il campanello o avvisi parlati come "La porta è rimasta aperta". Quasi tutti quelli che lo collegano per la prima volta incontrano gli stessi problemi: niente audio, l'altoparlante gracchia, i file partono nell'ordine sbagliato o il monitor seriale mostra "Unable to begin". Questa guida li risolve uno per uno e spiega da dove nascono.
Prima scoprirai i pin del modulo e perché sulla linea RX si mette una resistenza da 1 kΩ. Poi vedrai come preparare la scheda SD in FAT32, dare ai file nomi secondo lo schema 0001.mp3 e cartelle 01, riprodurre il primo suono con la libreria DFRobotDFPlayerMini, regolare volume ed equalizzatore, cambiare brano con i pulsanti e scegliere l'altoparlante giusto o un amplificatore esterno. Le ultime sezioni contengono la soluzione passo passo all'errore "Unable to begin", un lettore MP3 con ESP32 controllato da una pagina web e un esempio in MicroPython senza librerie per il Raspberry Pi Pico. Se ti basta un bip o una melodia semplice, un buzzer è la scelta più semplice.

Cos'è il DFPlayer Mini e come funziona?
Il DFPlayer Mini è un lettore MP3 autonomo composto da un chip decoder MP3, un DAC a 24 bit, uno slot per scheda microSD e un piccolo amplificatore mono. Arduino deve solo inviare brevi comandi come "riproduci il brano 3" o "imposta il volume a 20"; leggere il file dalla scheda, decodificare l'audio compresso e pilotare l'altoparlante sono compiti del modulo. Per questo anche un Arduino Uno con 2 KB di RAM riesce a riprodurre musica senza fatica. I comandi viaggiano a 9600 baud in pacchetti da 10 byte, e il modulo risponde con lo stesso formato quando un brano finisce, quando la scheda viene inserita o tolta o quando si verifica un errore. Il chip sulla scheda dipende dal produttore (YX5200-24SS, MH2024K-24SS, GD3200B e altri). Tutti capiscono gli stessi comandi, ma possono rispondere con tempi diversi, un dettaglio che conterà più avanti con l'errore "Unable to begin". Il modulo si può controllare in tre modi: tramite porta seriale (UART), con i pulsanti IO o con una scala di resistenze ADKEY.
| Caratteristica | Valore |
|---|---|
| File supportati | MP3, WAV, WMA |
| Frequenze di campionamento | 8 / 11,025 / 12 / 16 / 22,05 / 24 / 32 / 44,1 / 48 kHz |
| DAC | 24 bit; 90 dB di gamma dinamica, 85 dB di rapporto segnale/rumore |
| Memoria | Scheda microSD (TF) fino a 32 GB, FAT16 o FAT32; supporta anche le chiavette USB |
| Capacità cartelle | Fino a 100 cartelle, 255 file per cartella |
| Volume | 30 livelli (0–30) |
| Equalizzatore (EQ) | 6 modalità: Normal, Pop, Rock, Jazz, Classic, Bass |
| Uscita altoparlante | Amplificatore mono integrato, altoparlanti sotto i 3 W |
| Uscita di linea | DAC_L e DAC_R: stereo, per cuffie o amplificatore esterno |
| Alimentazione | 3,2–5,0 V (tipica 4,2 V) |
| Corrente a riposo | Circa 20 mA |
| Comunicazione | UART, 9600 baud, 8N1 |
| Dimensioni | 20 × 20 mm |
Pinout del DFPlayer Mini
| Pin | Nome | Funzione |
|---|---|---|
| 1 | VCC | Ingresso alimentazione, 3,2–5,0 V |
| 2 | RX | Ingresso seriale: va al pin TX della scheda tramite una resistenza da 1 kΩ |
| 3 | TX | Uscita seriale: va al pin RX della scheda |
| 4 | DAC_R | Uscita di linea canale destro (cuffie o amplificatore) |
| 5 | DAC_L | Uscita di linea canale sinistro (cuffie o amplificatore) |
| 6 e 8 | SPK_1, SPK_2 | Uscita altoparlante: qui vanno i due capi di un altoparlante sotto i 3 W |
| 7 | GND | Massa |
| 9 | IO_1 | Pressione breve verso GND: brano precedente; pressione lunga: volume giù |
| 10 | GND | Massa |
| 11 | IO_2 | Pressione breve verso GND: brano successivo; pressione lunga: volume su |
| 12 | ADKEY1 | Ingresso per più pulsanti tramite scala di resistenze |
| 13 | ADKEY2 | Secondo ingresso per scala di resistenze |
| 14 | USB+ | D+ per una chiavetta USB |
| 15 | USB− | D− per una chiavetta USB |
| 16 | BUSY | LOW durante la riproduzione, HIGH a riposo |
Se usi la porta seriale, ti servono solo i pin VCC, GND, RX, TX e quelli dell'altoparlante. Il pin BUSY ti dice se un brano è finito senza bisogno di comunicazione seriale, e anche il piccolo LED sulla scheda si accende durante la riproduzione. I pin IO_1 e IO_2 permettono al modulo di funzionare perfino senza Arduino: con un pulsante tra ciascun pin e GND, una pressione breve cambia brano e una lunga regola il volume. Anche i pulsanti collegati ai pin ADKEY tramite resistenze di valore diverso possono avviare brani precisi. Bastano quindi una batteria, un altoparlante e due pulsanti per costruire un campanello o un giocattolo parlante senza microcontrollore. I pin USB+ e USB− servono a riprodurre da una chiavetta USB al posto della scheda SD e nella maggior parte dei progetti restano liberi.
Collegamento del DFPlayer Mini ad Arduino e la resistenza da 1k su RX
| Pin DFPlayer | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 5V (VIN) | VBUS (USB 5 V, pin 40) |
| GND | GND | GND | GND |
| RX | D11 tramite una resistenza da 1 kΩ | GPIO 17 (TX2) tramite una resistenza da 1 kΩ | GP0 (UART0 TX) tramite una resistenza da 1 kΩ |
| TX | D10 | GPIO 16 (RX2) | GP1 (UART0 RX) |
| SPK_1 e SPK_2 | I due capi dell'altoparlante | I due capi dell'altoparlante | I due capi dell'altoparlante |
| BUSY (facoltativo) | D5 | Non usato | Non usato |



Le linee dati si incrociano: il TX del modulo va all'RX della scheda e il suo RX al TX della scheda. La porta seriale hardware dell'Uno su D0 e D1 serve per caricare gli sketch via USB e per il monitor seriale, quindi colleghiamo il modulo a D10 (RX) e D11 (TX) con SoftwareSerial. La resistenza da 1 kΩ in serie all'ingresso RX del modulo non è un dettaglio da poco. Il chip del DFPlayer lavora con logica a 3,3 V, mentre il pin TX dell'Uno fornisce 5 V. Senza resistenza, la differenza fa scorrere corrente nei diodi di protezione dell'ingresso del chip; questa corrente sollecita il chip e provoca il fruscio e i clic che si sentono nell'altoparlante durante la comunicazione seriale. Se fai il calcolo con la legge di Ohm, vedrai che 1 kΩ limita questa corrente a circa 1–2 mA, mentre il segnale a 9600 baud non ne risente. Una resistenza molto più grande, come 10 kΩ, può indebolire il segnale fino a interrompere la comunicazione. L'uscita TX del modulo si collega direttamente all'Uno, perché l'Uno legge 3,3 V come HIGH (la soglia è di circa 3,0 V).
Preparare la scheda SD: FAT32, cartelle e nomi 0001.mp3
Il DFPlayer Mini legge schede microSD fino a 32 GB formattate in FAT16 o FAT32. Le schede da 64 GB in su escono di fabbrica in exFAT, un formato che il modulo non legge; per qualche centinaio di brani una scheda da 1–16 GB è più che sufficiente. Codificare gli MP3 a 128–192 kbps e 44,1 kHz è la scelta più sicura per compatibilità e velocità di lettura. Il modulo riconosce i file dal numero, non dal nome; a seconda della funzione con cui li riproduci, i nomi di cartelle e file devono seguire uno schema preciso:
| Posizione sulla scheda | Esempio | Funzione della libreria | Regola |
|---|---|---|---|
| Cartella principale | /0001.mp3, /0002.mp3 | play(1) | Riproduce nell'ordine in cui i file sono stati copiati sulla scheda, non per nome |
| Cartelle numerate | /01/001.mp3 … /99/255.mp3 | playFolder(1, 1) | Nome cartella a 2 cifre (01–99), nome file a 3 cifre (001–255) |
| Cartella mp3 | /mp3/0001.mp3 | playMp3Folder(1) | Nome file a 4 cifre; il file viene trovato tramite il numero nel nome |
| Cartella advert | /advert/0001.mp3 | advertise(1) | Interrompe il brano in corso e lo riprende alla fine dell'annuncio |
| Cartelle grandi | /01/0001.mp3 … /15/3000.mp3 | playLargeFolder(1, 1) | Al massimo 15 cartelle, 3000 file per cartella, nomi a 4 cifre |
- Formatta la scheda sul computer in FAT32 (su Windows: tasto destro > Formatta; su macOS: Utility Disco > Inizializza > MS-DOS (FAT)).
- Crea nella cartella principale una cartella chiamata mp3 e, se serve, cartelle numerate come 01 e 02.
- Rinomina i file come 0001.mp3, 0002.mp3 (nelle cartelle numerate: 001.mp3). Dopo il numero puoi aggiungere una descrizione, come 0001_ciao.mp3; il modulo guarda solo le cifre iniziali.
- Se riprodurrai i file della cartella principale con play(), copiali uno alla volta e in ordine; copiandoli tutti insieme l'ordine può mescolarsi.
- Espelli la scheda in modo sicuro e inseriscila nel modulo a modulo spento; inserirla o toglierla durante il funzionamento può danneggiare i file.
La libreria DFRobotDFPlayerMini e un primo sketch di prova
- Nell'Arduino IDE apri il Gestore librerie, scrivi DFRobotDFPlayerMini e installa la libreria di DFRobot. L'installazione è spiegata nei dettagli in Come aggiungere una libreria ad Arduino.
- Copia almeno un MP3 nella cartella principale della scheda SD, inserisci la scheda nel modulo e monta il circuito come nella tabella.
- Carica lo sketch qui sotto e apri il monitor seriale a 115200 baud.
- Dopo qualche secondo dovresti vedere "DFPlayer Mini online." e il numero di file sulla scheda, e poi sentire il primo brano.
1#include <SoftwareSerial.h>
2#include <DFRobotDFPlayerMini.h>
3
4SoftwareSerial dfSerial(10, 11); // RX = D10 ← DFPlayer TX, TX = D11 → 1 kΩ → DFPlayer RX
5DFRobotDFPlayerMini player;
6
7void setup() {
8 Serial.begin(115200);
9 dfSerial.begin(9600); // DFPlayer her zaman 9600 baud / DFPlayer always uses 9600 baud
10 Serial.println(F("DFPlayer baslatiliyor / Starting DFPlayer..."));
11
12 if (!player.begin(dfSerial)) { // reset gönderir, kartı bekler / sends a reset, waits for the card
13 Serial.println(F("Unable to begin: kablolari ve SD karti kontrol et / check wiring and SD card"));
14 while (true) {} // burada dur / stop here
15 }
16 Serial.println(F("DFPlayer Mini online."));
17 Serial.print(F("Karttaki dosya / Files on card: "));
18 Serial.println(player.readFileCounts()); // gizli dosyalar da sayılır / hidden files are counted too
19
20 player.volume(20); // ses seviyesi 0-30 / volume 0-30
21 player.EQ(DFPLAYER_EQ_NORMAL); // ekolayzır: normal / equalizer: normal
22 player.play(1); // kökteki ilk dosya / first file in the root
23}
24
25void loop() {
26 if (player.available()) { // modülden bildirim geldi / a message arrived from the module
27 uint8_t type = player.readType();
28 int value = player.read();
29 if (type == DFPlayerPlayFinished) {
30 Serial.print(F("Parca bitti / Track finished: "));
31 Serial.println(value);
32 } else if (type == DFPlayerError) {
33 Serial.print(F("Hata kodu / Error code: "));
34 Serial.println(value); // kodların anlamı tabloda / meanings are in the table
35 } else if (type == DFPlayerCardRemoved) {
36 Serial.println(F("SD kart cikarildi / SD card removed"));
37 }
38 }
39}
40| Funzione | Cosa fa |
|---|---|
| begin(seriale, isACK, doReset) | Avvia il modulo; di default invia un reset e attende il messaggio che indica che la scheda è pronta |
| volume(0–30) | Imposta il volume; volumeUp() e volumeDown() lo cambiano di un livello |
| EQ(DFPLAYER_EQ_POP) | Equalizzatore: NORMAL, POP, ROCK, JAZZ, CLASSIC, BASS |
| play(n) | Riproduce l'n-esimo file della cartella principale (in ordine di copia) |
| next() / previous() | Brano successivo / precedente |
| pause() / start() | Mette in pausa / riprende da dove si era fermato |
| stop() | Ferma la riproduzione |
| loop(n) | Ripete il brano n senza fine |
| enableLoopAll() / randomAll() | Riproduce tutti i brani in loop / in ordine casuale |
| readState() / readVolume() / readFileCounts() | Interroga lo stato, il volume e il numero di file sulla scheda |
| available() / readType() / read() | Legge i messaggi del modulo (brano finito, errore, scheda rimossa) |
Volume, equalizzatore e annunci in sequenza con il pin BUSY
Il volume va da 0 a 30. Con un altoparlante piccolo, 15–20 basta per la maggior parte delle stanze; oltre 25, soprattutto con un'alimentazione debole, il suono può iniziare a distorcere (clipping) e il modulo a riavviarsi. L'equalizzatore cambia l'equilibrio tra bassi e alti; sugli altoparlanti piccoli la modalità BASS rende facilmente il suono ovattato, quindi parti da NORMAL. Le cartelle numerate sono comodissime per i progetti che parlano: metti le parole "Temperatura" e "gradi" nella cartella 01 e i numeri da 001.mp3 a 100.mp3 nella cartella 02, e Arduino potrà pronunciare i numeri in una frase. Il modo più affidabile per sapere che un file è finito è il pin BUSY: è LOW mentre il modulo suona e HIGH a riposo. Lo sketch seguente legge BUSY su D5 e riproduce i file uno dopo l'altro senza sovrapporli:
1#include <SoftwareSerial.h>
2#include <DFRobotDFPlayerMini.h>
3
4SoftwareSerial dfSerial(10, 11); // RX = D10 ← DFPlayer TX, TX = D11 → 1 kΩ → DFPlayer RX
5DFRobotDFPlayerMini player;
6const byte BUSY_PIN = 5; // DFPlayer BUSY: çalarken LOW / LOW while playing
7
8// Klasör 01: 001.mp3 "Sıcaklık", 002.mp3 "derece" / folder 01: 001.mp3 "Temperature", 002.mp3 "degrees"
9// Klasör 02: 001.mp3 ... 100.mp3 = 1 ... 100 sayıları / folder 02: 001.mp3 ... 100.mp3 = numbers 1 ... 100
10
11void playAndWait(uint8_t folder, uint8_t file) {
12 player.playFolder(folder, file); // /01/001.mp3 gibi / e.g. /01/001.mp3
13 unsigned long start = millis();
14 while (digitalRead(BUSY_PIN) == HIGH && millis() - start < 1000) {} // çalma başlasın / wait for playback to start
15 while (digitalRead(BUSY_PIN) == LOW) {} // parça bitsin / wait for the track to end
16 delay(50);
17}
18
19void sayTemperature(int degrees) {
20 playAndWait(1, 1); // "Sıcaklık" / "Temperature"
21 if (degrees >= 1 && degrees <= 100) {
22 playAndWait(2, degrees); // sayıyı söyle / say the number
23 }
24 playAndWait(1, 2); // "derece" / "degrees"
25}
26
27void setup() {
28 pinMode(BUSY_PIN, INPUT);
29 Serial.begin(115200);
30 dfSerial.begin(9600);
31 if (!player.begin(dfSerial)) {
32 Serial.println(F("Unable to begin"));
33 while (true) {}
34 }
35 player.volume(22);
36 sayTemperature(23); // değer bir sensörden de gelebilir / the value can come from a sensor
37}
38
39void loop() {
40}
41playAndWait() invia prima il comando, attende fino a 1 secondo che BUSY passi a LOW (il modulo impiega qualche centinaio di millisecondi per iniziare a suonare) e poi aspetta la fine del brano. Puoi registrare i file audio con la tua voce o generarli con uno strumento di sintesi vocale (TTS); tagliare il silenzio all'inizio e alla fine di ogni file rende l'annuncio più naturale. Se vuoi interrompere la musica per un breve avviso, usa advertise(n): il modulo riproduce l'annuncio dalla cartella /advert e poi riprende la musica da dove si era fermata. Questo comando funziona solo mentre un brano è in riproduzione; se lo chiami con il modulo a riposo, restituisce un errore.
Cambiare brano con i pulsanti e regolare il volume con un potenziometro
Ora costruiamo il nostro lettore MP3: tre pulsanti fanno da brano precedente, play/pausa e brano successivo, e un potenziometro regola il volume. Collega i pulsanti tra D2, D3 e D4 e GND; dato che usiamo le resistenze di pull-up interne, non servono resistenze esterne (il motivo è spiegato in Come collegare un pulsante). I pin esterni del potenziometro vanno a 5V e GND, quello centrale ad A0. Quando un brano finisce, lo sketch passa automaticamente al successivo.
1#include <SoftwareSerial.h>
2#include <DFRobotDFPlayerMini.h>
3
4SoftwareSerial dfSerial(10, 11); // RX = D10 ← DFPlayer TX, TX = D11 → 1 kΩ → DFPlayer RX
5DFRobotDFPlayerMini player;
6
7const byte BTN[3] = {2, 3, 4}; // önceki, oynat/duraklat, sonraki / previous, play/pause, next
8const byte POT_PIN = A0; // ses ayarı potu / volume potentiometer
9bool lastState[3] = {HIGH, HIGH, HIGH};
10unsigned long lastChange[3] = {0, 0, 0};
11bool paused = false;
12int lastRaw = -100; // ilk turda sesi mutlaka ayarla / always set the volume on the first pass
13unsigned long lastPotRead = 0;
14unsigned long lastFinish = 0;
15
16// Butona yeni basıldıysa true döner (50 ms sıçrama filtresi) / true on a new press (50 ms debounce)
17bool pressed(byte i) {
18 bool s = digitalRead(BTN[i]);
19 if (s != lastState[i] && millis() - lastChange[i] > 50) {
20 lastState[i] = s;
21 lastChange[i] = millis();
22 return s == LOW; // INPUT_PULLUP: basınca LOW / LOW when pressed
23 }
24 return false;
25}
26
27void setup() {
28 for (byte i = 0; i < 3; i++) pinMode(BTN[i], INPUT_PULLUP);
29 Serial.begin(115200);
30 dfSerial.begin(9600);
31 if (!player.begin(dfSerial)) {
32 Serial.println(F("Unable to begin"));
33 while (true) {}
34 }
35 player.play(1);
36}
37
38void loop() {
39 if (pressed(0)) { player.previous(); paused = false; }
40 if (pressed(2)) { player.next(); paused = false; }
41 if (pressed(1)) {
42 if (paused) player.start(); // kaldığı yerden devam / resume
43 else player.pause(); // duraklat / pause
44 paused = !paused;
45 }
46
47 if (millis() - lastPotRead > 100) { // potu saniyede 10 kez oku / read the pot 10 times per second
48 lastPotRead = millis();
49 int raw = analogRead(POT_PIN);
50 if (abs(raw - lastRaw) > 20) { // titremeyi yok say / ignore jitter
51 lastRaw = raw;
52 player.volume(map(raw, 0, 1023, 0, 30));
53 }
54 }
55
56 if (player.available() && player.readType() == DFPlayerPlayFinished) {
57 if (millis() - lastFinish > 1000) player.next(); // parça bitince sonrakine geç / go to the next track
58 lastFinish = millis(); // bazı modüller bitişi iki kez bildirir / some modules report the end twice
59 }
60}
61| Parte del codice | A cosa serve |
|---|---|
| pressed() | Rileva solo il momento della pressione e ignora i rimbalzi entro 50 ms; anche tenendo premuto il pulsante parte un solo comando |
| abs(raw - lastRaw) > 20 | Aggiorna il volume solo con variazioni evidenti, così le piccole oscillazioni del potenziometro non inondano il modulo di comandi e non causano clic |
| map(raw, 0, 1023, 0, 30) | Converte il valore analogico 0–1023 nell'intervallo di volume 0–30 del DFPlayer |
| paused | Ricorda lo stato di riproduzione, così lo stesso pulsante mette in pausa e riprende |
| DFPlayerPlayFinished | Il messaggio che arriva a fine brano; lo sketch passa al brano successivo |
| millis() - lastFinish > 1000 | Alcuni moduli clone segnalano due volte la fine del brano; questo controllo evita di saltarne uno |
Scegliere l'altoparlante (3 W) e un amplificatore esterno
L'amplificatore del DFPlayer (sulla maggior parte delle schede un chip di tipo 8002) pilota direttamente un altoparlante sotto i 3 W con impedenza di 4 Ω o 8 Ω. Il miglior equilibrio si ottiene con un altoparlante da 8 Ω e 1–3 W; anche quelli piccoli da 0,5 W funzionano, ma a volume alto vanno in difficoltà. I 3 W sono il limite superiore dell'amplificatore con 5 V di alimentazione e carico da 4 Ω, nel punto in cui la distorsione diventa evidente; la potenza pulita che otterrai nell'uso quotidiano è inferiore. Montare l'altoparlante in una scatola, o almeno su un pannello, migliora nettamente i bassi, perché il suono emesso davanti e dietro la membrana smette di annullarsi. A volume alto il modulo può assorbire per brevi istanti qualche centinaio di milliampere; su un Arduino alimentato dalla USB del computer questo può causare cali di tensione, fruscio e riavvii. Se vuoi più potenza o un suono stereo, collega le uscite di linea DAC_L e DAC_R a un amplificatore esterno:
| Uscita | Collegamento | Quando? |
|---|---|---|
| Amplificatore integrato | SPK_1 e SPK_2 → altoparlante da 4–8 Ω fino a 3 W | Piccoli progetti come campanelli, giocattoli o avvisi parlati |
| Cuffie | DAC_L, DAC_R e GND → jack da 3,5 mm | Ascolto personale; parti con il volume basso |
| Modulo amplificatore PAM8403 | DAC_L, DAC_R e GND → ingressi L, R e GND dell'amplificatore; amplificatore alimentato a 5 V | Stereo 2 × 3 W, cassa portatile a batteria |
| Amplificatore PAM8610 o TPA3116 | Uscite DAC → ingresso dell'amplificatore; amplificatore alimentato a 12 V | Più potenza: 2 × 10 W e oltre |
| Cassa attiva (AUX) | DAC_L, DAC_R e GND → ingresso AUX della cassa | Riutilizzare delle casse per computer che hai già |
Come eliminare fruscio, disturbi e clic
- Fruscio e clic durante l'invio dei comandi: Manca la resistenza da 1 kΩ sulla linea RX. Mettila tra il pin TX di Arduino e il pin RX del modulo.
- Fruscio o ronzio continuo: L'alimentazione è rumorosa o insufficiente. Alimenta il DFPlayer con una sorgente a 5 V separata, aggiungi un condensatore tra VCC e GND e collega tutte le masse.
- Un "pop" all'accensione: Lo causa il comando di reset inviato da begin(). Se ti dà fastidio, salta il reset con player.begin(dfSerial, true, false).
- Ronzio con l'ESP32: Gli impulsi di corrente durante la trasmissione Wi-Fi entrano nell'alimentazione e da lì nell'audio. Aggiungi un condensatore sull'alimentazione del DFPlayer e, se puoi, usa una sorgente separata.
- Suono gracchiante o distorto a volume alto: L'altoparlante o l'amplificatore lavorano al limite. Abbassa il volume intorno a 20–25, scegli un altoparlante più efficiente o passa a un amplificatore esterno.
- Leggero fruscio senza riproduzione: È il rumore proprio dell'amplificatore della scheda e sui moduli piccoli non sparisce mai del tutto. Nei progetti in cui il silenzio conta, collegare l'uscita DAC a un buon amplificatore esterno dà il risultato migliore.
L'errore "Unable to begin" e come risolverlo
Se il monitor seriale mostra Unable to begin: seguito dalle righe 1.Please recheck the connection! e 2.Please insert the SD card!, il controllo di begin() nell'esempio della libreria non è andato a buon fine. begin() invia al modulo un comando di reset e attende per 2 secondi il messaggio "scheda pronta" (card online); se non arriva, restituisce false. Quindi la causa può essere il cablaggio, la scheda SD, l'alimentazione o il modo in cui risponde il modulo. Controlla in quest'ordine:
| Possibile causa | Verifica e soluzione |
|---|---|
| TX e RX non incrociati | Il TX del modulo deve andare a D10 (RX di SoftwareSerial) e il suo RX, tramite 1 kΩ, a D11 (TX di SoftwareSerial); deve corrispondere all'ordine (RX, TX) di SoftwareSerial(10, 11) |
| GND non in comune | Il GND del modulo deve essere collegato al GND di Arduino; se usi un'alimentazione separata, unisci comunque le masse |
| Scheda SD non letta | La scheda è inserita, in FAT32, sotto i 32 GB e contiene almeno un file audio? Riformattala o prova un'altra scheda |
| Resistenza sbagliata | Sulla linea RX va 1 kΩ; valori grandi come 10 kΩ indeboliscono il segnale |
| Alimentazione insufficiente | Su VCC servono 4–5 V; scollega temporaneamente l'altoparlante, misura la tensione con il multimetro e aggiungi un condensatore |
| Baud rate sbagliato | Deve essere dfSerial.begin(9600); non confonderlo con la velocità del monitor seriale (115200) |
| D0 e D1 occupati | Sull'Uno la seriale hardware è condivisa con la USB; sposta il modulo sui pin di SoftwareSerial |
| Il chip clone risponde in ritardo | Aggiungi delay(1000) prima di begin(); se non basta, usa begin(dfSerial, true, false) per saltare l'attesa dopo il reset |
| Codice DFPlayerError | Nome nella libreria | Significato |
|---|---|---|
| 1 | Busy | Modulo occupato o scheda non trovata (inizializzazione non completata) |
| 2 | Sleeping | Il modulo è in modalità sleep |
| 3 | SerialWrongStack | Dati seriali ricevuti corrotti |
| 4 | CheckSumNotMatch | Il checksum del pacchetto non corrisponde |
| 5 | FileIndexOut | Il numero di brano richiesto è fuori dall'intervallo della scheda |
| 6 | FileMismatch | Il file richiesto non è stato trovato; controlla i nomi |
| 7 | Advertise | Errore di annuncio (advert), per esempio advertise() chiamato senza riproduzione in corso |
DFPlayer Mini con ESP32: controllare gli MP3 da una pagina web
Sull'ESP32 non serve SoftwareSerial: ognuna delle sue tre UART hardware può essere assegnata ai pin che preferisci. Nello sketch qui sotto la UART2 lavora su GPIO 16 (RX) e GPIO 17 (TX), e il DFPlayer è alimentato dal pin 5V (VIN) della scheda ESP32. Il segnale TX a 3,3 V dell'ESP32 è direttamente compatibile con il modulo, ma tieni comunque la resistenza da 1 kΩ come protezione contro i disturbi. Nella direzione opposta DFRobot indica che il livello logico del modulo è 3,3 V; tuttavia su alcune schede clone alimentate a 5 V è stata misurata una tensione più alta sulla linea TX. Prima di collegarlo, misura tra TX e GND con un multimetro; se supera 3,6 V, inserisci un partitore di tensione da 1 kΩ + 2 kΩ. Lo sketch si collega alla rete di casa e offre una pagina che puoi aprire sul telefono; i suoi pulsanti cambiano brano, mettono in pausa e regolano il volume.
1#include <WiFi.h>
2#include <WebServer.h>
3#include <DFRobotDFPlayerMini.h>
4
5const char *WIFI_SSID = "WIFI_ADI"; // kendi ağ adın / your network name
6const char *WIFI_PASS = "WIFI_SIFRESI"; // kendi şifren / your password
7
8HardwareSerial dfSerial(2); // UART2
9DFRobotDFPlayerMini player;
10WebServer server(80);
11int volumeLevel = 15;
12
13const char PAGE[] = R"rawliteral(<!DOCTYPE html><html><head>
14<meta name="viewport" content="width=device-width,initial-scale=1"><title>ESP32 MP3</title>
15<style>body{font-family:sans-serif;text-align:center}button{font-size:22px;margin:6px;padding:10px 18px}</style>
16</head><body><h2>DFPlayer Mini</h2>
17<button onclick="c('prev')">Prev</button><button onclick="c('pause')">Pause</button>
18<button onclick="c('play')">Play</button><button onclick="c('next')">Next</button><br>
19<button onclick="c('down')">Vol -</button><button onclick="c('up')">Vol +</button>
20<p id="s"></p>
21<script>function c(x){fetch('/cmd?c='+x).then(r=>r.text()).then(t=>document.getElementById('s').innerText=t)}</script>
22</body></html>)rawliteral";
23
24void handleCmd() {
25 String c = server.arg("c");
26 if (c == "next") player.next();
27 else if (c == "prev") player.previous();
28 else if (c == "pause") player.pause();
29 else if (c == "play") player.start();
30 else if (c == "up" && volumeLevel < 30) player.volume(++volumeLevel);
31 else if (c == "down" && volumeLevel > 0) player.volume(--volumeLevel);
32 server.send(200, "text/plain", "Ses / Volume: " + String(volumeLevel));
33}
34
35void setup() {
36 Serial.begin(115200);
37 dfSerial.begin(9600, SERIAL_8N1, 16, 17); // RX = GPIO16 ← DFPlayer TX, TX = GPIO17 → 1 kΩ → DFPlayer RX
38 delay(1000); // modül kartı okusun / let the module read the card
39 if (!player.begin(dfSerial)) {
40 Serial.println("Unable to begin");
41 while (true) delay(10);
42 }
43 player.volume(volumeLevel);
44
45 WiFi.begin(WIFI_SSID, WIFI_PASS);
46 while (WiFi.status() != WL_CONNECTED) { // ağa bağlanana kadar bekle / wait for the network
47 delay(500);
48 Serial.print(".");
49 }
50 Serial.print("\nAdres / Address: http://");
51 Serial.println(WiFi.localIP());
52
53 server.on("/", []() { server.send(200, "text/html", PAGE); });
54 server.on("/cmd", handleCmd);
55 server.begin();
56 player.play(1);
57}
58
59void loop() {
60 server.handleClient(); // tarayıcı isteklerini işle / handle browser requests
61}
62Dopo il caricamento, scrivi nel browser del telefono l'indirizzo mostrato nel monitor seriale (per esempio 192.168.1.42); telefono ed ESP32 devono essere sulla stessa rete Wi-Fi. Se non si collega, segui i passaggi di L'ESP32 non si connette al Wi-Fi. Sulle schede con modulo ESP32-WROVER, GPIO 16 e 17 sono riservati alla PSRAM interna, quindi sposta la UART su altri pin come 26 e 27; basta cambiare i numeri dei pin nella riga dfSerial.begin(). Se l'ESP32 si riavvia da solo mentre l'altoparlante suona forte, il problema è l'alimentazione; trovi i dettagli in Brownout dell'ESP32.
DFPlayer Mini con Raspberry Pi Pico e MicroPython (UART)
Sul Raspberry Pi Pico, usare direttamente il protocollo seriale del modulo invece di cercare una libreria pronta è semplice e anche molto istruttivo. Ogni comando è un pacchetto da 10 byte: il byte di inizio 0x7E, la versione 0xFF, la lunghezza 0x06, il codice del comando, il flag di risposta (0 = nessuna conferma), un parametro da due byte, un checksum da due byte e il byte di fine 0xEF. Il checksum è il valore negativo a 16 bit della somma dei sei byte che vanno dalla versione all'ultimo byte del parametro. Per esempio, il pacchetto che riproduce il primo brano della cartella principale è 7E FF 06 03 00 00 01 FE F7 EF. Il modulo, a sua volta, invia messaggi con codice 0x3D quando un brano finisce, 0x3F quando la scheda è pronta e 0x40 in caso di errore. La UART a 3,3 V del Pico si adatta direttamente al modulo; l'avvertenza sulla tensione di TX della sezione ESP32 vale anche qui, perché nemmeno i pin del Pico tollerano i 5 V. Alimenta il modulo dal pin VBUS (USB 5 V) del Pico.
| Comando | Codice | Parametro |
|---|---|---|
| Brano successivo / precedente | 0x01 / 0x02 | Nessuno |
| Riprodurre l'n-esimo brano della cartella principale | 0x03 | 1–2999 |
| Volume | 0x06 | 0–30 |
| Equalizzatore | 0x07 | 0–5 |
| Reset | 0x0C | Nessuno |
| Riprendi / pausa | 0x0D / 0x0E | Nessuno |
| Riprodurre da una cartella | 0x0F | Byte alto cartella (1–99), byte basso file (1–255) |
| Riprodurre dalla cartella mp3 | 0x12 | Numero del file (1 per 0001.mp3) |
| Annuncio (advert) | 0x13 | Numero del file |
| Stop | 0x16 | Nessuno |
| Brano finito (inviato dal modulo) | 0x3D | Numero del brano finito |
1from machine import UART, Pin
2import time
3
4# GP0 (UART0 TX) → 1 kΩ → DFPlayer RX, GP1 (UART0 RX) ← DFPlayer TX
5uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
6btn_next = Pin(14, Pin.IN, Pin.PULL_UP) # sonraki parça / next track
7btn_play = Pin(15, Pin.IN, Pin.PULL_UP) # oynat-duraklat / play-pause
8TRACKS = 5 # /mp3 klasöründeki dosya sayısı / number of files in /mp3
9
10def send(cmd, param=0):
11 # 10 baytlık komut paketi, onay istemeden / 10-byte command frame without ACK
12 frame = bytearray([0x7E, 0xFF, 0x06, cmd, 0x00, param >> 8, param & 0xFF, 0, 0, 0xEF])
13 checksum = -sum(frame[1:7]) & 0xFFFF # sağlama toplamı / checksum
14 frame[7] = checksum >> 8
15 frame[8] = checksum & 0xFF
16 uart.write(frame)
17 time.sleep_ms(30)
18
19buf = b""
20
21def events():
22 # gelen 10 baytlık bildirimlerin komut kodlarını döndür / return command codes of incoming messages
23 global buf
24 if uart.any():
25 buf += uart.read()
26 codes = []
27 while True:
28 start = buf.find(b"\x7e")
29 if start < 0:
30 buf = b""
31 break
32 if len(buf) - start < 10:
33 buf = buf[start:]
34 break
35 frame = buf[start:start + 10]
36 if frame[9] == 0xEF:
37 codes.append(frame[3])
38 buf = buf[start + 10:]
39 else:
40 buf = buf[start + 1:]
41 return codes
42
43def play_track(n):
44 send(0x12, n) # /mp3/000n.mp3 dosyasını çal / play /mp3/000n.mp3
45
46time.sleep(2) # modül kartı okusun / let the module read the card
47send(0x06, 18) # ses 18/30 / volume 18 of 30
48track = 1
49play_track(track)
50playing = True
51last_end = 0
52
53while True:
54 if btn_next.value() == 0:
55 track = track % TRACKS + 1 # son parçadan sonra başa dön / wrap after the last track
56 play_track(track)
57 playing = True
58 time.sleep_ms(300) # basit sıçrama önleme / simple debounce
59 if btn_play.value() == 0:
60 send(0x0E if playing else 0x0D) # 0x0E duraklat, 0x0D devam / 0x0E pause, 0x0D resume
61 playing = not playing
62 time.sleep_ms(300)
63 for code in events():
64 # 0x3D: SD karttaki parça bitti / 0x3D: track on the SD card finished
65 if code == 0x3D and time.ticks_diff(time.ticks_ms(), last_end) > 1000:
66 last_end = time.ticks_ms() # çift bildirimi yok say / ignore the duplicate message
67 track = track % TRACKS + 1
68 play_track(track)
69Se salvi il codice sul Pico come main.py con Thonny, il Pico funzionerà come un lettore MP3 a ogni accensione; se sei alle prime armi con MicroPython, dai un'occhiata a Le basi di MicroPython. Il pulsante su GP14 passa al brano successivo, quello su GP15 mette in pausa e riprende; l'altro capo di ogni pulsante va a GND. La funzione events() accumula i byte in arrivo in un buffer ed estrae i pacchetti che iniziano con 0x7E e finiscono con 0xEF. Quando arriva il messaggio di brano finito (0x3D), il codice passa al file successivo e dopo l'ultimo ricomincia dal primo. Non dimenticare di impostare la variabile TRACKS sul numero di file della tua cartella /mp3.
Idee di progetti con il DFPlayer Mini
- Campanello con melodie: Un campanello che suona una melodia a caso quando premi il pulsante e abbassa il volume di notte.
- Sistema di benvenuto: Un sensore di movimento PIR fa partire un saluto quando arriva qualcuno.
- Carillon con tessere: Ogni tessera RFID riproduce una cartella diversa; un lettore musicale senza schermo per bambini.
- Orologio parlante: Con un modulo orologio RTC, un orologio che dice l'ora ad alta voce o la annuncia allo scoccare di ogni ora.
- Lettore MP3 con telecomando: Controllo di brano e volume con un ricevitore IR e telecomando.
- Decorazione di Halloween o scatola degli scherzi: Un HC-SR04 fa partire un suono spaventoso quando rileva che qualcuno si avvicina.
- Allarmi e avvisi parlati: Frasi chiare come "Gas rilevato in cucina" invece di un bip in caso di gas, allagamento o porta rimasta aperta.
- Lettore MP3 con display: Mostra numero del brano e volume su un display OLED.
Con una scheda SD con i nomi giusti, la resistenza da 1 kΩ sulla linea RX e un'alimentazione a 5 V solida, il DFPlayer Mini porta un audio vero nei tuoi progetti Arduino in pochi minuti. Se qualcosa non va, controlla prima la scheda e il cablaggio, poi l'alimentazione; quasi tutti i problemi nascono da uno di questi tre punti. Se ti incuriosiscono le basi della comunicazione seriale, La comunicazione seriale UART è un buon passo successivo. Nell'app BlueGrays trovi progetti sonori come melodie con il buzzer, un pianoforte semplice, un campanello con sensore di movimento e melodie con ESP32, ognuno con schema del circuito e codice passo passo, a cui poi potrai dare un audio vero con il DFPlayer Mini.
Domande frequenti
Quanto può essere grande la scheda SD del DFPlayer Mini?
Il DFPlayer Mini legge schede microSD fino a 32 GB in FAT16 o FAT32. Le schede da 64 GB in su sono formattate in exFAT e quindi il modulo non le vede. Per qualche centinaio di MP3 una scheda da 1–16 GB è più che sufficiente.
Perché il mio DFPlayer Mini non emette nessun suono?
Per prima cosa assicurati che nel monitor seriale compaia "online"; se non compare, il problema è nel cablaggio o nella scheda SD. Se il modulo si avvia ma resta muto, controlla che il volume non sia a 0, che l'altoparlante sia collegato a SPK_1 e SPK_2 e che i nomi dei file corrispondano alla funzione che chiami. Se il LED sulla scheda si accende, il modulo sta davvero suonando.
Perché si mette una resistenza da 1k sul pin RX del DFPlayer Mini?
Il chip del modulo funziona a 3,3 V, mentre il pin TX dell'Arduino Uno fornisce 5 V. Una resistenza da 1 kΩ in serie alla linea RX limita la corrente che entra nel chip e riduce il fruscio dell'altoparlante durante la comunicazione seriale. È consigliata anche sulle schede a 3,3 V come ESP32 e Pico, come protezione contro i disturbi.
Il DFPlayer Mini funziona senza Arduino?
Sì. Collegando i pin IO_1 e IO_2 a GND tramite pulsanti, una pressione breve cambia brano e una lunga regola il volume. Anche i pulsanti collegati ai pin ADKEY tramite resistenze possono avviare brani precisi. Così puoi costruire un lettore MP3 o un campanello con una batteria, un altoparlante e qualche pulsante, senza microcontrollore.
Quale altoparlante si può collegare al DFPlayer Mini?
Ai pin SPK_1 e SPK_2 si collega direttamente un altoparlante da 4 Ω o 8 Ω e sotto i 3 W; quelli da 8 Ω e 1–3 W danno il miglior equilibrio. Non collegare nessuno dei due capi dell'altoparlante a GND. Per più volume o un suono stereo, collega le uscite DAC_L e DAC_R a un amplificatore come il PAM8403.
Perché il DFPlayer Mini riproduce i file nell'ordine sbagliato?
La funzione play(n) non guarda il nome del file, ma l'ordine in cui i file sono stati copiati sulla scheda. Per riprodurre in base al nome, chiama i file /mp3/0001.mp3 e usa playMp3Folder(), oppure /01/001.mp3 e usa playFolder(). Se hai preparato la scheda su un Mac, elimina anche i file nascosti ._.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Uso del cicalino
Ti sei mai chiesto come fa un campanello o un allarme a suonare? L'Arduino fa suonare un piccolo cicalino a intervalli brevi: bip, pausa, bip, pausa. Vedi come l'elettricità diventa suono e fai il pri

Inno nazionale turco con cicalino
Premi il pulsante e un piccolo buzzer comincia a suonare l'inno nazionale turco, nota dopo nota. L'Arduino suona ogni nota all'altezza e con la durata giuste, esegue due strofe dell'inno dall'inizio a

Impostazione della frequenza con cicalino
Comandi il suono di un buzzer con quattro pulsanti: uno avvia il suono, uno lo zittisce e gli altri due lo rendono più acuto o più grave. Tieni premuto il pulsante su o giù e il tono cambia passo dopo

ESP32 Riproduzione di melodia con cicalino
Riproduzione di una semplice melodia (Twinkle Twinkle Little Star) con un buzzer passivo. Le note vengono riprodotte con le funzioni tone() e noTone() come in Arduino - la stessa sintassi funziona con ESP32 Arduino Core 3.0+. È necessario utilizzare un cicalino passivo (il cicalino attivo non riproduce la melodia).

Suonare melodie con telecomando IR e cicalino
Costruisci un carillon che suona melodie con i tasti del telecomando della TV. Un ricevitore a infrarossi cattura il segnale del telecomando; un tasto fa suonare al cicalino una vivace musica da video

Pianoforte semplice con cicalino e pulsante
Costruisci il tuo piccolo pianoforte con otto pulsanti. Ogni pulsante è una nota, dalla più grave alla più acuta: do, re, mi, fa, sol, la, si e il do acuto. La nota suona nel cicalino finché tieni pre

Marcia Mehter con Arduino
Questo progetto consente di riprodurre l'inno di Mehter con un ciclo infinito utilizzando solo Arduino Uno, Buzzer e cavi di collegamento. È sufficiente effettuare i collegamenti e incollare il codice.

Campanello e luce con sensore di movimento
Quando qualcuno si avvicina alla tua porta, lo sai prima ancora che suoni. Appena il sensore di movimento rileva qualcuno, il LED si accende e il buzzer suona un campanello di tre note, dalla più acut
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

