La carte Leonardo est programmé avec l’IDE Arduino.
Le code est assez simple, car il se compose de plusieurs exemples connus et librairies arduino :
- La librairie DFRobot_DF1201S pour commander le DFPlayer Pro en série via le port UART
- Un debounce des boutons poussoirs avec la librarie Bounce2
- Une fonction smooth permettant de lisser les valeurs du bouton de volume
Le code s’initialise avec plusieurs constantes et variables :
- buttonPin : les pins associés au 12 boutons sont scannés afin de voir si ils sont appuyés
- lastDebounceTime et debounceDelay : le temps depuis lequel le bouton a été appuyé est stocké dans un tableau afin de faire un debounce
- volumePin et mutePin : les pins A0 et A1 où sont connectés le bouton de volume et le switch de la prise casque
- lastIndexPlayed : dernier bouton joué, ce qui permet de mettre en pause en cas d’appuie sur le même bouton
Afin de ne pas trop pousser l’amplificateur du DFPlayerPro dans ses retranchements, le volume maximum est réduit par rapport à ce qu’il est possible par la librairie. Cela permet de ne pas aller à la saturation de l’amplificateur, ce qui est courant sur les amplificateurs 3W de class D où la puissance maximale est souvent donnée pour un THD (saturation) de 10%.
Le souci majeur rencontré avec la programmation de la boite à comptine a été le delai du lancement d’une comptine due à la fonction DF1201S.isPlaying(). Cette fonction est utilisée afin de pouvoir arrêter la lecture si une comptine est en train d’être lue.
Contrairement au DFPlayer “classique” le DFPlayerPro ne présente pas de pin “busy” permettant de savoir s’il y a une lecture en cours. Il a fallu donc passer par la fonction logicielle DF1201S.isPlaying().
La fonction n’est d’ailleurs pas présente dans la documentation de base de la carte, notamment car c’est une fonctionnalité ajouté à posteriori. Un delai de 2000ms est ajouté dans la fonction isPlaying() car celle-ci repose sur l’usage de DF1201S.getCurTime(), qui donne le temps de lecture en seconde (et non en miliseconde).
Cette méthode pose deux problèmes :
- un délai de 2s au lancement de chaque son
- la fonction est bloquante, ce qui met en pause l’exécution du programme
Afin de corriger cela, nous avons programmé une nouvelle version de la fonction DF1201S.isPlaying() qui teste en continu si le DFPlayer Pro est en lecture ou en pause. Ainsi la fonction isPlaying mesure toute les secondes si la lecture d’un fichier est en cours, et stocke cet état dans la variable booléenne isPlayingFlag.
// Rewritting of the isPlaying fonction of DFPlayer Pro lib making it non-blocking and changing the delay to 1s
bool isPlaying() {
if (!startMeasure) {
lastMeasure = DF1201S.getCurTime();
startMeasure = true;
isPlayingElapsedMillis = 0;
}
if (isPlayingElapsedMillis > 1000) {
uint16_t newMeasure = DF1201S.getCurTime();
if (newMeasure – lastMeasure != 0) {
isPlayingFlag = true;
} else {
isPlayingFlag = false;
}
startMeasure = false;
}
}
Une amélioration possible du programme serait de passer directement en UART afin de voir s’il est possible d’avoir le temps de lecture en milliseconde, ce qui permettrait de réduire de délai de la fonction isPlaying().