IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Nouvelle bibliothèque "Musique"


Sujet :

Arduino

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Autodidacte oisif et versatile
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte oisif et versatile
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Points : 7
    Points
    7
    Par défaut Nouvelle bibliothèque "Musique"
    Bonjour
    Je suis nouveau sur Arduino (et en C) et un de mes premiers projets est de développer des jouets pour bébé. Pour cela j'ai besoin de jouer des musiques de comptines.
    J'ai des dizaines de morceaux composés chacun de dizaines de notes. Plutôt que de taper laborieusement mes fréquences et mes durées avec "Tone" dans des tableaux de chiffres, j'ai développé un petit programme qui permet d'entrer une partition "au kilomètre" et de la faire jouer, en entrant une simple chaine : "LA31MI42SO22DO53" qui veut dire La de la gamme 3 (440hz) pendant 1 temps, ensuite Mi de la gamme 4 pendant 2 temps etc.

    Je souhaite transformer ce programme en un objet de bibliothèque pour l'utiliser dans mes différentes applications. Je bloque à la déclaration de mon tableau de notes "char *note[]" qui donne des erreurs de compilation: où et comment faut-il le faire? dans le .h? dans le .cpp? avec [] ou pas? avec une * ? avec un dimensionnement? Tout marche dans mon petit programme ci-dessous, mais impossible d'en faire un include.
    Après plusieurs tentatives infructueuses et plusieurs jours de lectures sur les classes, les objets les includes, pointeurs et autres je me tourne vers vous pour des conseils.

    J'ai mis en gras ce qui pose souci (pour info j'ai réussi à faire mon objet en transformant le tableau note[] en string ("DODDREMBMIFAFD...") et j'en extrais 2 à 2 les caractères avec substring mais il y a peut-être plus simple, plus économe, plus rapide et plus élégant? j'ai mis ces fichiers en PJ si vous voulez les utiliser, ils fonctionnent bien, et c'est CADEAU!)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    const char *note[] = {"DO","DD","RE","MB","MI","FA","FD","SO","SD","LA","SB","SI","SL"};
    const int tempo=300, brocheBIP=10;
    const String partition = "SI21MI31MB31SI21MI31FD31SO32";
    const int longueur = partition.length();
    int frequence;
    byte duree, gamme;
    String noteLue;
    
    void setup() {
      pinMode(brocheBIP,OUTPUT);
    }
    
    void loop() {
      for (int i=1 ; i < longueur;  i+=4) {
        noteLue = partition.substring(i-1,i+1) ;
        byte j=1;
        while (j < 14) {
          if (noteLue == note[j-1]) {
            gamme = partition.substring(i+1,i+2).toInt() ;
            duree = partition.substring(i+2,i+3).toInt() ;  
            frequence=int(440*pow(2,(gamme+j/12-15/4)));
            if (j==13) {
              noTone(brocheBIP);
              } else {
              tone(brocheBIP, frequence,(60000/tempo)*duree);
              } 
            delay((60000/tempo)*duree);
            noTone(brocheBIP);
          }
        j++;
        }
      }
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 758
    Points : 57 813
    Points
    57 813
    Billets dans le blog
    42
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const char *note[] = {"DO","DD","RE","MB","MI","FA","FD","SO","SD","LA","SB","SI","SL"};
    ...
    String noteLue;
     
    void setup() {
     ...
    }
     
    void loop() {
      ...
          if (noteLue == note[j-1]) {
          ...      }
       ...
    }
    Le souci est que note est un tableau de char en C alors que noteLue est une instance de la classe String, un truc développé pour l'IDE Arduino qui facilite les traitements sur les chaînes de caractères et qui n'est pas très optimisé.

    Si on veut optimiser, on évite les String, on utilise que des char et on utilise strcmppour tester l'égalité.

    à tenter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const String note[] = {"DO","DD","RE","MB","MI","FA","FD","SO","SD","LA","SB","SI","SL"};
    ...
    String noteLue;
     
    void setup() {
     ...
    }
     
    void loop() {
      ...
          if (noteLue == note[j-1]) {
          ...      }
       ...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const char *note[] = {"DO","DD","RE","MB","MI","FA","FD","SO","SD","LA","SB","SI","SL"};
    ...
    String noteLue;
     
    void setup() {
     ...
    }
     
    void loop() {
      ...
          if (strcmp(noteLue.c_str(), note[j-1])==0) {
          ...      }
       ...
    }
    etc.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Autodidacte oisif et versatile
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte oisif et versatile
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Points : 7
    Points
    7
    Par défaut
    merci de ta réponse rapide, c'est déjà ça, j'ai appris un truc (pas vraiment intuitif comme syntaxe!) et j'économise 40 octets de programme.
    Mais ça ne résout pas mon problème. mon but est de faire de ce petit programme une fonction séparée
    Pour mieux me faire comprendre, ci-dessous j'ai créé la fonction "joue" dans le fichier principal : je voudrais savoir comment la sortir dans un autre fichier pour pouvoir l'appeler avec un #include, merci (pour le moment j'ai essayé la méthode de Robot-maker en copiant/collant sans trop comprendre car c'est pas bien expliqué, ça a marché pour ma méthode avec String (cf Musique.zip dans mon mail précédent) mais pas avec la méthode avec le tableau char *note[] : ça plante la compilation de mon .h et de mon .cpp)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    int tempo=300, la=440 ;
    byte brocheBIP=10 ;
     
    void setup() {
      pinMode(brocheBIP,OUTPUT);
    }
     
    void loop() {
    Joue(la,tempo,F("SI21MI31MB31SI21MI31FD31SO32"));
    }
     
    void Joue(int f_la, int f_tempo, String f_partition) {
    char *note[] = {"DO","DD","RE","MB","MI","FA","FD","SO","SD","LA","SB","SI","SL"};
    int longueur = f_partition.length();
    int frequence;
    byte duree, gamme;
    String noteLue;
    for (int i=1 ; i < longueur;  i+=4) {
      noteLue = f_partition.substring(i-1,i+1) ;
      byte j=1;
      while (j < 14) {
       if (strcmp(noteLue.c_str(), note[j-1])==0) {
          gamme = f_partition.substring(i+1,i+2).toInt() ;
          duree = f_partition.substring(i+2,i+3).toInt() ;  
          frequence=int(f_la*pow(2.0,(gamme+j/12.0-15.0/4.0)));
          if (j==13) {
            noTone(brocheBIP);
            } else {
            tone(brocheBIP, frequence,(60000/f_tempo)*duree);
          } 
          delay((60000/f_tempo)*duree);
          noTone(brocheBIP);
        }
      j++;
      }
    }
    }

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 758
    Points : 57 813
    Points
    57 813
    Billets dans le blog
    42
    Par défaut
    Citation Envoyé par arduiNoob Voir le message
    ça a marché pour ma méthode avec String (cf Musique.zip dans mon mail précédent)...
    Pour lever tes erreurs de compilation (sans connaître les messages d'erreur en plus) de ton programme, il ne faut pas seulement nous montrer les codes de la version qui fonctionne déjà ?

    Citation Envoyé par arduiNoob Voir le message
    ...mais pas avec la méthode avec le tableau char *note[] : ça plante la compilation de mon .h et de mon .cpp)
    C'est ce code-là qu'il faudrait poster...

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Autodidacte oisif et versatile
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte oisif et versatile
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Points : 7
    Points
    7
    Par défaut
    oui ce matin : je nettoye un peu le code pour qu'il soit "présentable" avant de le poster sur ce forum et là comme par miracle .... CA MAAARCHE !
    Non j'avoue je me suis bien documenté aussi et j'ai compris : il faut rester simple. Voilà mon conseil pour ceux qui seraient dans le même cas que moi dans le futur: oubliez les crochets et mettez des p'tites z'étoiles!
    L'intérêt, c'est que sans utiliser de "strings" je simplifie le code et je passe à 4966 octets au lieu de 7148 dans la première version !

    LE CROQUIS : (restons français)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <Musique.h>
     
    // Arduino joue ces huit notes en broche 10 et s'arrête. La partition est la chaîne qui posait problème à exporter en tant que tableau de "char" dans la classe Musique.
    Musique musique(440,300,10,"SI21MI31MB31SI21MI31FD31SO32LA31");
    void setup() {}
    void loop() { musique.joue();  while(1); }
    L'EN-TETE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef Musique_h
    #define Musique_h
    #include <arduino.h>
    
    class Musique 
    {
    public:
    Musique(int la, int tempo, byte brocheBIP, char *partition);
    void joue();
    
    private:
    char *_partition;
    int _la, _tempo, frequence;
    byte _brocheBIP, gamme;
    };
    
    #endif
    LE CONSTRUCTEUR ET LA METHODE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <arduino.h>
    #include "Musique.h"
    
    Musique::Musique(int la, int tempo, byte brocheBIP, char *partition) 
    {
    	pinMode(brocheBIP, OUTPUT);
    	_la=la;
    	_tempo=tempo ;
    	_brocheBIP=brocheBIP;
    	_partition = partition;
    	byte gamme;
    	int frequence;
    }
    
    void Musique::joue()
    {
    
    //on maintenant appeler sans problème les valeurs de _partition[i]
    
    }
    donc classement ==> AFFAIRE RESOLUE

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo