24 Janvier 2014
Leçon 7 : les notes de musique

les fonctions musicales
la fonction tone()
Cette fonction permet d'envoyer un signal périodique qui peut jouer des notes de musique si on l'envoie sur un haut-parleur.
sa syntaxe est
tone(broche, frequence, durée);
la fonction notone()
Cette fonction est nécessaire pour libérer la broche qui vient de jouer.
Tant qu'elle n'est pas appelée, on ne peut pas jouer de note sur une autre broche.
la fonction delay()
Vous la connaissez déjà.
On l'appelle entre chaque note pour qu'elles ne soient pas "collées".
Pour simplifier, on lui donnera la valeur 600 dans le 1er programme.
Dans les suivants on fera varier cette valeur en fonction de la durée de la note précédente.
montage
Plusieurs broches conviennent mais une seule à la fois. Impossible de jouer un morceau à plusieurs voix.
On utilisera la broche 8 d'Arduino en mettant un haut-parleur de 8 ohms entre cette broche et la masse.
programmation

Dans la gamme 3, la fréquence du DO est 262, celle du RÉ 294, celle du MI 330.
on choisira des durées de 400 ms pour les noires.
calculez les autres durées.
Vous en savez maintenant assez pour programmer ce morceau.

listes de notes et de durées
les listes
On ne passe pas les notes une par une mais on passe au programme l'adresse d'une liste de notes.
On lui passe aussi l'adresse d'une liste de durées.
passage de paramètreQuand nous passons un paramètre à une fonction, nous pouvons le faire de 2 manières :
|
premier programme avec liste
Remarquez la manière de déclarer un tableau initialisé de constantes.
// clair_de_lune.ino const int clairLune[] = {262, 262, 262, 294, 330, 294, 262, 330, 294, 294, 262 } ; const int dureeLune[] = {400, 400, 400, 400, 800, 800, 400, 400, 400, 400, 1200 }; void jouer(int* , int* , int ); // déclaration de fonction void setup() { pinMode( 8 , OUTPUT ); jouer(clairLune, dureeLune, 11); // Au clair ... Pierrot, delay(800); // pause jouer(clairLune, dureeLune, 11); // Prête-moi ... un mot. } void loop() { //rien si on ne veut pas jouer en continu } void jouer(const int* listeNotes, const int* dureesNotes, int nbNotes) { for (int numNote = 0; numNote < nbNotes; numNote++) { int duree = dureesNotes[numNote]; tone(8, listeNotes[numNote], duree); delay(duree * 1.3); } noTone(8); // libère la sortie 8 } |
La partie importante de cette séance n'est pas la manière de jouer une note mais le passage de paramètres
à la fonction jouer().
|
31 Janvier 2014
utilisation d'un fichier .h
Dans les programmes utilisant l'afficheur, nous avions appelé le fichier LiquidCrystal.h avec la directive #include
Ce fichier contenait des définitions vraies pour tous les afficheurs et son rôle était de nous éviter de les réécrire
dans chaque programme.
J'en ai écrit un pour éviter de répéter les fréquences des notes et leurs durées.
Son principe est simple : il permet au compilateur de savoir par exemple que "DO" veut dire "262 hertz" ou que "N" veut dire 400ms.
On l'appelle en écrivant en tête du programme #include mesnotes.h
Il faut aussi copier ce programme dans le même répertoire que le programme principal. Nous n'avions pas eu besoin de
recopier LiquidCrystal.h parce qu'il était compris dans le programme Arduino.
Nous allons en faire l'expérience avec Frère Jacques.
Frère Jacques avec #include
// frereJacques.ino #include "mesNotes.h" int frereJacques1[] = {FA4, SOL4, LA4, FA4, FA4, SOL4, LA4, FA4, LA4, LAdi4, DO5, LA4, LAdi4, DO5 } ; int dureeJacques1[] = {N, N, N, N, N, N, N, N, N, N, B, N, N, B }; void jouer(int* , int* , int ); void setup() { jouer(frereJacques1, dureeJacques1, 14); } void loop() { //rien si on ne veut pas jouer en continu } void jouer(int*listeNotes, int*dureesNotes, int nbNotes) { for (int numNote = 0; numNote < nbNotes; numNote++) { int duree = dureesNotes[numNote]; tone(8, listeNotes[numNote], duree); // On sépare les notes d'un intervale égal à 1,3 fois la note jouée. int pause = duree * 1.30; delay(pause); } noTone(8); // libère sortie 8 } |
cliquez sur cette ligne pour récupérer le fichier mesNotes.h
choix de l'air à jouer
On va utiliser le moniteur série pour choisir l'air à jouer : Frère Jacques quand on envoie J ou bien La Truite quand on envoie T .
#include "mesNotes.h" int frereJacques1[] = {FA4, SOL4, LA4, FA4, FA4, SOL4, LA4, FA4, LA4, LAdi4, DO5, LA4, LAdi4, DO5 } ; int frereJacques2[] = {DO5, RE5, DO5, LAdi4, LA4, FA4, DO5, RE5, DO5, LAdi4, LA4, FA4, FA4, DO4, FA4, 0, FA4, DO4, FA4 } ; int laTruite1[] = {SOL4, DO5, DO5, MI5, MI5, DO5, SOL4, SOL4, SOL4, SOL4, RE5, DO5, SI4, LA4, SOL4 }; int laTruite2[] = {SOL4, DO5, DO5, MI5, MI5, DO5, SOL4, DO5, SI4, LA4, SI4, DO5, FAdi4, SOL4}; int dureeJacques1[] = {N, N, N, N, N, N, N, N, N, N, B, N, N, B }; int dureeJacques2[] = {300, D, C, C, N, N, 300, D, C, C, N, N, N, N, N, N, N, N} ; int dureelaTruite1[] = {C, C, C, C, C, N, C, C, 300, D, D, D, D, D, N } ; int dureelaTruite2[] = {C, C, C, C, C, N, C, C, D, D, C, C, N } ; int i, recu[20]; void jouer(int* , int* , int ); void setup() { Serial.begin(9600); Serial.print("envoyez J pour Frere Jacques ou T pour La Truite"); } void loop() { i = 0 ; while ( Serial.available()>0 ) { recu[i] = Serial.read(); i++; delay(100); } if (i>0) { switch (recu[0]) { case 'j' : case 'J' : jouer(frereJacques1, dureeJacques1, 14); jouer(frereJacques2, dureeJacques2, 19); break; case 't' : case 'T' : jouer(laTruite1, dureelaTruite1, 15); jouer(laTruite2, dureelaTruite2, 14); break; } } } void jouer(int*listeNotes, int*dureesNotes, int nbNotes) { for (int numNote = 0; numNote < nbNotes; numNote++) { int duree = dureesNotes[numNote]; tone(8, listeNotes[numNote],duree); // On sépare les notes d'un intervale égal à 1,3 fois la note jouée. int pause = duree * 1.30; delay(pause); } noTone(8); // libère sortie 8 } |
Maintenant, il ne vous reste plus qu'à traduire chaque symphonie de Beethoven en langage Arduino. :)
haut de la page

