2 actions simultanées

Bonjour,

J'ai imprimé en 3D un petit sapin de Noël sur lequel j'ai installé 10 LEDs qui clignotent. Jusqu'ici je m'en sors bien :slight_smile:
J'ai ensuite 3 boutons qui chacun après une pression joue une musique de Noël sur un buzzer. Le code fonctionne MAIS je bloque sur le fait qu'il ne met pas possible de faire l'action en boucle des LEDs et venir appuyer sur un bouton pour déclencher une musique sans stopper les LEDs.

J'ai fait de nombreuses recherche et j'ai bien compris qu'il n'est pas possible de créer 2 loops et qu'il est logique que les actions se fassent les unes derrière les autres. Je débute et je cherche à comprendre le fonctionnement de l'arduino.

Pourriez-vous s'il vous plait me dire si je persiste en vain pour trouver une solution ou s'il existe une autre méthode pour que 2 actions se lancent sans se gêner?

J'ai vu de nombreux post qui parlent de "mills" mais je n'en comprends pas trop le principe et je ne suis pas sûr que cela résolve mon problème.

Merci pour l'aide que vous pourrez m'apporter.

P.S.
Je n'ai pas mis les codes, ils ne sont pas de moi et je ne sais pas si je peux les poster.

Rodolphe

Oui avec la fonction millis, vous devriez vous en sortir. Disons que vous avez une boucle qui joue des notes, à l'intérieur en fin de boucle, vous rajouter un morceau de code avec millis non bloquant qui va déclencher une action tous les x secondes.

Pas le temps de tester, je vous donne le principe.

unsigned long time = 0; à déclarer en global

et dans la boucle for existante par exemple:

for (....){

// le code pour les notes

// vous ajouter ce morceau de code
unsigned long result = (millis() - time)
if (result>1000){
// votre procédure ici qui va allumer / éteindre les leds
time = millis()
}
}

C’est vrai que ce n’est pas forcément évident, mais c’est très simple si on comprend bien le principe. Il faudrait un tuto sur le sujet : @Mr_Tuto : si tu lis ces lignes… :wink:

Je vais tenter de t’expliquer le principe. Je te conseille d’essayer de le mettre en oeuvre petit à petit. Par exemple, tu commences par faire clignoter une guirlande, puis une seconde avec des timings différents, etc.

Tout est basé sur la fonction millis() : elle renvoie le nombre de millisecondes écoulées depuis que le microcontrôleur fonctionne. On s’en sert donc pour chronométrer (localiser dans le temps) des événements ou mesurer des durées.

Ainsi supposons que tu veuilles faire clignoter une guirlande avec une période de 1500ms. Il faut donc vérifier régulièrement le temps passé (en interrogeant millis()) et dès que 1500 ms se sont écoulées, on change l’état de la guirlande (allumé → éteint ou éteint → allumé).

Tu vois qu’il faut donc utiliser des variables :

  • l’état de la guirlande (utilise un booléen)
  • l’instant du dernier changement d’état
  • la période

Lors de l’allumage de la guirlande, tu passes l’état à “allumé” (ou true, ou 1) et tu stockes le contenu de millis() dans la variable de l’instant du dernier changement d’état.

La loop va vérifier que la durée d’allumage (la période) ne s’est pas écoulée : on compare millis() - l’instant du dernier changement d’état à la période. Si c’est supérieur, il suffit de changer l’état de la guirlande et de remettre le contenu de millis() dans la variable de l’instant du dernier changement d’état.
Ca s’écrit :

if (millis() - chrono > periode) {
  chrono = millis();
  ...
}

où chrono est la variable qui contient l’instant du dernier changement d’état.

Note que, pour des raisons liées au codage binaire, il vaut mieux utiliser un type unsigned long pour la variable chrono.
Enfin, si tu as plusieurs choses à commander ainsi (plusieurs guirlandes, des notes de musique) il faut un jeu de variables pour chacune.

Voici un code de test:

// Ce code de chanson de noël est d' Yves Pelletier et provient de son site Web:
// Le site Web d' Yves Pelletier est un recueil d'informations, je vous invite à le visiter
// http://electroniqueamateur.blogspot.com/2018/12/arduino-chante-noel.html


// Cet extrait de code de chanson de noël va permettre de mettre en place deux actions
// dépendantes du temps, un chant de noël avec un buzzer passif et des leds (simulation ici de la led par la led interne de la carte)

// fréquence associée à chaque note
// do, do#, ré, ré#, mi, fa, fa#, sol, sol#, la, la#, si
const float note[12] = {65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47
                       };

// chaque note de la mélodie comporte 3 paramètres:
// note (de 0 à 11:  0 pour do, 1 pour do#, etc)
// octave (1 à 3)
// durée (1 pour croche, 2 pour noire, 4 pour ronde)


#define sortie 8  // raccorder cette broche à la pin signal du buzzer passif et l'autre '-' à GND
                  // celle du milieu ne sert pas
                  
unsigned long time1 = 0; // à déclarer en global

byte etat = 1; // va servir à basculer de l'état1 à l'état 0

void setup() {
  pinMode (LED_BUILTIN, OUTPUT);
}

void loop() {
  petitPapa();
  delay(3000);
}

unsigned long leds(void) {
  unsigned long time2 = millis();
  // --------------------------------------
  // Votre de code de gestion des Leds
  digitalWrite(LED_BUILTIN, etat);
  etat = !etat;
  // --------------------------------------
  unsigned long tempsExecution = (millis() - time2);
  return tempsExecution;
}


void petitPapa(void) {
  // petit papa noël
  const int nombreDeNotes = 58;
  const int tempo = 250    ; // plus c'est petit, plus c'est rapide
  const int melodie[][3] = { {7, 2, 2}, {0, 3, 2}, {0, 3, 2}, {0, 3, 2}, {2, 3, 2}, {0, 3, 6},
    {0, 3, 1}, {2, 3, 1}, {4, 3, 2}, {4, 3, 2}, {4, 3, 2}, {5, 3, 2}, {4, 3, 6},
    {2, 3, 2}, {0, 3, 3}, {0, 3, 1}, {0, 3, 1}, {0, 3, 1}, {11, 2, 1}, {9, 2, 1}, {7, 2, 6},
    {7, 2, 1}, {7, 2, 1}, {0, 3, 4}, {0, 3, 1}, {0, 3, 1}, {11, 2, 1}, {0, 3, 1}, {2, 3, 6},
    {7, 2, 2}, {0, 3, 2}, {0, 3, 2}, {0, 3, 2}, {2, 3, 2}, {0, 3, 6},
    {0, 3, 1}, {2, 3, 1}, {4, 3, 2}, {4, 3, 2}, {4, 3, 2}, {5, 3, 2}, {4, 3, 6},
    {2, 3, 2}, {0, 3, 3}, {0, 3, 1}, {0, 3, 1}, {0, 3, 1}, {11, 2, 1}, {9, 2, 1}, {7, 2, 6},
    {7, 2, 1}, {7, 2, 1}, {0, 3, 4}, {0, 3, 1}, {0, 3, 1}, {2, 3, 1}, {2, 3, 1}, {0, 3, 6},
  };


  int frequence;

  for ( int i = 0; i < nombreDeNotes ; i++ ) {
    frequence = round(note[melodie[i][0]] * 2 * (melodie[i][1] - 1));

    tone(sortie, frequence);
    delay(tempo * melodie[i][2] - 50);
    noTone(sortie);

    // vous ajouter ce morceau de code
    unsigned long result = (millis() - time1);
    if (result > 1000) { // allumage des leds toutes les secondes
      // votre procédure ici qui va allumer / éteindre les leds
      unsigned long diff = leds(); // ici diff vaudra certainement 0 car le temps d'exécution de la procédure est très court dans cet exemple
      time1 = millis();
      if (diff < 50) {
        delay (50 - diff); // permet d'aligner le temps de pose en rapport avec l'exécution de notre procédure
      }
    } else {
      delay(50);
    }
  }
}

Merci à tous pour vos réponses autant précises que utiles!

Je me suis penché sur l'utilisation de la fonction "Millis" et comme l'indique LESEPT cela est simple si on en comprends le principe. Malheureusement pour moi je n'arrive pas à visualiser le déroulement des étapes de la fonction "Millis".

J'ai donc essayé (bêtement) d’appliquer le code test de NICO78 dans mon propre code mais je dois mal m'y prendre et cela m'apporte des erreurs de }
Je pense sincèrement que la solution est dans le code test de NICO78 puisqu'il ressemble à ce que je souhaite faire.

Pensez-vous que je puisse poster mon code afin que vous puissiez m'orienter vers la solution?

En tout cas un grand merci à vous pour l'aide que vous m'avez déjà apporté :slight_smile:

EDIT:
J'ai essayé le code de NICO78 mais du premier post, voilà ce qu'il se passe:
-Tout est éteint.
-J’appuie sur un des 3 boutons, il fait 3 notes de la musique puis lance la boucle des LEDS
-Une fois la boucle terminée il fait les 3 notes suivantes puis relance les LEDS
-Etc...

Bon, c'est une sorte de progrès dirons nous :))

Rodolphe

Pensez-vous que je puisse poster mon code afin que vous puissiez m'orienter vers la solution?

Je dirais oui, au moins pour savoir de quelles leds tu parles et comment tu les commandes.

Je t'ai conseillé d'apprendre pas à pas, de ne pas vouloir faire tout d'un seul coup.
Commence par faire clignoter une led.

Supposons que ta led est connectée sur le pin D5 (je te laisse faire le montage, au besoin ici). Voici un code pour la faire clignoter avec une période de 1492 ms. Pourquoi 1492 ? Je réponds "pourquoi pas ?"

#define LED5 5
#define PeriodeLed5 1492ul
unsigned long chronoLed5;
bool etatLED5 = LOW;

void setup () {
  pinMode (LED5, OUTPUT);
  digitalWrite (LED5, etatLED5);  // Led éteinte au début
  chronoLed5 = millis();  // Initialisation du chrono en début de programme
}

void loop() {
  if (millis()-chronoLed5 > PeriodeLed5) {  // Si le temps est passé
      chronoLed5 = millis(); 
      etatLED5 = !etatLED5;  // On inverse l'état de la led
      digitalWrite (LED5, etatLED5);
   }
}

Si tu testes ça, tu devrais voir ta led s'allumer et s'éteindre toutes les 1,492 secondes.
Si ça fonctionne, je t'encourage à ajouter une seconde led et dupliquer les variables pour la faire clignoter avec une période différente. Il suffit de faire un nouveau bloc if dans la loop qui gère la seconde led.
Si tu y arrives, c'est que tu as compris le principe. Tu peux maintenant ajouter la musique.
Pour ça, il faut voir chaque note comme un nouvel état de la musique : au lieu d'inverser une led à chaque fin de période, tu passes à la note suivante. Tu dois avoir, comme dans le code de Nico78 un tableau qui te donne la durée de chaque note : utilise le pour connaitre la "période" de chaque note : c'est la durée au bout de laquelle tu dois changer de note et passer à la suivante.

Effectivement j’ai réussi à faire clignoter une Led tout en faisant clignoter la seconde Led dans le temps de la première.
La 2ème Led a fait son action sans attendre que la première se termine.
Ok, je viens de comprendre le fonctionnement de Millis en le mettant en situation! TOP!

Je vais tenter d’y intégrer le code de NICO78 pour jouer petit papa Noël.
Cela risque d’être la partie la plus compliqué pour moi mais j’ai bon espoir!

Je me permet donc également de vous montrer le code que je souhaite faire fonctionner.
Il fonctionne mais vous l’aurez compris pas exactement comme je le souhaiterai c’est à dire de pouvoir lancer une des 3 musiques à n’importe quel moment sans stoppé le clignotement des Leds.

J’ai supprimé une partie du cycle des Leds pour pouvoir le poster (trop de caractère)

int p=100; // Temps clignotement des Leds
int p2=230; // Temps clignotement des Leds

#include "pitches.h"
#define melodyPin 2


// Jingle Bells

int melody[] = {
  NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5,
  NOTE_E5,
  NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5,
  NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_D5, NOTE_D5, NOTE_E5,
  NOTE_D5, NOTE_G5
};

int tempo[] = {
  8, 8, 4,
  8, 8, 4,
  8, 8, 8, 8,
  2,
  8, 8, 8, 8,
  8, 8, 8, 16, 16,
  8, 8, 8, 8,
  4, 4
};

// We wish you a merry Christmas

int wish_melody[] = {
  NOTE_B3, 
  NOTE_F4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4,
  NOTE_D4, NOTE_D4, NOTE_D4,
  NOTE_G4, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4,
  NOTE_E4, NOTE_E4, NOTE_E4,
  NOTE_A4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4,
  NOTE_F4, NOTE_D4, NOTE_B3, NOTE_B3,
  NOTE_D4, NOTE_G4, NOTE_E4,
  NOTE_F4
};

int wish_tempo[] = {
  4,
  4, 8, 8, 8, 8,
  4, 4, 4,
  4, 8, 8, 8, 8,
  4, 4, 4,
  4, 8, 8, 8, 8,
  4, 4, 8, 8,
  4, 4, 4,
  2
};

// Santa Claus is coming to town

int santa_melody[] = {
  NOTE_G4,
  NOTE_E4, NOTE_F4, NOTE_G4, NOTE_G4, NOTE_G4,
  NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, NOTE_C5,
  NOTE_E4, NOTE_F4, NOTE_G4, NOTE_G4, NOTE_G4,
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4,
  NOTE_E4, NOTE_G4, NOTE_C4, NOTE_E4,
  NOTE_D4, NOTE_F4, NOTE_B3,
  NOTE_C4
};

int santa_tempo[] = {
  8,
  8, 8, 4, 4, 4,
  8, 8, 4, 4, 4,
  8, 8, 4, 4, 4,
  8, 8, 4, 2,
  4, 4, 4, 4,
  4, 2, 4,
  1
};

int switchOne = 0; // Bouton 1
int switchTwo = 0; // Bouton 2
int switchThree = 0; // Bouton 3



void setup() {
  

 pinMode(13,OUTPUT);//LED
 pinMode(12,OUTPUT);//LED
 pinMode(11,OUTPUT);//LED
 pinMode(10,OUTPUT);//LED
 pinMode(9,OUTPUT); //LED
 pinMode(8,OUTPUT); //LED
 pinMode(7,OUTPUT); //LED
 pinMode(6,OUTPUT); //LED
 pinMode(5,OUTPUT); //LED
 pinMode(4,OUTPUT); //LED
 pinMode(3,OUTPUT);
 pinMode(2, OUTPUT); // Buzzer
 pinMode(A1, INPUT); //bouton1
 pinMode(A2, INPUT); //bouton2
 pinMode(A3, INPUT); //bouton3
}

void loop() 

{


// Début code pour les boutons et les musiques
switchOne = digitalRead(A1);
  switchTwo = digitalRead(A2);
  switchThree = digitalRead(A3);
  if (switchOne == HIGH) {
    sing(1);
  } else if (switchTwo == HIGH) {
    sing(2);
  } else if (switchThree == HIGH) {
    sing(3);
  }
}

int song = 0;

void sing(int s) {
  // iterate over the notes of the melody:
  song = s;
  if (song == 3) {
    Serial.println(" 'We wish you a Merry Christmas'");
    int size = sizeof(wish_melody) / sizeof(int);
    for (int thisNote = 0; thisNote < size; thisNote++) {

      // to calculate the note duration, take one second
      // divided by the note type.
      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 1000 / wish_tempo[thisNote];

      buzz(melodyPin, wish_melody[thisNote], noteDuration);

      // to distinguish the notes, set a minimum time between them.
      // the note's duration + 30% seems to work well:
      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);

      // stop the tone playing:
      buzz(melodyPin, 0, noteDuration);

    }
  } else if (song == 2) {
    Serial.println(" 'Santa Claus is coming to town'");
    int size = sizeof(santa_melody) / sizeof(int);
    for (int thisNote = 0; thisNote < size; thisNote++) {

      // to calculate the note duration, take one second
      // divided by the note type.
      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 900 / santa_tempo[thisNote];

      buzz(melodyPin, santa_melody[thisNote], noteDuration);

      // to distinguish the notes, set a minimum time between them.
      // the note's duration + 30% seems to work well:
      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);

      // stop the tone playing:
      buzz(melodyPin, 0, noteDuration);

    }
  } else {

    Serial.println(" 'Jingle Bells'");
    int size = sizeof(melody) / sizeof(int);
    for (int thisNote = 0; thisNote < size; thisNote++) {

      // to calculate the note duration, take one second
      // divided by the note type.
      //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 1000 / tempo[thisNote];

      buzz(melodyPin, melody[thisNote], noteDuration);

      // to distinguish the notes, set a minimum time between them.
      // the note's duration + 30% seems to work well:
      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);

      // stop the tone playing:
      buzz(melodyPin, 0, noteDuration);

    }
  }
}

void buzz(int targetPin, long frequency, long length) {

  long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
  //// there are two phases to each cycle
  long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to
  //// get the total number of cycles to produce
  for (long i = 0; i < numCycles; i++) { // for the calculated length of time...
    digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait again or the calculated delay value
  }

//Fin code musiques et boutons

//Début code des Leds


   digitalWrite(13, LOW); 
   digitalWrite(12, LOW); 
   digitalWrite(11, LOW);
   digitalWrite(10, LOW);
   digitalWrite(9, LOW);
   digitalWrite(8,HIGH);
   digitalWrite(7,LOW);
   digitalWrite(6,LOW);
   digitalWrite(5,LOW);
   digitalWrite(4,LOW);
   digitalWrite(3,LOW);
   
   delay(p);
   
   digitalWrite(13, LOW); 
   digitalWrite(12, LOW); 
   digitalWrite(11, LOW);
   digitalWrite(10, LOW);
   digitalWrite(9, HIGH);
   digitalWrite(8,LOW);
   digitalWrite(7,HIGH);
   digitalWrite(6,LOW);
   digitalWrite(5,LOW);
   digitalWrite(4,LOW);
   digitalWrite(3,LOW);
   
   delay(p);
   
   digitalWrite(13, LOW); 
   digitalWrite(12, LOW); 
   digitalWrite(11, LOW);
   digitalWrite(10, HIGH);
   digitalWrite(9, LOW);
   digitalWrite(8,LOW);
   digitalWrite(7,LOW);
   digitalWrite(6,HIGH);
   digitalWrite(5,LOW);
   digitalWrite(4,LOW);
   digitalWrite(3,LOW);
   
   delay(p);
   
   digitalWrite(13, LOW); 
   digitalWrite(12, LOW); 
   digitalWrite(11, HIGH);
   digitalWrite(10, LOW);
   digitalWrite(9, LOW);
   digitalWrite(8,LOW);
   digitalWrite(7,LOW);
   digitalWrite(6,LOW);
   digitalWrite(5,HIGH);
   digitalWrite(4,LOW);
   digitalWrite(3,LOW);
   
   delay(0);
   
   
}
//Fin code Leds

lesept:
C'est vrai que ce n'est pas forcément évident, mais c'est très simple si on comprend bien le principe. Il faudrait un tuto sur le sujet : @Mr_Tuto : si tu lis ces lignes... :wink:

Je ne sais pas pourquoi mais j'ai l'impression que c'était pour moi :slight_smile:

Le tuto existe déjà plus ou moins: Deux machines à état en parallèle, une pour jouer les notes et une pour le clignotement (si elles sont indépendantes - sinon une seule comprenant le buzzer et les LEDs si elles sont dépendantes) et en s’inspirant du code de blink without delay qui doit avoir quelques centaines d’explications déjà sur internet

Il y a un bon tuto d’eskimon aussi sur “introduire le temps"

J-M-L:
Je ne sais pas pourquoi mais j'ai l'impression que c'était pour moi :slight_smile:

Re à tous,

Alors j'ai tenté le clignotement des Leds avec un buzzer en appliquant les explications de Lesept.
Les Leds fonctionnent mais le buzzer ne fait qu'une tonalité et ne prends pas en compte la seconde.

J'ai loupé un truc, pouvez-vous m'aider?

#define LED5 5
#define LED4 4
#define Buzzer 8
#define PeriodeLed4 100ul
#define PeriodeLed5 1000ul
#define BuzzerA  1000ul
#define BuzzerB  1800ul

unsigned long chronoLed5;
unsigned long chronoLed4;
unsigned long buzzer1;

bool etatLED4 = LOW;
bool etatLED5 = HIGH;
bool etatBUZZER = LOW;

void setup () {

  pinMode (LED5, OUTPUT);
  pinMode (LED4, OUTPUT);
  pinMode(Buzzer,OUTPUT);

  digitalWrite (LED4, etatLED4);  // Led éteinte au début
  digitalWrite (LED5, etatLED5);  // Led allumée au début
  digitalWrite (Buzzer, !etatBUZZER);  // Buzzer allumée au début

  chronoLed5 = millis();  // Initialisation du chrono en début de programme
  chronoLed4 = millis();  // Initialisation du chrono en début de programme
  buzzer1 = millis();  // Initialisation du chrono en début de programme
}

void loop() {
  if (millis()-chronoLed5 > PeriodeLed5) {  // Si le temps est passé
      chronoLed5 = millis();
      etatLED5 = !etatLED5;  // On inverse l'état de la led
      digitalWrite (LED5, etatLED5);
      
   }

     if (millis()-chronoLed4 > PeriodeLed4) {  // Si le temps est passé
      chronoLed4 = millis();
      etatLED4 = !etatLED4;  // On inverse l'état de la led
      digitalWrite (LED4, etatLED4);
    } 

     if (millis()-buzzer1 > BuzzerA) {  // Si le temps est passé
      buzzer1 = millis();
      etatBUZZER = !etatBUZZER;  // On inverse l'état du buzzer      
      tone(Buzzer, 100); 
     }

     if (millis()-buzzer1 > BuzzerB) {  // Si le temps est passé
      buzzer1 = millis();
      etatBUZZER = !etatBUZZER;  // On inverse l'état du buzzer
      tone(Buzzer, 500); 
   }
}
etatBUZZER = !etatBUZZER;  // On inverse l'état du buzzer

ça ne sert à rien.
Ce que tu veux faire ici c'est "allumer" le buzzer pendant une durée, puis passer à une autre note.
Tu peux ajouter un petit temps sans musique avant de passer à la suivante.

Disons que la durée de la note est dans la variable duree. La durée entre deux notes est dans la variable intervalle. Il faut ajouter une variable pour indiquer qu'on joue ou qu'on ne joue pas (un booléen).

En global :

bool etatNote = true;
int frequence = 500;

Puis dans la loop :

  if (etatNote) {
     if (millis()-buzzer1 > duree) {  // Si le temps est passé
      buzzer1 = millis();
      etatNote = !etatNote;  // On inverse l'état du buzzer
      noTone(); // on arrête la note
     }
   } else {
     if (millis()-buzzer1 > intervalle) { 
      buzzer1 = millis();
      etatNote = !etatNote;  // On inverse l'état du buzzer
      tone(Buzzer, frequence); // on lance la note
        }
  }

A tester : ça devrait faire bip pendant "duree" millisecondes, puis rien pendant "intervalle" millisecondes, etc.
Si tu veux faire une musique, avec plusieurs notes et plusieurs durées, il faut les mettre dans des tableaux et lire ces valeurs une par une (avec une variable "i" qui indique à quelle note tu es), et les affecter à "duree" et 'frequence"

Bonsoir,

Je travail toujours sur mon projet et m’appuyant sur vos aides!
Donc, me voilà maintenant avec 2 Leds qui clignotent chacune avec millis OK
J’ai ajouté des tonalités pour le buzzer en venant chercher les notes avec une variable “i” comme expliqué par Lesept.

Cela pourrait-être bien si mon buzzer ne faisait pas seulement une seule note toute les x millisecondes indiqué par ma variable tempo :confused:

Je n’arrive pas à faire lire les notes une par une.

#define LED5 5
#define LED4 4
#define Buzzer 8
#define PeriodeLed4 100ul
#define PeriodeLed5 1000ul

unsigned long chronoLed5;
unsigned long chronoLed4;
unsigned long chronoMelodie;

bool etatLED4 = LOW;
bool etatLED5 = HIGH;

int tempo = 150; // Temps entre chaque note
int numTones = 10; //Nombre de tonalités
int tones[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440}; //Les tonalités


void setup () {

  pinMode (LED5, OUTPUT);
  pinMode (LED4, OUTPUT);


  digitalWrite (LED4, etatLED4);  // Led éteinte au début
  digitalWrite (LED5, etatLED5);  // Led allumée au début


  chronoLed5 = millis();  // Initialisation du chrono en début de programme
  chronoLed4 = millis();  // Initialisation du chrono en début de programme
  chronoMelodie = millis(); // Initialisation du chrono en début de programme
}


void loop() {

  if (millis()-chronoLed5 > PeriodeLed5) {  // Si le temps est passé
      chronoLed5 = millis();
      etatLED5 = !etatLED5;  // On inverse l'état de la led
      digitalWrite (LED5, etatLED5);
      
   }

     if (millis()-chronoLed4 > PeriodeLed4) {  // Si le temps est passé
      chronoLed4 = millis();
      etatLED4 = !etatLED4;  // On inverse l'état de la led
      digitalWrite (LED4, etatLED4);
    } 

    if (millis()-chronoMelodie > tempo) {  // Si le temps est passé
      chronoMelodie = millis();
   for (int i = 0; i < numTones; i++)
   {
      tone(Buzzer, tones[i]);
   }
      noTone(Buzzer);
 } 
 }

Si vous voulez que ça beep en permanence il ne faut pas de noTone(Buzzer);

Si vous utilisez la version tone(pin, frequency, duration) vous pouvez donner une durée du buzz

viseo:
Bonjour,

J'ai imprimé en 3D un petit sapin de Noël sur lequel j'ai installé 10 LEDs qui clignotent. Jusqu'ici je m'en sors bien :slight_smile:
J'ai ensuite 3 boutons qui chacun après une pression joue une musique de Noël sur un buzzer. Le code fonctionne MAIS je bloque sur le fait qu'il ne met pas possible de faire l'action en boucle des LEDs et venir appuyer sur un bouton pour déclencher une musique sans stopper les LEDs.

J'ai fait de nombreuses recherche et j'ai bien compris qu'il n'est pas possible de créer 2 loops et qu'il est logique que les actions se fassent les unes derrière les autres. Je débute et je cherche à comprendre le fonctionnement de l'arduino.

Pourriez-vous s'il vous plait me dire si je persiste en vain pour trouver une solution ou s'il existe une autre méthode pour que 2 actions se lancent sans se gêner?

J'ai vu de nombreux post qui parlent de "mills" mais je n'en comprends pas trop le principe et je ne suis pas sûr que cela résolve mon problème.

Merci pour l'aide que vous pourrez m'apporter.

P.S.
Je n'ai pas mis les codes, ils ne sont pas de moi et je ne sais pas si je peux les poster.

Rodolphe

Bonsoir,
Vous dites qu'il n'est pas possible de lancer deux boucles en même temps. En C peut-être...
Personnellement, je programme en langage FORTH et le langage FORTH est multi-tâche. J'ai fait une vidéo qui montre deux boucles déclenchées et gérées en multi-tâche sur ARDUINO NANO...

Cordialement

Comme il n’y a qu’un processeur ce n’est pas du vrai multitâche - c’est juste du partage de temps (le processeur ne fait pas deux choses en même temps mais rapidement un va-et-vient entre différentes actions) - dans le cas de Forth c’est un enchaînement circulaire, asynchrone et coopératif des tâches

Ça se fait sans problème avec la bonne approche sur l’architecture du code en utilisant le temps (millis) en C ou C++.

Certains langages ou bibliothèques permettent une abstraction et génèrent du code qui fait cela pour vous

Je te propose cette mise à jour. Je n'ai pas testé, n'ayant pas de buzzer sous la main.

#define LED5 5
#define LED4 4
#define Buzzer 8
#define PeriodeLed4 100ul
#define PeriodeLed5 1000ul

unsigned long chronoLed5;
unsigned long chronoLed4;
unsigned long chronoMelodie;

bool etatLED4 = LOW;
bool etatLED5 = HIGH;
bool etatNote = false;

int numNote = 0; // numéro de la note à jouer
int tempo = 150; // Temps entre chaque note
int numTones = 10; //Nombre de tonalités
int tones[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440}; //Les tonalités
int toneduration[] = {500, 500, 500, 500, 300, 300, 300, 300, 500, 300};
int notes = sizeof(tones) / sizeof(int);

void setup () {

  pinMode (LED5, OUTPUT);
  pinMode (LED4, OUTPUT);
  pinMode (Buzzer, OUTPUT);
  digitalWrite (LED4, etatLED4);  // Led éteinte au début
  digitalWrite (LED5, etatLED5);  // Led allumée au début

  chronoLed5    = millis();  // Initialisation du chrono en début de programme
  chronoLed4    = millis();  // Initialisation du chrono en début de programme
  chronoMelodie = millis(); // Initialisation du chrono en début de programme
}

void loop() {
  if (millis()-chronoLed5 > PeriodeLed5) {  // Si le temps est passé
    chronoLed5 = millis();
    etatLED5 = !etatLED5;  // On inverse l'état de la led
    digitalWrite (LED5, etatLED5);
   }

  if (millis()-chronoLed4 > PeriodeLed4) {  // Si le temps est passé
    chronoLed4 = millis();
    etatLED4 = !etatLED4;  // On inverse l'état de la led
    digitalWrite (LED4, etatLED4);
  }

  if (etatNote) { // On joue une note
   if (millis()-chronoMelodie > toneduration[numNote]) {  // Si le temps est passé
    chronoMelodie = millis();
    etatNote = !etatNote;  // On inverse l'état du buzzer
    noTone(); // on arrête la note
    }
  } else { // On lance une note si la temporisation entre notes est terminée
    if (millis()-chronoMelodie > tempo) {
      chronoMelodie = millis();
      etatNote = !etatNote;  // On inverse l'état du buzzer
      tone(Buzzer, frequence); // on lance la note
      numNote = (numNote + 1) % notes;
    } 
  }
}

Je ne sais pas si cette ligne est correcte :

int notes = sizeof(tones) / sizeof(int);

Si elle ne compile pas, remplace la par

int notes = 10;

lesept:
Je ne sais pas si cette ligne est correcte :

int notes = sizeof(tones) / sizeof(int);

oui ca va marcher puisque vous mettez des int dans le tableau tones

Pour ne jamais se poser de questions comme cela vous pouvez diviser le nombre d’octets du tableau par le nombre d’octets du premier élément du tableau et ça marche à tous les coups pour trouver le nombre d’éléments dans le tableau (et ça retourne un entier non signé de type size_t)

size_t notes = sizeof(tones) / sizeof(tones[0]);

En passant - sizeof étant un opérateur unaire (comme ! Par exemple) et pas une fonction on n’a pas vraiment besoin des parenthèses, on peut écrire (pour frimer un peu et briller lors de votre prochaine revue de code :wink: )size_t notes = sizeof tones / sizeof tones[0];

Merci c'est ce que je cherchais... :wink: