[Résolu] SFEMP3Shield + IRremote

Salut à tous.

J'ai pour projet de créer un lecteur MP3 piloté avec une télécommande IR (infrarouge).
Mais je rencontre quelques problèmes de mise en oeuvre.
J'ai donc besoin de votre aide.

Matériels utilisés :

Librairies Arduino utilisées :

J'ai tout d'abord testé le shield MP3 grâce à l'exemple FilePlayer fourni avec la librairie SFEMP3Shield.
Tout marche nickel.

J'ai ensuite fait un sketch pour récupérer les signaux de la télécommande (Pièce-jointe : Telecommande_receiver.ino).
Lui aussi marche nickel.
J'ai ainsi pu récupérer le code des touches qui n'intéressaient et faire un nouveau sketch (Pièce-jointe : Skeleton.ino) qui me servira de base pour contrôler le shield MP3.

J'ai alors entrepris de mixer ce sketch avec l'exemple FilePlayer (Pièce-jointe : PlayerMP3.ino).
C'est là que les problèmes sont apparus.
La 1ère fois que j'utilise la télécommande, ça marche.
Tant que la chanson n'est pas terminée, le code de la touche appuyée récupéré est erroné.
Lorsque la chanson est finie, le récepteur IR renvoi le bon code.
Et ainsi de suite.

Après avoir fait des recherches sur le net, j'en ai déduit qu'il s'agissait de conflits entre les interruptions externes utilisées par les 2 librairies SFEMP3Shield et IRremote.

L'arduino UNO peut gérer 2 interruptions externes.
J'ai alors d'abord essayé de modifier les librairies pour qu'ils utilisent une interruption différente.
Test 1 :
J'ai essayé de changer IrremoteInt.h ligne 66 à 67 :

//#define IR_USE_TIMER1 // tx = pin 9
#define IR_USE_TIMER2 // tx = pin 3

par

#define IR_USE_TIMER1 // tx = pin 9
//#define IR_USE_TIMER2 // tx = pin 3

Cela n'a rien changé : toujours un code erroné tant qu'une chanson est jouée.

Test 2 :
J'ai remis le fichier IrremoteInt.h original et j'ai essayé de modifier SFEMP3ShieldConfig.h ligne 187 :

#define MP3_DREQINT          0

par

#define MP3_DREQINT          1

Dans ce cas, la télécommande marche mais aucune chanson ne se lance pas.

J'ai alors testé différentes choses sur la librairie SFEMP3Shield :
Test 3 :
J'ai remis le fichier SFEMP3ShieldConfig.h original et je l'ai re-modifié en changeant la ligne 220 :

#define USE_MP3_REFILL_MEANS USE_MP3_INTx

par

#define USE_MP3_REFILL_MEANS USE_MP3_Polled

Et j'ai aussi ajouté la ligne suivante au tout début de mon loop () :

MP3player.available ();

Dans ce cas, ça marche plutôt bien : la télécommande est utilisable même lorsqu'une chanson est en cours de lecture.
Par contre, certaines fonctions de librairie SFEMP3Shield ne marchent plus comme :

  • pauseMusic
  • resumeMusic

Et lorsque j'utilise end () là plus rien ne marche.
Idem lorsque je teste avec l'exemple FilePlayer

Test 4 :
Je suis reparti des fichiers originaux et j'ai re-modifié le fichier SFEMP3ShieldConfig.h en changeant la ligne 220 :

#define USE_MP3_REFILL_MEANS USE_MP3_INTx

par

#define USE_MP3_REFILL_MEANS USE_MP3_Timer1

J'ai alors installé la librairie TimerOne et l'ai inclus dans mon code.
J'ai aussi remis la ligne suivante au tout début de mon loop () :

MP3player.available ();

Là je reviens au problème de base : la télécommande n'est plus utilisable tant qu'une chanson est en cours de lecture.

Test 5 :
Je suis reparti des fichiers originaux et j'ai re-modifié le fichier SFEMP3ShieldConfig.h en changeant la ligne 220 :

#define USE_MP3_REFILL_MEANS USE_MP3_INTx

par

#define USE_MP3_REFILL_MEANS USE_MP3_SimpleTimer

J'ai alors installé la librairie SimpleTimer et l'ai inclus dans mon code.
Là je reviens au test 2 : la télécommande marche mais aucune chanson ne se lance pas.

Je ne sais plus quoi tester !
J'ai besoin d'un coup de pouce.
Merci d'avance pour votre aide.

Telecommande_receiver.ino (295 Bytes)

Skeleton.ino (1.76 KB)

PlayerMP3.ino (4.52 KB)

Hum ça sent le conflit entre l'IR et le lecteur MP3 ça !!!

Regarde bien les pins utilisé etc, il doit y avoir un truc en commun qui bug tout !

Merci skizoh pour ton aide

J'ai testé de mettre le capteur IR sur différentes pins (11, A0 à A5) et rien n'a changé.
Je suis quasiment sûr que le MP3 player shield n'utilise pas les sorties analogiques.

Mon avis est que le conflit se situe au niveau des interruptions et/ou des timers.
Mais je pensais que les tests décrits précédemment auraient empêchés ça, mais non.
Difficile pour moi de déboguer ces librairies : ça dépasse de trop loin mon niveau.

Si personnes ne peut m'aider, je vais m'orienter vers une solution avec 2 arduino : 1 pour le MP3 player shield et 1 pour le capteur IR.
Et je les ferai communiquer ensemble via l'interface série.
Mais cette solution ne me plait pas trop et j'aimerai vraiment trouver comment résoudre ce problème.

J'ai choisi une approche un peu différente de la tienne. Plutôt que l'infrarouge j'utilise une connexion utp pour commander mon lecteur mp3.
J'ai réalisé une première version avec une platine Arduino Ethernet et un module Rogue rMP3 qui me donne entière satisfaction. Le site larocola.net est dédié à cette réalisation.
Je développe maintenant une seconde version qui me permet, en plus de lire les fichiers audios dans différents codecs, d'écouter la radio en streaming. Pour cela j'utilise un Arduino Due, un module WIZ820io (plus rapide que le module Arduino Ethernet) et le module MP3 Player de Sparkfun. Le projet est bien avancé et j'ai déjà publié quelques information ici: La Rocola – Mes projets pour mieux profiter de mon hamac.
Pour éviter des conflits entre les différents périphériques, je n'utilise pas le mode "interruption" de la librairie SFEMP3Shield mais le mode "polled" (#define USE_MP3_REFILL_MEANS USE_MP3_Polled dans SFEMP3ShieldConfig.h)
J'espère que cette info pourra t'aider.

Merci gallegojm,

Je vais regarder ton projet avec beaucoup d'intérêt.

Pour ma part, je ne souhaite pas utiliser de connexion Ethernet comme télécommande.
Pas de prise Ethernet là où sera le lecteur mp3.
Mais pourquoi pas du wifi.
Je vais y penser pour la v2.
Merci pour cette idée.

J'ai testé le mode "polled".
Voir mon test 3.
C'est avec lui que j'arrive à utiliser la télécommande IR en même temps que le player MP3.
Par contre, certaines fonctionnalité du player MP3 ne marche plus dans ce mode comme pauseMusic.
Et lorsque je le met en veille (fonction end), là plus rien ne marche.

Je viens de voir sur ce post que tu as détecté le même problème que moi pour la mise en pause.
Par contre, je n'ai pas compris la réponse qui t'as été donné.
Pourrais-tu me l'expliquer, stp ?

La réponse de Bill Porter concerne la deuxième partie de ce post (currentPosition(), etc...)
Pour pauseMusic(), j'apporte moi-même une solution, en modifiant la fonction available() de la bibliothèque SFEMP3Shield.
J'ai remplacé (vers la ligne 1677)

#elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Polled
  refill();
#endif

par

#elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Polled
  if( playing_state != paused_playback )
	  refill();
#endif

Une autre suggestion:
Fais-tu tes tests avec des fichiers mp3 de différents bitrate? Juste pour t'assurer que l'Arduino Uno a le temps de faire tout ce que tu lui demandes

Je confirme que ta modif marche pour la mise en pause lorsqu'on est en mode "polled".

Faute de temps libre, je n'ai pas encore compris ce qu'implique cette correction.
Mais je vais peut-être pouvoir m'en inspirer pour corriger le problème de mise en veille.

Je vous tiendrais informé.

Merci gallegojm

Je n'utilise pas la fonction end(), mais en lisant les commentaires dans SFEMP3Shield.cpp vers la ligne 151:
"use begin() to reinitialize the VS10xx, for use"
As-tu essayé?

Sinon, s'il s'agit simplement d'arrêter la lecture, il vaut mieux utiliser la fonction stopTrack()
Bonne chance!

oui j'ai testé begin () pour relancer le player après un end ().
C'est justement ça qui ne marchait pas.

Le end () n'est pas pareil que le stop () :
Il permet de mettre en veille le lecteur MP3 et donc d'économiser du courant.
Pratique si on est sur batterie.

J'ai bêtement essayé de modifier la librairie comme tu l'avais fait pour la pause.
J'ai remplacé (à la ligne 1677 de SFEMP3Shield.cpp)

#elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Polled
  refill();
#endif

par

#elif defined(USE_MP3_REFILL_MEANS) && USE_MP3_REFILL_MEANS == USE_MP3_Polled
  if ((playing_state != paused_playback) && (playing_state != deactivated))
    refill();
#endif

et ça marche !
Je n'ai plus qu'à comprendre ce que j'ai fait XD

Encore un grand merci à toi gallegojm pour ton aide.
Je vais pouvoir passer ce post en "résolu".
Je vais aussi reporter ce bug à l'auteur de la librairie et lui proposer notre patch.