Ceci est une ancienne révision du document !


Lecteurs audio DFplayer

  • Porteur du projet : Réso-nance laurent
  • Date : 07/06/2019/
  • Licence : CC-by-sa-3.0
  • Description : Plusieurs lecteurs audio wav controllés par un arduino
  • Fichiers sources : audioplayer.zip

Description

Ce lecteur audio permet de lire deux fichiers wav simultanément sur deux sorties casques ou HP séparées. Le décodage et la lecture des fichiers depuis une carte micro SD est géré par un petit module tout-en-un : le DFplayer mini. Le code est modulaire et permet d'ajouter autant de lecteurs que nécessaire. L'interface entre le DFplayer et les boutons qui permettent de lancer la lecture est gérée par un arduino (nano pour deux lecteurs) Lecteurs audio DFplayer

Hardware

DFplayer

Sorties audio Le DFplayer possède deux sorties pour casque / niveau ligne appelées DAC_L et DAC_R sur les pins 4 et 5. Il possède en outre un petit amplificateur intégré permettant d'y connecter deux HP de faible impédance sur les sorties SPK_1 et SPK_2.

Alimentation Ce lecteur peut être alimenté en 3.3V ou 5V. L'alimentation étant souvent source de bruit dans les montages audio, on choisira d'alimenter l'arduino en 9V depuis son Vin pour qu'il alimente à son tour le DFplayer au travers de ses régulateurs 5V et 3.3V intégrés. Ceux-ci étant des régulateurs linéaires, ils fournissent une tension plus stable et moins bruitée que les alimentations à découpage. En revanche leur rendement est souvent bien inférieur et ils dissipent leur pertes sous forme de chaleur. Pour alimenter plus de deux ou trois DFplayer, on aura plutôt recours à une alimentation à découpage 3V3 correctement filtrée ou à un régulateur linéaire additionnel externe, type 7805

Contrôle de la lecture L'arduino s'interface simplement en port série avec le DFplayer. Pour utiliser plusieurs lecteurs sur un même arduino et faciliter les opérations de téléversement et débogage, on émulera un port série virtuel côté arduino qui permettra d'assigner autant de TXs et RXs qu'il y a de pins disponibles sans perdre le port série matériel, toujours accessible via l'USB.

Contrôle du volume Si l'on peut ajuster le volume de lecture depuis l'arduino via le port série, cela produit des petits disruptions audibles dans la lecture du fichier. Un potentiomètre double (stéréo) peut être utilisé directement entre les sorties analogique DAC et la prise casque pour un meilleur confort de lecture.

circuit

Le circuit pour deux lecteurs indépendants comprends donc:

  • deux DFplayers : outre leur connection à l'arduino, il est nécessaire de connecter ensemble les deux pins de masse par un câble le plus court possible pour éviter tout ajout de bruit numérique.
  • un arduino nano qui centralise les contrôles et communique avec les DFplayers
  • deux boutons par lecteur pour choisir la piste à lire
  • deux résistances de 220R pour adapter l'impédance du DFplayer à celle plus élevée du casque. Cette valeur à été choisie empiriquement pour obtenir le meilleur rapport qualité sonore / volume maximal possible. Une résistance trop élevée diminuera drastiquement le volume sonore tandis qu'une résistance trop faible laissera entendre du bruit lié à une intensité trop élevée drainée par le casque.

Le potentiomètre qui ne figure pas sur le schéma est connecté comme suit :

Code

Le code utilisé par l'arduino utilise la librairie standard SoftwareSerial ainsi que la librairie DFRobotDFPlayerMini . Il est écrit de façon modulaire pour pouvoir aisément ajouter des lecteurs. Un struct représente chaque lecteur, les pins de ses boutons de lecture, une entrée analogique pour le volume ainsi qu'un pointeur vers l'instance de SoftwareSerial par qui il communique. Un define ligne 5 permet d'activer ou de désactiver le contrôle numérique du volume via un potentiomètre connecté sur une entrée analogique.

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#define MAXVOLUME 25
//#define volumeControl
 
SoftwareSerial softwareSerial1(10, 11); // RX, TX
SoftwareSerial softwareSerial2(2, 3); // RX, TX
DFRobotDFPlayerMini Player1;
DFRobotDFPlayerMini Player2;
 
struct player {
  String name;
  int button1pin;
  int button2pin;
  int potPin;
  bool button1State;
  bool button2State;
  int volume;
  SoftwareSerial* serial;
  DFRobotDFPlayerMini &player;
};
 
player player1 = {"player1", 4, 5, A0, HIGH, HIGH, 0, &softwareSerial1, Player1};
player player2 = {"player2", 6, 7, A1, HIGH, HIGH, 0, &softwareSerial2, Player2};
 
void setup()
{
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  initialise(player1);
  delay(2000);
  initialise(player2);
  delay(2000);
  digitalWrite(LED_BUILTIN, HIGH);
}
 
void loop() {
  DFRobotDFPlayerMini *test = &player1.player;
  playerHandle(&player1);
  playerHandle(&player2);
  delay(100);
}
 
void initialise(player DFplayer) {
  pinMode(DFplayer.button1pin, INPUT_PULLUP);
  pinMode(DFplayer.button2pin, INPUT_PULLUP);
  DFplayer.serial->begin(9600);
  if (!DFplayer.player.begin(*DFplayer.serial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true) { // blink fast on initialisation error
      digitalWrite(LED_BUILTIN, HIGH);
      delay(300);
      digitalWrite(LED_BUILTIN, LOW);
      delay(300);
      }
  }
  delay(1000);
  Serial.println(F("DFPlayer Mini online."));
  DFplayer.player.setTimeOut(500); //Set serial communication time out 500ms
  //----Set volume----
  DFplayer.player.volume(MAXVOLUME);  //Set volume value (0~30).
  //----Set different EQ----
    DFplayer.player.EQ(DFPLAYER_EQ_BASS);
  //----Set device we use SD as default----
  DFplayer.player.outputDevice(DFPLAYER_DEVICE_SD);
  //----Mp3 control----
  DFplayer.player.enableDAC();  //Enable On-chip DAC
}
 
void playerHandle (player *DFplayer) {
  bool button1 = digitalRead(DFplayer->button1pin);
  bool button2 = digitalRead(DFplayer->button2pin);
  int potValue = analogRead(DFplayer->potPin);
  DFRobotDFPlayerMini Player = DFplayer->player;
  if (button1 == LOW && DFplayer->button1State == HIGH) Player.play(1);
  if (button2 == LOW && DFplayer->button2State == HIGH) Player.play(2);
  #ifdef volumeControl
  int volume = map(potValue, 0, 1023, 0, MAXVOLUME);
  if (volume != DFplayer->volume) {Player.volume(volume); Serial.println(volume);}
  #endif
  DFplayer->button1State = button1;
  DFplayer->button2State = button2;
  DFplayer->volume = volume;
}