can't make buzzer buzz only once

Hi,
I have a buzzer that is set to buzz when it is between certain temperatures. I would like it to only buzz once when it is between these two temperatures, but my code currently instructs it to keep buzzing until it is no longer between the temperatures.

float temp; 
int buzzerPin = 8;

void setup() 
{
pinMode(buzzerPin,OUTPUT);//Initialise the buzzerPin as an output 
pinMode(A0,INPUT);
Serial.begin (9600) ;  // put your setup code here, to run once:

}

void loop() 
{
 temp = analogRead (A0) ; //read the value from the sensor
 temp = temp * 0.048828125 ; 
 Serial.print ( "TEMPERATURE: ") ; //prints temperature in serial monitor 
 Serial.print (temp) ;
 Serial.print ("*C") ;
 Serial.println () ;
 delay (1000) ;     // put your main code here, to run repeatedly:

if (temp >=24.0 && temp<= 25.0) { 
  digitalWrite(buzzerPin, HIGH);
  tone(buzzerPin, 1500, 1000); delay(150);
 }
else 
{
  digitalWrite (buzzerPin, LOW);
}

}

Would anyone know how to make it only buzz once?
Any help would be appreciated!!
thankyou, Tegan :smiley:

. . .
bool buzzerFlag = true;

void setup()
{
. . .
}

void loop()
{
. . .
if (buzzerFlag == true && temp >=24.0 && temp<= 25.0) { 
  buzzerFlag = false;
  tone(buzzerPin, 1500, 1000); delay(150);
 }
. . .
}

thankyou!! that works perfectly :slight_smile: :slight_smile:

If i were to continue these intervals, for example between 25 to 25 degrees the buzzer was to buzz twice, how would i do this?

“for example between 25 to 25 degrees”

Whaaaaat ?

i would like the buzzer to buzz twice when the sensor reads a temperature of 26 degrees? :slight_smile:

. . .
bool buzzerFlag = true;
byte buzzerCounter = 0;

void setup()
{
. . .
}

void loop()
{
. . .
if (buzzerFlag == true && temp >= 26) 
 { 
  buzzerFlag = false;
 }

if(buzzerFlag == false && buzzerCounter < 2)
{
  buzzerCounter = buzzerCounter + 1;
  tone(buzzerPin, 1500, 250); 
  delay(750);
}

. . .
}

Hi, i've tried using your code in a way that my buzzer buzzes once, twice then three times at different temperatures, but it does not work instead it buzzes once at 24 degrees.
Any suggestions?

float temp; 
int buzzerPin = 8;
bool buzzerFlag= true;
byte buzzerCounter =0;

void setup() 
{
pinMode(buzzerPin,OUTPUT);//Initialise the buzzerPin as an output 
pinMode(A0,INPUT);
Serial.begin (9600) ;  // put your setup code here, to run once:

}

void loop() 
{
 temp = analogRead (A0) ; //read the value from the sensor
 temp = temp * 0.048828125 ; 
 Serial.print ( "TEMPERATURE: ") ; //prints temperature in serial monitor 
 Serial.print (temp) ;
 Serial.print ("*C") ;
 Serial.println () ;
 delay (1000) ;     // put your main code here, to run repeatedly:

if (buzzerFlag == true && temp >=24.0 && temp<= 25.0) { 
  buzzerFlag = false;
  }

if (buzzerFlag == false && buzzerCounter < 1)
{
  buzzerCounter = buzzerCounter + 0;
  tone(buzzerPin, 1500, 1000); 
  delay(150);
 }
else 
{
  digitalWrite (buzzerPin, LOW);
}
if (buzzerFlag == true && temp >=26.0 && temp<= 27.0) { 
  buzzerFlag = false;
  }

if (buzzerFlag == false && buzzerCounter < 2)
{
  buzzerCounter = buzzerCounter + 1;
  tone(buzzerPin, 1500, 1000); 
  delay(150);
 }
else 
{
  digitalWrite (buzzerPin, LOW);
}
if (buzzerFlag == true && temp >=28.0 && temp<= 29.0) { 
  buzzerFlag = false;
  }

if (buzzerFlag == false && buzzerCounter < 3)
{
  buzzerCounter = buzzerCounter + 2;
  tone(buzzerPin, 1500, 1000); 
  delay(150);
 }
else 
{
  digitalWrite (buzzerPin, LOW);
}

}

Thankyou, tegan :slight_smile:

You never said you wanted to incorporate a whole bunch of different levels with buzzers :wink:

sorry!!
yes that is my aim, any advice on how this would be done?

What happens if the temperature goes to 24.5 then to 23 then back to 24.5?

What happens if the temperature goes to 24.5 then to 26 then back to 24.5?

If the code was to go from 24.5, i would like it to buzz once, then stop at 23 then buzz once again at 24.5. So i would like it to buzz once when anytime it is between the temperature of 24-25 degrees.

and if the code was to go from 24.5, i would like it to buzz once, then buzz twice when it reaches 26 then buzz once again at 24.5. So i would like it to buzz twice when anytime it is between the temperature of 26-27 degrees.

A real-world example would be a car reversing camera/alarm.

Thanks, Tegan :slight_smile:

Try this:

float temp;
int buzzerPin      = 8;

bool lockFlag      = false;
bool lockFlag2425  = false;
bool lockFlag2627  = false;
bool lockFlag2829  = false;

byte buzzerCounter = 0;
int  duration      = 500;

//machine state
byte mState = 0;

unsigned long buzzerMillis;
unsigned long printMillis;

//***************************************************************************************
void setup()
{
  pinMode(buzzerPin, OUTPUT); //Initialise the buzzerPin as an output
  pinMode(A0, INPUT);
  Serial.begin (9600) ;  // put your setup code here, to run once:

} //END of setup()

//***************************************************************************************
void loop()
{
  //***********************************
  if (millis() - printMillis >= 1000)
  {
    printMillis = millis();

    temp = analogRead (A0); //read the value from the sensor
    temp = temp * 0.048828125;

    if (temp < 24 || temp > 29)
    {
      //allow all range checking 
      lockFlag2425  = false;
      lockFlag2627  = false;
      lockFlag2829  = false;
    }

    Serial.print( "TEMPERATURE: "); //prints temperature in serial monitor
    Serial.print(temp);
    Serial.print("*C");
    Serial.println();
    
  }

  //***********************************
  if (lockFlag == false && lockFlag2425 == false && temp >= 24.0 && temp <= 25.0)
  {
    mState = 1;
    //set disable flags
    lockFlag = true;
    //we only want to beep once per range entry point
    lockFlag2425  = true;
    lockFlag2627  = false;
    lockFlag2829  = false;

    tone(buzzerPin, 1500, duration);
    buzzerMillis = millis();
    
  }

  //***********************************
  else if (lockFlag == false && lockFlag2627 == false && temp >= 26.0 && temp <= 27.0)
  {
    mState = 2;
    //set disable flags
    lockFlag = true;
    lockFlag2425  = false;
    //we only want to beep once per range entry point
    lockFlag2627  = true;
    lockFlag2829  = false;

    buzzerCounter = 0;
    tone(buzzerPin, 1500, duration);
    buzzerMillis = millis();
    
  }

  //***********************************
  else if (lockFlag == false && lockFlag2829 == false && temp >= 28.0 && temp <= 29.0)
  {
    mState = 3;
    //set disable flags
    lockFlag = true;
    lockFlag2425  = false;
    lockFlag2627  = false;
    //we only want to beep once per range entry point
    lockFlag2829  = true;

    buzzerCounter = 0;
    tone(buzzerPin, 1500, duration);
    buzzerMillis = millis();
    
  }

  //***********************************
  switch (mState)
  {
    //*********************
    case 0:
      break;

    //*********************
    case 1:
      if (millis() - buzzerMillis >= 1250)
      {
        //allow range checking once again
        lockFlag = false;
        mState = 0;
      }

      break;

    //*********************
    case 2:
      if (millis() - buzzerMillis >= 1250)
      {
        buzzerMillis = millis();
        buzzerCounter++;

        if (buzzerCounter >= 2)
        {
          //allow range checking once again
          lockFlag = false;
          mState = 0;

          break;
        }

        tone(buzzerPin, 1500, duration);
      }

      break;

    //*********************
    case 3:
      if (millis() - buzzerMillis >= 1250)
      {
        buzzerMillis = millis();
        buzzerCounter++;

        if (buzzerCounter >= 3)
        {
          //allow range checking once again
          lockFlag = false;
          mState = 0;

          break;
        }

        tone(buzzerPin, 1500, duration);
      }

      break;

  } //END of switch/case


} //END of loop()

Yes thankyou! That works great!
If i was to continue with the temperature (for example, raising my range up to 31 degrees) would i just copy and paste the if statements and write up a new case?
Thankyou so much for your help !! :smiley:

After you understand what’s happening, repeat things accordingly.

You do realize 25.0 to 26.0 and 27.0 to 28.0 are not covered.

Thankyou so much for all your help!!
Just one final question, what makes each lockFlag either true or false?
As you can see by the code you have given me, each LockFlag is labelled true or false differently.
(Sorry if this is a dumb question, as I am very new to this.)
Thankyou, Tegan :smiley:

//********************************************************************************************

  if (lockFlag == false && lockFlag2425 == false && temp >= 24.0 && temp <= 25.0)
  {
    mState = 1;
    //set disable flags
    lockFlag = true;
    //we only want to beep once per range entry point
    lockFlag2425  = true;
    lockFlag2627  = false;
    lockFlag2829  = false;

    tone(buzzerPin, 1500, duration);
    buzzerMillis = millis();
    
  }

//********************************************************************************************

  else if (lockFlag == false && lockFlag2627 == false && temp >= 25.0 && temp <= 26.0)
  {
    mState = 2;
    //set disable flags
    lockFlag = true;
    lockFlag2425  = false;
    //we only want to beep once per range entry point
    lockFlag2627  = true;
    lockFlag2829  = false;

    buzzerCounter = 0;
    tone(buzzerPin, 1500, duration);
    buzzerMillis = millis();
    
  }
. . .
  //***********************************
  if (lockFlag == false && lockFlag2425 == false && temp >= 24.0 && temp <= 25.0)
  {
    mState = 1;
    //set disable flags
    lockFlag = true; // <———<<<< set true
. . .
. . .
    case 1:
      if (millis() - buzzerMillis >= 1250)
      {
        //allow range checking once again
        lockFlag = false;   //  <———<<<< set false
        mState = 0;
      }
. . .

Use search feature < F > to find others

The purpose of the ‘lockFlag’ variable is to ‘disable all’ range checking when you are timing a beeping sequence.

This flag can be considered as an overall disable flag.

If you didn’t have this flag and the temperature was fluctuating while beeping was executing (example 26.5 to 28.5), your sequence of beeps would be interrupted and you would ‘not’ get your desired results.

As for lockFlag2425, lockFlag2627 and lockFlag2829, these flags are used to stop checking a ‘specific range’ while you sit within that range.

If you didn’t have these flags, beeping would continue forever as long as you are in the temperature range.

lockFlag2425 = true; //this range checking is now disabled, only ‘one’ beep sequence is going to happen
lockFlag2627 = false; //this range checking will be allowed
lockFlag2829 = false; //this range checking will be allowed

Summary:
if (lockFlag == false && lockFlag2425 == false && temp >= 24.0 && temp <= 25.0)

Only when both the ‘overall’ lockFlag AND ‘specific’ lockFlag2425 are false will you be allowed to check for this temperature range.

Please do not send PMs.

You can attach large sketches to a post once you have reached code tag limits.
Your current sketch is attached below.

When you write code, compile and test it as you go.
Only when you are satisfied that things work should you proceed with adding new sections.

This avoids writing all the code all at once then having to go back and trying to find where all your faults are.

An observation:
It appears you are changing your design as you are proceeding with the project (i.e. you keep adding more and more capability).
You should always start with well thought out design criteria that includes 'ALL' your requirements.
In this way, you can avoid choppy coding, band aide fixes etc.

For example: if we knew at the start you wanted all these ranges ARRAYS would have been suggested.

YourCodeFromPM.ino (9.86 KB)

Code for 24 to 31 inclusive is attached below. Temp24-31.ino
Study things and add the other ranges as you need.

Note: there are easier ways to handle this using arrays, but let's stick with the current design.

If you don't understand what has been done, ask for help.

EDIT
Updated code to version 2 (fixed a upper limit bug).

Temp24-31.ino (9.16 KB)