Auteur Sujet: Un mini module sonore  (Lu 86071 fois)

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Un mini module sonore
« le: mars 14, 2016, 11:46:50 am »
J'ai réalisé ce week-end un petit module sonore.

Le réalisme du modélisme nécessite de déclencher des sons selon des événements précis, à des endroits bien choisis. Pour cela j'ai besoin d'un petit module bon marché.

J'ai assemblé un mini, une carte lecteur microSD, un transistor NPN pour amplifier le son vers un haut-parleur 8 ohm standard et un régulateur 7809 pour pouvoir alimenter le montage avec du 12V.
Le mini est programmé avec une petite carte FTDI232 basic.

Le principe est simple, le programme attend que la pin 2 passe au 0V pour délivrer le son inscrit dans un fichier.

Il utilise les bibliothèques SD, SPI et TMRpcm

Voici le programme que vous pouvez adapter à vos besoins :

/*
 * Module sonore - Passage à Niveau
 * Base : un Nano + lecteur microSD + ampli BD241 + haut parleur
 * Version du 13/3/2016 Dominique Bultez
 */
 
#include <SD.h>                   // need to include the SD library
#define SD_ChipSelectPin 10       // using digital pin 10 on arduino nano 328, can use other pins
#include <TMRpcm.h>               //  also need to include this library...
#include <SPI.h>
/*
 * SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK).
 */
TMRpcm tmrpcm;                    // create an object for use in this sketch
File root;
int val;
int bouton, oldbouton = 0;
bool debouncing = false;
#define _Bouton 2
#define _LedSon 4
#define _niveau 4

/////////////////////// SETUP /////////////////

void setup(){

  tmrpcm.speakerPin = 9;              //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc
  pinMode(_LedSon,OUTPUT);            //LED Connected to pin 4
  digitalWrite(_LedSon, LOW);
  pinMode(_Bouton, INPUT_PULLUP);     // pour bouton ou commande extérieure sur pin 2
 
  Serial.begin(115200);
  if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail"); 
    while(1) {
      // led clignote
      digitalWrite(_LedSon, HIGH);    // allume Led
      delay(250);
      digitalWrite(_LedSon, LOW);     // eteint led
      delay(250);
    }
  }
  root = SD.open("/");
  //printDirectory(root, 0);
  //delay(500);
  Serial.println("SD OK");
  val = _niveau;
  //Joue(val);
}

//////////////////// LOOP //////////////////

void loop(){ 

while (Serial.available() > 0)
  {
    val = Serial.parseInt();  // lecture entier
    if (Serial.read() == '\n')
    {
      Serial.print("valeur : ");
      Serial.println(val);
      if (val == 0) {
        printDirectory(root, 0);
      } else {
        Joue(val);
      }
    }
  }

  bouton = digitalRead(_Bouton);
  if (bouton == LOW) {
    if (tmrpcm.isPlaying()) {
    } else {
      Joue(_niveau);
      //digitalWrite(_LedSon, HIGH);      // allume Led
    }
  } else {                              // bouton HIGH
      tmrpcm.stopPlayback();            // Stop all playback
      //digitalWrite(_LedSon, LOW);       // eteint Led
  }
 
  if(tmrpcm.isPlaying())  {
    digitalWrite(_LedSon, HIGH);
   } else {
    digitalWrite(_LedSon, LOW);
    }
}

//////////////// fin de loop ///////////////

void Joue(int a_val) {
      Serial.print("je joue ");Serial.println(a_val);
      switch (a_val) {
        case 1:
        tmrpcm.play((char*)("1.wav"));       
        break;
        case 2:
        tmrpcm.play((char*)("2.wav"));
        break;
        case 3:
        tmrpcm.play((char*)("3.wav"));
        break;
        case 4:
        tmrpcm.play((char*)("4.wav"));
        break;
        case 5:
        tmrpcm.play((char*)("5.wav"));
        break;
        case 6:
        tmrpcm.play((char*)("6.wav"));
        break;
        case 7:
        tmrpcm.play((char*)("7.wav"));
        break;
        case 8:
        tmrpcm.play((char*)("8.wav"));
        break;
        case 9:
        tmrpcm.play((char*)("9.wav"));
        break;
      }
}

void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       Serial.println("fin");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

Et il reste 14 pins libres ...
« Modifié: mars 14, 2016, 09:24:11 pm par Dominique »
Cordialement,
Dominique

DDEFF

  • Hero Member
  • *****
  • Messages: 760
    • Voir le profil
Re : Un mini module sonore
« Réponse #1 le: mars 14, 2016, 04:33:40 pm »
Tout simplement !  :D
Et tu as 9 sons sur ta SD.
"Ce n'est pas le puits qui est trop profond, c'est ta corde qui est trop courte" (proverbe chinois)

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : Un mini module sonore
« Réponse #2 le: mars 14, 2016, 05:37:26 pm »
C'est ce que tu avais proposé dans un article ?

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Re : Re : Un mini module sonore
« Réponse #3 le: mars 14, 2016, 05:55:51 pm »
C'est ce que tu avais proposé dans un article ?

Oui c'est une suite logique de l'article, une mise en œuvre nettement moins coûteuse.

En plus je vais essayer de faire fonctionner un passage à niveau en même temps avec des capteurs genre ILS et 2 relais.

J'ai mis 9 sons identiques sur la carte avec des niveaux différents pour choisir celui qui rend le mieux en fonction du HP choisi et de son emplacement.

Pour préparer les fichiers sons : Audacity !

Je ferais bien un circuit imprimé ...
Cordialement,
Dominique

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #4 le: octobre 23, 2016, 07:00:21 pm »
Bonsoir,
Le son est en boucle, comment faire pour qu'il ne passe qu'une fois. La fonction Delay ne fonctionne pas
Merci
 :)

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Re : Un mini module sonore
« Réponse #5 le: octobre 23, 2016, 08:19:53 pm »
Bonsoir,
Le son est en boucle, comment faire pour qu'il ne passe qu'une fois. La fonction Delay ne fonctionne pas
Merci
 :)

Pouvez-vous en dire un peu plus ?
Il n'y a aucune raison que la fonction delay() ne fonctionne pas. Une erreur s'est glissée soit dans le montage, soit dans le programme que vous avez recopié.

Je viens de faire le test et ça marche chez moi.
Cordialement,
Dominique

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #6 le: octobre 23, 2016, 09:27:28 pm »
Re bonsoir,

Voici le code qui ne fonctionne pas chez moi

void Joue(int a_val) {
      Serial.print("je joue ");Serial.println(a_val);
      switch (a_val) {
        case 1:
        tmrpcm.play((char*)("annonce1.wav")); 
        delay(1000);
        break;




De plus c'est le dernier bouton poussoir qui fonctionne, parmi les 3 installés

Re Bonsoir,

De plus avec les lignes suivantes, le son est le dernier de la liste ?

TMRpcm tmrpcm;                    // create an object for use in this sketch
File root;
int val;
int bouton, oldbouton = 0;

bool debouncing = false;

#define _Bouton 2
#define _LedSon 1
#define _niveau 2

#define _Bouton 3
#define _LedSon 2
#define _niveau 2

#define _Bouton 4
#define _LedSon 3
#define _niveau 2

Merci

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Re : Un mini module sonore
« Réponse #7 le: octobre 23, 2016, 11:08:14 pm »
Bonsoir,

Je ne vois pas bien ce qui cloche, il faudrait voir l'ensemble du code.

De toute façon dans ces 2 lignes :
tmrpcm.play((char*)("annonce1.wav")); 
        delay(1000);

Le "delay(1000);" ne sert à rien car tmrpcm joue en tache de fond : supprimez le.

Par contre, ce programme peut planter facilement par manque de mémoire, surtout si vous appelez la fonction printDirectory().
Vérifiez que la mémoire disponible affichée après la compilation est supérieur à 800 octets.
Pour récupérer de la mémoire, n'hésitez pas à remplacer Serial.print("quelque chose"); par Serial.print(F("quelque chose"));
Je vous conseille de modifier cette fonction printDirectory() comme suit :

void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       Serial.println("fin");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       // printDirectory(entry, numTabs+1); // supprimer les appels re-entrants
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}
« Modifié: octobre 23, 2016, 11:11:55 pm par Dominique »
Cordialement,
Dominique

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #8 le: octobre 24, 2016, 10:44:04 am »
Bonjour,

1er soucis : Après le téléversement, le bouton ne fonctionne pas, il faut que j'appuie sur le bouton reset de la carte UNO pour que le bouton "son" fonctionne ?
2 : Le fichier "#define _LedSon 1" n'a aucune influence que je mette 0 ou 5 il  ?
3: Le "#define _Bouton 2 est sur la broche PWM2, le 3 sur PWM3 et le 4 sur PWM4, mais quelque soit l'ordre, c'est le dernier qui fonctionne

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #9 le: octobre 24, 2016, 10:45:31 am »
Oups, erreur de doigt je n'ai pas fini mes explications
 :o

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #10 le: octobre 24, 2016, 10:52:15 am »
Bonjour,

1er soucis : Après le téléversement, le bouton "son" ne fonctionne pas, il faut que j'appuie sur le bouton reset de la carte UNO pour que le bouton "son" fonctionne ? Pour info après téléversement il reste 866 octets pour les variable lolcales
2 : Le fichier "#define _LedSon 1" n'a aucune influence que je mette 0 ou 5 il  ?
3: Le "#define _Bouton "son" 2 est sur la broche PWM2, le 3 sur PWM3 et le 4 sur PWM4, mais quelque soit l'ordre, c'est le dernier bouton qui fonctionne
Exemple :
#define _Bouton 2
#define _LedSon 1
#define _niveau 1

#define _Bouton 3
#define _LedSon 1
#define _niveau 2

Le bouton 3 fonctionne, mais pas le 2 ?

4: Le son passe en boucle, je n'arrive pas à faire "passer" le son une seule fois ?

J'ai vérifié les branchements et à priori pas de problème

Merci encore pour votre aide
Patrick


Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Re : Un mini module sonore
« Réponse #11 le: octobre 24, 2016, 10:56:58 am »
Je ne comprend pas votre problème ni votre programme !
Cette suite de #define est contradictoire.
Vos explications semblent démontrer que le programme se plante au démarrage. Quels tests avez-vous prévu ?
Envoyez-moi votre programme complet ET votre schéma, ça ira plus vite !

Bon courage
« Modifié: octobre 24, 2016, 11:24:25 am par Thierry »
Cordialement,
Dominique

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #12 le: octobre 24, 2016, 11:54:13 am »
Voici mon fichier
Merci

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3039
  • 100% Arduino et N
    • Voir le profil
Re : Un mini module sonore
« Réponse #13 le: octobre 24, 2016, 02:39:25 pm »
Il y a plusieurs choses :

#define _Bouton 2
#define _LedSon 4
#define _niveau 1

#define _Bouton 3
#define _LedSon 4
#define _niveau 2

#define _Bouton 4
#define _LedSon 4
#define _niveau 3

Ca revient à redéfinir 3 fois les mêmes étiquettes : il reste à la fin seulement la dernière : _Bouton = 4, _LedSon = 4, _niveau = 3,
donc seul le bouton en pin 4 fonctionne et joue le "niveau 3"
Les boutons sur les pins 2 et 3 n'existent pas dans votre programme.
Il faudrait définir _Bouton2, _Bouton3 et _Bouton4 et les tester tous les 3 dans le programme.

Enfin, comme je vous l'ai dit, commentez la ligne printDirectory(entry, numTabs+1); dans void printDirectory(File dir, int numTabs), car ça doit planter (éviter la récursivité dans si peu de mémoire).

Est-ce que vos sons sont bien écrits dans la carte microSD ?
Je testerai votre programme un peu plus tard.
Cordialement,
Dominique

Papachef

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Un mini module sonore
« Réponse #14 le: octobre 24, 2016, 06:18:39 pm »
Bonsoir,
Pour jouer le son il faut toujours faire Reset sur la carte UNO
A priori je suis au bout de mes compétences car je n'arrive pas à définir les boutons 2,3 et 4
Les sons sont bien inscrits sur la carte
En gros, je sèche
Merci