Come usare DFPlayer Mini con Arduino

Il nome ufficiale del prodotto DFRobot è DFPlayer - Mini MP3 Player, con codice DFR0299. È un piccolo modulo audio capace di riprodurre file MP3, WAV e WMA da una scheda microSD/TF e, nel progetto di riferimento, anche da una memoria USB. Può essere comandato da Arduino tramite seriale UART, ma possiede anche modalità autonome con pulsanti e reti di resistori.

Il modulo mostrato nella fotografia è marcato MP3-TF-16P V3.0, una forma compatibile molto diffusa. Poiché esistono diverse revisioni e moduli compatibili, alcune funzioni avanzate possono comportarsi in modo differente. La guida usa l'interfaccia e la libreria ufficiali DFRobot come riferimento.

Come funziona il DFPlayer Mini

Modulo audio DFPlayer Mini MP3-TF-16P con lettore microSD

Il DFPlayer Mini contiene un decoder audio, un lettore microSD, un convertitore digitale-analogico, un piccolo amplificatore mono e un'interfaccia seriale. Arduino non deve decodificare il file audio: invia soltanto comandi come “riproduci la traccia 1”, “aumenta il volume” o “metti in pausa”.

La comunicazione UART predefinita usa normalmente 9600 bit/s, 8 bit di dati, nessuna parità e un bit di stop. Il volume è regolabile su 30 livelli, da 0 a 30.

Pinout completo del DFPlayer Mini

Pinout completo del modulo DFPlayer Mini con VCC, UART, DAC, speaker, ADKEY, USB, IO e BUSY

VCC e GND: alimentazione

Il pin VCC alimenta il modulo, mentre i due pin GND sono elettricamente la massa comune. Il progetto di riferimento accetta circa 3,2-5 V; con Arduino UNO viene normalmente utilizzata un'alimentazione stabile a 5 V. I due pin GND possono essere usati in punti diversi del circuito, ma appartengono alla stessa massa.

RX e TX: comunicazione seriale con Arduino

RX è l'ingresso seriale del DFPlayer e riceve i comandi trasmessi da Arduino. TX è l'uscita seriale del modulo e invia ad Arduino risposte, stati ed errori. I collegamenti sono incrociati: TX del DFPlayer va al pin RX scelto su Arduino, mentre TX di Arduino va verso RX del DFPlayer.

SPK_1 e SPK_2: uscita diretta per altoparlante

I pin SPK_1 e SPK_2 sono le due estremità dell'uscita amplificata mono a ponte. Un piccolo altoparlante viene collegato direttamente tra SPK_1 e SPK_2. Nessuno dei due terminali dell'altoparlante deve essere collegato a GND. L'amplificatore integrato è pensato per piccoli speaker con potenza inferiore o uguale a circa 3 W.

DAC_L e DAC_R: uscita audio stereo

DAC_L e DAC_R forniscono rispettivamente il canale audio sinistro e destro a livello non amplificato. Queste uscite sono adatte a un amplificatore esterno, a un ingresso audio o, nei limiti indicati dal produttore, a cuffie. Non devono essere usate come sostitute di SPK_1 e SPK_2 per pilotare direttamente un altoparlante di potenza.

USB+ e USB-: memoria USB U-disk

USB+ e USB- sono le linee dati D+ e D- per una memoria USB. Per usare una chiavetta serve un connettore USB femmina o un breakout correttamente cablato: oltre alle due linee dati, la chiavetta deve ricevere 5 V e GND. Questi pin non sono una porta seriale USB e non servono a caricare programmi o file dal PC direttamente nel modulo.

IO_1 e IO_2: controllo semplice con due pulsanti

I pin IO_1 e IO_2 permettono di comandare il modulo senza Arduino. Collegando ciascun pin a un pulsante che chiude verso GND, una pressione breve seleziona la traccia precedente o successiva, mentre una pressione prolungata regola il volume. Nel comportamento di riferimento IO_1 gestisce precedente/volume meno e IO_2 gestisce successiva/volume più.

ADKEY_1 e ADKEY_2: molti pulsanti con due soli ingressi

Gli ingressi ADKEY_1 e ADKEY_2 leggono differenti livelli di tensione. Collegando pulsanti a GND attraverso resistori di valori differenti, il modulo riconosce quale tasto è stato premuto. La configurazione di riferimento può gestire fino a 20 comandi distribuiti sui due ingressi. I valori dei resistori devono seguire la tabella ADKEY prevista dal modulo: non sono tasti digitali normali.

BUSY: sapere quando una traccia è in riproduzione

Il pin BUSY indica lo stato della riproduzione. Nel comportamento di riferimento è LOW mentre il modulo sta riproducendo un file e HIGH quando non sta riproducendo. Può essere collegato a un ingresso digitale di Arduino per attendere la fine di un messaggio senza basarsi su un ritardo fisso.

Collegamento del DFPlayer Mini ad Arduino UNO

Schema di collegamento DFPlayer Mini ad Arduino UNO con SoftwareSerial e partitore resistivo sul pin RX del modulo
  • VCC del DFPlayer → 5V di Arduino;
  • GND del DFPlayer → GND di Arduino;
  • TX del DFPlayer → pin 2 di Arduino, usato come RX software;
  • pin 3 di Arduino, usato come TX software → resistenza da 1 kΩ → nodo RX del DFPlayer;
  • resistenza da 2 kΩ tra il nodo RX del DFPlayer e GND;
  • altoparlante collegato tra SPK_1 e SPK_2.

Perché serve il partitore da 1 kΩ e 2 kΩ?

Arduino UNO trasmette normalmente un livello logico alto vicino a 5 V, mentre l'ingresso seriale del modulo lavora a un livello inferiore. Le resistenze da 1 kΩ e 2 kΩ creano un partitore:

VOUT = 5 V × 2 kΩ / (1 kΩ + 2 kΩ) ≈ 3,33 V

La resistenza da 1 kΩ è collegata tra il TX di Arduino e il nodo RX del modulo. La resistenza da 2 kΩ è collegata tra quel nodo e GND. Il TX del DFPlayer può invece essere collegato direttamente al pin RX di Arduino, perché il suo livello alto è leggibile dall'ATmega328P.

Preparare la microSD e i file audio

Usa una microSD/TF fino a 32 GB formattata FAT16 o FAT32. Per ottenere una selezione prevedibile con playMp3Folder(), crea nella directory principale una cartella chiamata mp3 e assegna ai file nomi numerici di quattro cifre:

/mp3/0001.mp3
/mp3/0002.mp3
/mp3/0003.mp3

È possibile aggiungere testo dopo il numero, per esempio 0001_avvio.mp3. Non rimuovere o inserire la scheda mentre il modulo è alimentato. Il comando generico play(1) può dipendere dall'ordine con cui i file sono stati copiati; per questo i nomi numerici e le funzioni dedicate alle cartelle sono spesso più affidabili.

Installare la libreria DFRobotDFPlayerMini

Apri il Library Manager dell'Arduino IDE, cerca DFRobotDFPlayerMini e installa la libreria mantenuta da DFRobot. La guida utilizza inoltre SoftwareSerial, inclusa nell'ambiente Arduino AVR.

#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

Primo codice: riprodurre /mp3/0001.mp3

dfplayer_basic.ino
// https://nemiatools.com
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

// Arduino pin 2 = RX: riceve dal TX del DFPlayer
// Arduino pin 3 = TX: invia al RX del DFPlayer
SoftwareSerial dfSerial(2, 3);

DFRobotDFPlayerMini dfPlayer;

void setup() {
  Serial.begin(9600);
  dfSerial.begin(9600);

  Serial.println("Inizializzazione DFPlayer Mini...");

  if (!dfPlayer.begin(dfSerial, true, true)) {
    Serial.println("DFPlayer non rilevato.");
    Serial.println("Controlla cablaggio e memoria.");
    while (true) {
      delay(1000);
    }
  }

  Serial.println("DFPlayer pronto");

  dfPlayer.volume(20); // Volume da 0 a 30
  dfPlayer.EQ(DFPLAYER_EQ_NORMAL);
  dfPlayer.outputDevice(DFPLAYER_DEVICE_SD);

  delay(500);
  dfPlayer.playMp3Folder(1); // /mp3/0001.mp3
}

void loop() {
  if (dfPlayer.available()) {
    uint8_t eventType = dfPlayer.readType();
    int eventValue = dfPlayer.read();

    Serial.print("Evento DFPlayer: ");
    Serial.print(eventType);
    Serial.print(" - valore: ");
    Serial.println(eventValue);
  }
}

Come funziona il codice

SoftwareSerial dfSerial(2, 3) crea una porta seriale software. Il primo numero è RX e il secondo è TX: Arduino riceve sul pin 2 dal TX del modulo e trasmette dal pin 3 verso il partitore collegato al RX del modulo.

dfPlayer.begin(dfSerial, true, true) associa la libreria alla porta seriale. Il secondo parametro abilita le risposte ACK e il terzo richiede un reset del modulo durante l'inizializzazione. Se la funzione restituisce false, il programma si ferma perché il lettore non è stato inizializzato.

volume(20) imposta il volume, EQ(DFPLAYER_EQ_NORMAL) seleziona l'equalizzazione normale e outputDevice(DFPLAYER_DEVICE_SD) sceglie la microSD. Dopo una breve attesa, playMp3Folder(1) riproduce il file /mp3/0001.mp3.

Nel loop, available() segnala la presenza di un evento o di una risposta. readType() restituisce il tipo di evento e read() il relativo valore, utile per rilevare fine traccia, memoria rimossa ed errori.

Esempio: controllare il DFPlayer dal Monitor Seriale

dfplayer_serial_controller.ino
// https://nemiatools.com
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

SoftwareSerial dfSerial(2, 3);
DFRobotDFPlayerMini dfPlayer;

int volumeLevel = 20;

void printCommands() {
  Serial.println();
  Serial.println("Comandi:");
  Serial.println("1 = riproduci /mp3/0001.mp3");
  Serial.println("2 = riproduci /mp3/0002.mp3");
  Serial.println("n = traccia successiva");
  Serial.println("p = traccia precedente");
  Serial.println("+ = aumenta volume");
  Serial.println("- = diminuisci volume");
  Serial.println("a = pausa");
  Serial.println("r = riprendi");
  Serial.println("s = stop");
}

void setup() {
  Serial.begin(9600);
  dfSerial.begin(9600);

  if (!dfPlayer.begin(dfSerial, true, true)) {
    Serial.println("Errore di inizializzazione");
    while (true) {
      delay(1000);
    }
  }

  dfPlayer.volume(volumeLevel);
  dfPlayer.outputDevice(DFPLAYER_DEVICE_SD);

  printCommands();
}

void loop() {
  if (Serial.available()) {
    char command = Serial.read();

    switch (command) {
      case '1':
        dfPlayer.playMp3Folder(1);
        break;

      case '2':
        dfPlayer.playMp3Folder(2);
        break;

      case 'n':
        dfPlayer.next();
        break;

      case 'p':
        dfPlayer.previous();
        break;

      case '+':
        if (volumeLevel < 30) {
          volumeLevel++;
          dfPlayer.volume(volumeLevel);
        }
        break;

      case '-':
        if (volumeLevel > 0) {
          volumeLevel--;
          dfPlayer.volume(volumeLevel);
        }
        break;

      case 'a':
        dfPlayer.pause();
        break;

      case 'r':
        dfPlayer.start();
        break;

      case 's':
        dfPlayer.stop();
        break;
    }
  }
}

Questo programma mostra il principio con cui un sensore, un keypad o un pulsante può controllare il lettore. Il Monitor Seriale serve soltanto come sorgente dei comandi: la riproduzione vera e propria viene gestita dal DFPlayer.

Tutte le principali funzioni della libreria

Inizializzazione, attesa e messaggi

begin(stream, isACK, doReset) inizializza il modulo sulla porta seriale scelta. setTimeOut(ms) imposta il timeout delle risposte. available() controlla se è arrivato un evento, mentre waitAvailable(duration) può attenderlo per un tempo definito. readType() e read() restituiscono rispettivamente il tipo e il valore del messaggio.

Riproduzione di base

play(numero) avvia una traccia secondo l'indice del dispositivo selezionato. next() e previous() cambiano traccia. pause() mette in pausa, start() riprende e stop() arresta la riproduzione. loop(numero) riproduce ripetutamente una traccia specifica.

Riproduzione per cartelle e nomi numerici

playMp3Folder(numero) seleziona un file come /mp3/0001.mp3. playFolder(cartella, file) usa cartelle numeriche e nomi a tre cifre, per esempio /15/004.mp3. playLargeFolder(cartella, file) gestisce cartelle e numeri più grandi secondo il formato supportato dal firmware. loopFolder(cartella) ripete tutti i file di una cartella.

Ripetizione e riproduzione casuale

enableLoop() e disableLoop() attivano o disattivano la ripetizione della traccia corrente. enableLoopAll() e disableLoopAll() controllano la ripetizione dell'intera raccolta. randomAll() avvia la riproduzione casuale dei file.

Volume ed equalizzatore

volume(valore) imposta un livello da 0 a 30. volumeUp() e volumeDown() aumentano o riducono il livello. EQ() seleziona uno dei profili disponibili: NORMAL, POP, ROCK, JAZZ, CLASSIC e BASS.

Scelta della memoria

outputDevice() seleziona la sorgente. Le costanti della libreria comprendono DFPLAYER_DEVICE_SD, DFPLAYER_DEVICE_U_DISK, FLASH, AUX e SLEEP. Non tutte le sorgenti sono fisicamente disponibili o affidabili su ogni modulo compatibile.

Messaggi pubblicitari

advertise(numero) interrompe temporaneamente la traccia corrente per riprodurre un file dalla cartella /ADVERT. Al termine, la riproduzione precedente può continuare. stopAdvertise() termina il messaggio pubblicitario. Questa funzione è utile per avvisi vocali e notifiche.

Controllo del modulo e delle uscite

sleep() porta il modulo in modalità di riposo e reset() lo riavvia. enableDAC() e disableDAC() controllano il convertitore audio. outputSetting(enable, gain) abilita l'uscita e imposta il guadagno previsto dal protocollo.

Lettura delle informazioni

readState() legge lo stato di riproduzione, readVolume() il volume e readEQ() il profilo EQ. readFileCounts() restituisce il numero dei file, mentre la variante con parametro permette di specificare il dispositivo. readCurrentFileNumber() restituisce il file corrente. readFileCountsInFolder(cartella) conta i file di una cartella e readFolderCounts() legge il numero delle cartelle.

Riprodurre audio da una chiavetta USB

Il progetto di riferimento del DFPlayer supporta una memoria USB “U-disk” fino a 32 GB. Collega USB+ e USB- alle corrispondenti linee D+ e D- di un connettore USB-A femmina, e alimenta la chiavetta con 5 V e GND. Mantieni i collegamenti USB corti e corretti.

dfplayer_usb_fragment.ino
// Seleziona la chiavetta USB come memoria
dfPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK);

delay(500);

// Riproduce la prima traccia disponibile
dfPlayer.play(1);

Inserisci la chiavetta prima di inizializzare il modulo e lascia un breve tempo al lettore per riconoscerla. Sui moduli compatibili o sulle revisioni non ufficiali la modalità U-disk può non essere implementata nello stesso modo: in caso di problemi verifica il chip e la documentazione specifica della tua scheda.

Usare il DFPlayer Mini senza Arduino

Modalità I/O con due pulsanti

Collega un pulsante tra IO_1 e GND e un secondo pulsante tra IO_2 e GND. Le pressioni brevi cambiano traccia, mentre quelle lunghe regolano il volume. Servono soltanto alimentazione, speaker e memoria contenente i file.

Modalità ADKEY con molti pulsanti

Per creare un pannello con più comandi, collega a ADKEY_1 e ADKEY_2 diversi pulsanti, ciascuno con il valore resistivo previsto verso GND. Il modulo misura la tensione e associa ogni intervallo a una funzione differente, come selezione diretta di tracce, play/pausa, modalità di riproduzione e volume. Questa modalità evita completamente il microcontrollore, ma richiede resistori corretti e tolleranze sufficientemente precise.

Usare il pin BUSY con Arduino

const byte BUSY_PIN = 4;

void setup() {
  pinMode(BUSY_PIN, INPUT);
}

void loop() {
  if (digitalRead(BUSY_PIN) == LOW) {
    // Il DFPlayer sta riproducendo
  }
  else {
    // La riproduzione è terminata o il modulo è inattivo
  }
}

BUSY è particolarmente utile quando un'azione deve iniziare soltanto dopo la fine di una frase. Ricorda che alcuni moduli compatibili possono invertire o gestire diversamente questo segnale: controllalo sul tuo esemplare durante i test.

Applicazioni del DFPlayer Mini

  • robot parlanti e animatronica;
  • messaggi vocali per sensori e allarmi;
  • campanelli e sistemi di benvenuto;
  • giocattoli, cosplay e oggetti di scena;
  • riproduttori audio comandati da RFID o keypad;
  • effetti sonori per modellismo e diorami;
  • menu vocali e dispositivi accessibili.

Problemi comuni

Il modulo non viene inizializzato

Controlla VCC, GND, incrocio RX/TX, baud rate a 9600 e presenza di una memoria valida. Assicurati che il TX di Arduino raggiunga il pin RX del modulo attraverso il partitore.

Si sente un ronzio o la comunicazione è instabile

Usa un'alimentazione stabile, collegamenti corti e una massa comune. Il partitore sul RX del modulo riduce correttamente il livello logico; evita di far passare i fili seriali vicino ai cavi dell'altoparlante.

Il file richiesto non viene riprodotto

Verifica la formattazione FAT16/FAT32, il nome della cartella e le quattro cifre del file. Controlla anche che il numero richiesto esista e che i file nascosti creati dal sistema operativo non alterino l'ordinamento.

L'audio è distorto o il modulo si riavvia

Riduci il volume e verifica che l'alimentazione possa fornire la corrente richiesta dall'amplificatore. Non collegare un altoparlante tra SPK_1 e GND: deve essere collegato tra SPK_1 e SPK_2.

La chiavetta USB non viene riconosciuta

Controlla l'alimentazione a 5 V della chiavetta, l'ordine di USB+ e USB-, il formato FAT e la compatibilità effettiva della revisione del modulo. La modalità USB non è una connessione diretta al computer.