Problème avec tone() + array [RESOLU]

Bonsoir,

Est-ce que quelqu'un sait pourquoi, dans la fonction playIW(), ce qui est en commentaire marche, mais ce qui est entre astérisques ne marche pas? (Seulement la première note est jouée)

/* Arduino Pro Mini 5V, 16MHz 
 * GND----1K resistance in series with---- small loudspeaker----pin 10
 * GND----GND IR receiver    VCC----VCC IR receiver   IR receiver output----pin 9
 * Plays a tune from an array or notes from a Sony-type remote.
 */

#define C5  523
#define D5  587
#define DS5 622
#define E5  659
#define F5  698
#define FS5 740
#define G5  784
#define GS5 831
#define A5  880
#define AS5 932
#define B5  988
#define C6  1047
#define CS6 1109
#define D6  1175
#define DS6 1245
#define E6  1319
#define F6  1397
#define FS6 1480
#define G6  1568
#define GS6 1661
#define A6  1760
#define AS6 1865
#define B6  1976
#define CS7 2093

#define quaver  150
#define squaver  75
#define crochetp  450

const int notepin = 10;

int IWnotes[] = {D6,quaver,C6,quaver,B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,D5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,B5,quaver,G5,quaver,B5,quaver,D6,quaver,C6,quaver,B5,quaver,C6,quaver,A5,squaver,0,squaver,A5,squaver,0,squaver,E5,quaver,A5,squaver,0,squaver,A5,squaver,0,squaver,C6,quaver,A5,quaver,C6,quaver,E6,quaver,D6,quaver,C6,quaver,

B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,D5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,B5,quaver,G5,quaver,B5,quaver,D6,quaver,C6,quaver,B5,quaver,C6,quaver,B5,quaver,C6,quaver,A5,quaver,D6,quaver,C6,quaver,B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,G5,crochetp,D6,quaver,

B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,D5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,B5,quaver,G5,quaver,B5,quaver,D6,quaver,C6,quaver,B5,quaver,C6,quaver,A5,squaver,0,squaver,A5,squaver,0,squaver,E5,quaver,A5,squaver,0,squaver,A5,squaver,0,squaver,C6,quaver,A5,quaver,C6,quaver,E6,quaver,D6,quaver,C6,quaver,

B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,D5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,B5,quaver,G5,quaver,B5,quaver,D6,quaver,C6,quaver,B5,quaver,C6,quaver,B5,quaver,C6,quaver,A5,quaver,D6,quaver,C6,quaver,B5,quaver,G5,squaver,0,squaver,G5,squaver,0,squaver,G5,crochetp,D6,quaver,

G6,quaver,FS6,quaver,G6,quaver,G5,quaver,B5,quaver,D6,quaver,G6,quaver,FS6,quaver,G6,quaver,B6,quaver,A6,quaver,G6,quaver,FS6,quaver,D6,squaver,0,squaver,D6,squaver,0,squaver,A5,quaver,D6,squaver,0,squaver,D6,squaver,0,squaver,FS6,quaver,D6,quaver,FS6,quaver,A6,quaver,G6,quaver,FS6,quaver,

E6,quaver,G6,squaver,0,squaver,G6,squaver,0,squaver,D6,quaver,G6,squaver,0,squaver,G6,squaver,0,squaver,C6,quaver,G6,squaver,0,squaver,G6,squaver,0,squaver,B5,quaver,G6,squaver,0,squaver,G6,squaver,0,squaver,C6,quaver,B5,quaver,C6,quaver,A5,quaver,D6,quaver,C6,squaver,0,squaver,B5,squaver,0,squaver,G5,squaver,0,squaver,G5,squaver,0,squaver,G5,500,-1,-1};


void playIW()                      // Plays an array of notes(note,duration)
{
 int i = 0;
 while(IWnotes[i] != -1)

 {
   /*tone(notepin,IWnotes[i]);
   delay(IWnotes[i+1]);
   noTone(notepin);
   i += 2;*/
  //*********************** 
   tone(notepin,IWnotes[i],IWnotes[i+1]);
   i+=2;
   //*************************/
 }
}

void setup()
{
  pinMode(notepin, OUTPUT);
  
  playIW();
}

void loop(){}

Merci.

Bonjour,

Parce que la fonction tone n'est pas bloquante, elle fonctionne en tache de fond Si tu mets tone(note,temps); , il n'y auras pas d'attente de temps avant la fin de l'instruction note, la note suivante sera jouée immédiatement. Il faut donc mettre un délai après tone()

@kamill

Merci pour ta réponse, mais alors, à quoi sert tone(pin,frequency,DURATION) si la fonction ne tient pas compte de DURATION?

EDIT: Si quelqu'un sait où se trouve le code source pour tone(), j'aimerais bien le lire.

/cygdrive/e/ardu/Arduino/hardware/arduino/avr/cores/arduino/Tone.cpp sur mon pc ... Il est plus facile de consulter https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Tone.cpp

La durée Sert a arrêter le son automatiquement sans que vous vous en souciez et votre programme lui continue à tourner - c’est non bloquant

Merci dbrion06, je n'avais pas pensé à ça. Encore une convention du langage C(++), je suppose.

kl@PBStretch:~$ sudo find / -name *.cpp | grep tone kl@PBStretch:~$ sudo find / -name *.cpp | grep Tone /home/kl/.arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/Tone.cpp /home/kl/arduino-1.8.4/hardware/arduino/avr/cores/arduino/Tone.cpp /usr/share/arduino/hardware/arduino/cores/arduino/Tone.cpp /usr/share/arduino/hardware/arduino/cores/robot/Tone.cpp kl@PBStretch:~$

On ne m'aura plus.

@J-M-L:

J'ai bien compris pour le coté non-bloquant, c'est juste que je trouve bizarre que l'on ne peut pas jouer une suite de notes avec tone(pin, fréquence, durée) alors que la fonction est dédié à ça. Un tableau de plus de 200 éléments pour faire "beep", c'est presque aussi drôle que la blague de la majuscule.

Tiens, c'est l'heure du Thé..... :)

Je ne comprends pas ce que vous dites… On peut… il faut faire

tone(pin, fréquence, durée) ; delay(durée);
tone(pin, fréquence, durée) ; delay(durée);
tone(pin, fréquence, durée) ; delay(durée);
tone(pin, fréquence, durée) ; delay(durée);
...

(sans accents :slight_smile: )

et vous mettez cela dans une boucle donc

for(byte i=0; i<200; i++) {
  tone(pin, frequence[i], duree[i]) ; 
  delay(duree[i]);
}

ou juste

for(byte i=0; i<200; i++) {
  tone(pin, frequence[i]) ; // joue cette note jusque'à contre-ordre  
  delay(duree[i]);
}
noTone();// pour arrêter le son de la dernière note

si vous ne mettez pas le delay, vous passez directement au son d’après en quelques micro-secondes et vous mangez vos 200 entrées super vite - quasiment rien le temps d’entendre - et le son que vous entendez en entier c’est en fait la dernière note

Comme tout le monde, je ne lis pas toujours la doc. Je cherche un truc tout fait et je fais du copier/coller. Le hasard faisant bien les choses, je suis tombé sur la version tone(pin, fréquence) avec laquelle les fonctions delay(durée) et noTone(pin) sont nécessaires (le bout de code qui marche entre /* et */ dans la fonction playIW() de mon premier poste).

Et puis j'ai eu la mauvaise idée d'aller lire la doc de la fonction tone(), et je vois que l'on peut faire tout d'un coup avec la version tone(pin, fréquence, durée). J'adopte cette nouvelle version, et comme j'ai l'impression d'être dans un bon jour, je décide de passer le tableau en paramètre de la fonction playIW pour pouvoir jouer n'importe quelle tableau de notes.

Mon haut-parleur ne fait plus que des beeps, ou alors, probablement quand je dépasse la fin du tableau, un bruit comme lorsque l'on roule sur un smartphone.

Convaincu que Kernighan et Ritchie aurait du être pendu par les gosses, je laisse tomber l'idée du tableau en paramètre. Mais je garde ma nouvelle version de tone().

BEEP! Ca ne marche pas non plus.

C'est là que je reviens à la version originale de ma fonction (entre /* et /) et que je demande ici pourquoi l'autre (entre //*************************) ne marche pas.

Dans la fonction tone(pin, fréquence, durée), "durée" ne sert à rien, sauf pour arrêter la note sans avoir a utiliser noTone(). tone() ne peu pas jouer une suite de notes toute seule.

Maintenant, je sais pourquoi une version de ma fonction marche et l'autre pas.

Mais j'aurais préféré une fonction tone() qui assure la durée de la note. Je croyais que la version tone(pin, fréquence, durée) servait à ça.

Il y a un concurrent français (cockadoodledoooo!) à youtube, mais malheureusement c'est lent comme l'administration:

https://www.peertube.fr/videos/watch/5284a8f5-f89d-4d37-a390-6ef03c7fa45b

kayel: Comme tout le monde, je ne lis pas toujours la doc.

Généralisation abusive... les bons programmeurs lisent la doc, voire le code source si nécessaire pour comprendre comment ça fonctionne.... ça évite bien des déboires...

kayel: Mais j'aurais préféré une fonction tone() qui assure la durée de la note. Je croyais que la version tone(pin, fréquence, durée) servait à ça.

mais la fonction [u]assure[/u] la durée de la note. Si vous ne donnez pas de contre-ordre, la note sera jouée pendant cette durée et s'arrêtera toute seule. Votre problème c'est que vous donnez un contre-ordre et demandez de jouer une autre note alors que celle là est toujours en cours.

Si vous voulez avoir votre propre fonction et qu'elle soit bloquante, vous pouvez l'écrire vous même...

void myTone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
  tone(_pin, frequency, duration);
  delay(duration);
}

et voilà vous n'avez plus qu'a appeler myTone() au lieu de tone()...