# Piezo Element & Photo-resistor Problems

I’m basically trying to make the piezo buzzer scream when there’s light and play music when it’s dark. To do so, I used a photoresistor which decreases in resistance with more light. I’m trying to make the code so that when there is light it screams once and when there is darkness it plays music once. I also want it to stop the music and quickly scream once there is light.
The problem with my code is that it screams over and over again and the music doesn’t stop. Below is my code; it would be great if someone gave me an advice to correct it. Thanks.

``````/*
* Arduino sends a square wave of the appropriate frequency to the piezo, generating
* the corresponding tone.
*
* The calculation of the tones is made following the mathematical
* operation:
*
* timeHigh = period / 2 = 1 / (2 * toneFrequency)
*
* where the different tones are described as in the table:
*
* note frequency period timeHigh
* c 261 Hz 3830 1915
* d 294 Hz 3400 1700
* e 329 Hz 3038 1519
* f 349 Hz 2864 1432
* g 392 Hz 2550 1275
* a 440 Hz 2272 1136
* b 493 Hz 2028 1014
*/

int speakerPin = 2;                                             // pin to use to drive speaker
char names[] = {'c','d','e','f','g','a','b'};                    // List of notes we want to be able to play
int rangeOfNotes = 8;
int tones[] ={1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
int length = 42;
char notes[] = "ccggaagffeeddcggffeedggffeedccggaagffeeddc ";

double beats[] = {1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4};
int tempo = 300;

int lightSensor = 5;     //Analog pin Light Resistor is connected to
int darknessThresh = 500;

void setup()
{
pinMode(speakerPin,OUTPUT);
Serial.begin(9600);
}

void Scream()
{
digitalWrite(speakerPin, HIGH);
delay(1500);
digitalWrite(speakerPin,LOW);
delay(1000);
}

void playNote(char note, int duration)                         //plays the note "note" for the time "duration"
{
//play the tone corresponding to the note name
for (int i = 0; i < rangeOfNotes; i++)
{
if (names[i] == note){
playTone(tones[i], duration);
}
}
}

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 Sing()
{

for (int i = 0; i < length; i++)
{
if (notes[i] == ' ')
{
delay(beats[i] * tempo);
}
else
{playNote(notes[i], beats[i] * tempo);}

delay(tempo/2);
}
}

void loop()
{
Serial.print("Light Level = ");
Serial.println(lightLevel);
if(lightLevel < (darknessThresh-20))
{
Scream();
}

if(lightLevel > darknessThresh)
{
Sing();
}
}
``````
``````  if(lightLevel < (darknessThresh-20))
{
Scream();
}

if(lightLevel > darknessThresh)
{
Sing();
}
``````

There’s your problem. You need to keep track of whether you have already sung or screamed. If you have already sung or screamed you don’t want to do it again.

``````  static boolian screamed = false;
if(!screamed && lightLevel < (darknessThresh-20))
{
// LIGHT!
Scream();
screamed = true;
}

if(screamed && lightLevel > darknessThresh)
{
// Dark has fallen
Sing();
screamed = false;
}
``````