Programme photoresistance + buzzer + musique

Bonjour,

Je suis toute débutante sur arduino mais j’ai de grande ambition (ou pas :smiley: ).

Je souhaiterais pour les portes ouvertes de mon lycée créer un coffre du jeu Zelda qui jouerait le petit jingle adéquat en s’ouvrant.

Pour cela je voudrais que la musique ce déclenche grâce à une photorésistance donc en ouvrant le coffre avec la lumière ça déclencherais la musique sur le buzzer.

J’ai donc déjà trouvé le programme pour la musique qui fonctionne bien. Même si la qualité de mon buzzer laisse à un peu désirer niveau qualité du son, ça fera l’affaire.

/* This code is derived from:
 * http://www.arduino.cc/en/Tutorial/Melody
 * This plays the chest noise from the Legend of Zelda on a piezo buzzer connected to pin 9 and ground. It has been tuned to a buzzer I had on hand, but you may want to adjust the values, testing against a tuner.
 */
  
int speakerPin = 0;
const int switchPin = 1;


char notes[] = "gabygabyxzCDxzCDabywabywzCDEzCDEbywFCDEqywFGDEqi        azbC"; // a space represents a rest
int length = sizeof(notes); // the number of notes
int beats[] = { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 2,3,3,16,};
int tempo = 75;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'x', 'a', 'z', 'b', 'C', 'y', 'D', 'w', 'E', 'F', 'q', 'G', 'i' };
  // c=C4, C = C5. These values have been tuned.
  int tones[] = { 1898, 1690, 1500, 1420, 1265, 1194, 1126, 1063, 1001, 947, 893, 843, 795, 749, 710, 668, 630, 594 };
   
  // play the tone corresponding to the note name
  for (int i = 0; i < 18; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

void setup() {
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH);
}

void loop() {
  pinMode(speakerPin, OUTPUT);
  if (digitalRead(switchPin) == 1) {
    for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
      delay(beats[i] * tempo); // rest
    } else {
      playNote(notes[i], beats[i] * tempo);
    }
    
    // pause between notes
    delay(tempo / 2); 
  }
  }
  delay(100);
}

J’ai également un programme qui permet de déclencher le buzzer si la résistance est inférieur ou supérieur à une certaine valeur.

int photoresistance = analogRead(0);
int buzzer = 5;
int buzzer = music;

void setup() 
{

pinMode(buzzer,OUTPUT);
Serial.begin(115200);

}

void loop() 
{
photoresistance = analogRead(0);
Serial.print("Photoresistance = ");
Serial.println(photoresistance);
delay(100);

if(photoresistance>100)
{
  digitalWrite(buzzer,HIGH);
  delay(1000);

}
else
{
  digitalWrite(buzzer,LOW);
 delay(100);
  
}

}

Le problème est donc de relier les deux pour déclencher la musique et non juste un horrible son strident.

Si quelqu’un pouvait me donner quelques indications sur la marche à suivre. :smiley_cat:

La fonction tone() te permettrait de jouer un son directement en donnant la fréquence. noTone() pour stopper.

Dans ton programme actuel, tu déclenches la musique avec cette condition:if (digitalRead(switchPin) == 1) {. Ce n'est pas très difficile d'y substituer la condition utilisée dans le second programme pour activer le buzzer.

Bonjour,

Merci pour vos réponses et encore désolé pour les multiples ouvertures de sujet. J’ai demandé à les faire supprimer.

J’ai réussi à faire ceci et ça fonctionne mais la musique se joue en continue du coup tant que la boîte est ouverte et en plus si je ferme pendant que ça joue la musique celle-ci se s’arrête que quand elle est terminé forcément.

int photoresistance = analogRead(0);

int speakerPin = 5;
const int switchPin = 1;

char notes[] = "gabygabyxzCDxzCDabywabywzCDEzCDEbywFCDEqywFGDEqi        azbC"; // a space represents a rest
int length = sizeof(notes); // the number of notes
int beats[] = { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 2,3,3,16,};
int tempo = 75;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'x', 'a', 'z', 'b', 'C', 'y', 'D', 'w', 'E', 'F', 'q', 'G', 'i' };
  // c=C4, C = C5. These values have been tuned.
  int tones[] = { 1898, 1690, 1500, 1420, 1265, 1194, 1126, 1063, 1001, 947, 893, 843, 795, 749, 710, 668, 630, 594 };
   
  // play the tone corresponding to the note name
  for (int i = 0; i < 18; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}


void setup() 
{

Serial.begin(9600);  

pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH);

}

void loop() 
{

photoresistance = analogRead(0);
Serial.print("Photoresistance = ");
Serial.println(photoresistance);

if (photoresistance>100)
{
  
pinMode(speakerPin, OUTPUT);
  if (digitalRead(switchPin) == 5);
  
  {
    for (int i = 0; i < length; i++) 
    
    {
    if (notes[i] == ' ') 
    {
      delay(beats[i] * tempo); // rest
    } 
    else 
    {
      playNote(notes[i], beats[i] * tempo);
    }
    
    // pause between notes
    delay(tempo / 2);
    }
   
}


}
else 
{
  pinMode(speakerPin, LOW);
}

}

Du coup maintenant j’aimerais que la musique ne se joue qu’une fois tant que la boîte est ouverte et si je ferme et ouvre de nouveau que ça se relance.

J’ai essayé la fonction while(1) mais là du coup ça joue la musique une seule fois mais ça ne se relance plus.

Bonjour,

Le plus simple est de tester la photorésistance entre chaque note et d’arrêter si on est dans le noir

void loop()
{
  photoresistance = analogRead(0);
  Serial.print("Photoresistance = ");
  Serial.println(photoresistance);

  if (photoresistance > 100)
  {
    pinMode(speakerPin, OUTPUT);
    if (digitalRead(switchPin) == 5);
    {
      for (int i = 0; i < length; i++)
      {
        if (notes[i] == ' ')
        {
          delay(beats[i] * tempo); // rest
        }
        else
        {
          playNote(notes[i], beats[i] * tempo);
        }
        // pause between notes
        delay(tempo / 2);
        if (analogRead(0) < 100)
          break;   // sort de la boucle
      }
    }
  }
  else
  {
    pinMode(speakerPin, LOW);
  }
}

Je n’ai pas compris ce que vient faire le switch dans le programme. La photorésistance ne suffit pas?
En plus sur la ligne

    if (digitalRead(switchPin) == 5);

il y a deux erreurs qui font que heureusement la ligne ne fait rien.

Merci beaucoup kamill, c'est super comme ça par contre si je laisse la boîte ouverte une fois que la musique est terminée j'ai un son continue qui sort du buzzer et qui ne s'arrête plus même dans le noir.

En ce qui concerne le switch je ne sais pas, j'ai trouvé le programme de la musique tel quel et j'ai juste voulu y ajouter la photorésistance donc j'avoue ne pas avoir tout compris dans le programme.

Bonjour,

J’ai modifié mon programme comme ceci :

void loop()
{
  photoresistance = analogRead(0);
  Serial.print("Photoresistance = ");
  Serial.println(photoresistance);

  if (photoresistance > 200)
  {
    pinMode(speakerPin, OUTPUT);
      {
      for (int i = 0; i < length; i++)
      {
        if (notes[i] == ' ')
        {
          delay(beats[i] * tempo); // rest
        }
        else
        {
          playNote(notes[i], beats[i] * tempo);
        }
        // pause between notes
        delay(tempo / 2);
      
        if (analogRead(0) < 200)
        pinMode (speakerPin, LOW);
                 
      }
    }
  }
}

Ça fonctionne plus ou moins enfin ça s’arrête bien dès que c’est dans le noir mais il y a un délais quand j’ouvre de nouveau, la musique ne repart pas aussitôt.

Et toujours ce problème que si je laisse ouvert la boîte j’ai la musique qui tourne en boucle.

J’ai essayé plusieurs chose mais je n’arrive pas à avoir la musique une seule fois quand j’ouvre et que ça s’arrête si je ferme pendant la musique (je ne sais pas si je suis claire).

Ca ne repart pas immédiatement car tu n’arrêtes pas la boucle, tu coupes simplement le son et ça ne peut pas repartir avant la fin de la mélodie. Utilises break comme je te l’ai indiqué.

Le fait que tu entendes un son qui ne s’arrête pas vient du fait que la table beats est plus courte d’un élément que la table notes. Donc ça peut jouer une note de n’importe quelle longueur à la fin (y compris très long). Supprimes une note de notes ou ajoutes un élément dans beats.

Pour jouer la mélodie une seule fois utilise un compteur qui te dis combien de fois tu as joué la mélodie et qui se remet à zéro quand on ferme la boite (tu pourrais aussi utiliser un booléen, mais avec un compteur tu peux jouer la mélodie le nombre de fois que tu veux).

void loop()
{
  static byte compteur = 0;

  photoresistance = analogRead(0);
  Serial.print("Photoresistance = ");
  Serial.println(photoresistance);

  if (photoresistance > 200)
  {
    if (compteur < 1)
    {
      compteur++;
      pinMode(speakerPin, OUTPUT);
      {
        for (int i = 0; i < length; i++)
        {
          if (notes[i] == ' ')
          {
            delay(beats[i] * tempo); // rest
          }
          else
          {
            playNote(notes[i], beats[i] * tempo);
          }
          // pause between notes
          delay(tempo / 2);

          if (analogRead(0) < 200)
            break;
        }
      }
    }
  }
  else
  {
    compteur = 0;
  }
}