Buzzer not turning off - false code?

Hello, this is my first time posting on here and I just got into Arduino so don’t be too harsh on my code. I have a simple problem. I am in the process of making an alarm clock that uses an LCD display, a passive buzzer to make sound and a button to turn it off. I would input the wanted time through serial, but I haven’t gotten to that point yet.
My problem is as follows: Right now the button is used as an on/off switch for the buzzer. When I upload the code, the buzzer is not making a sound (as it should). When I press it, it makes a siren sound(as it should). BUT when I press it again it does not turn off, but makes a monotone sound, kind of quiet but definitely noticeable. Why doesn’t digitalWrite(buzzerPin, LOW); that I call in alarmSound() function turn off my buzzer?
I have tried with analogWrite(buzzerPin, 0) and tone(buzzerPin,0) as well, neither seems to turn off the buzzer. I have also tried using pins 3 and 9, both analog. Could it be that my Arduino is faulty?
I have also checked the buzzer independently, it works fine and will shut off when used alone.
Here is my code.

#include <LiquidCrystal.h>

int buzzerPin = 9;
int buttonPin = 4;
LiquidCrystal lcd (7,6,10,11,12,13);

float sinVal;
int toneVal;

boolean soundOn = false;
boolean alarmSet = false;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  pinMode(5, OUTPUT);
  lcd.begin(16,2); //broj stupaca i redova
  lcd.print("Alarm nije");
  lcd.setCursor(0,1);
  lcd.print("Postavljen");
  analogWrite(5, 150); //kontrast
  Serial.begin(9600);
}

void loop() {
  
  checkButton();
  alarmSound();

}


void alarmSound(){
    for(int x=0;x<360;x++){
      checkButton();   
      if(soundOn == true){
      sinVal = sin(x * PI / 180);
      toneVal = 2000 + sinVal*500;
      tone(buzzerPin, toneVal);
      delay(1);
      }
      else{
        digitalWrite(buzzerPin, LOW);
      }
    }   
}

void checkButton(){
  //pritisak gumba - mijenjaj stanje alarma
  // ifovi radi bouncea
  if(digitalRead(buttonPin) == LOW){
  delay(10);
  if(digitalRead(buttonPin) == LOW){
    checkSound();
    while(digitalRead(buttonPin) == LOW){
      delay(10);
    }
  }
 }
}

void checkSound(){
  if(soundOn == true){
    soundOn = false;
    Serial.println("Alarm ugašen! Danas će biti dobar dan.");
  }
  else if(soundOn == false){
    soundOn = true;
    Serial.println("Ide gas!");
  }
}

You are setting buttonpin as input, do you have a pull up resistor? If not that’s your first problem.

See Buttons and other electro-mechanical inputs (introduction) - #2 by PerryBebbington

“A resistor between the input and Vcc is a pull-up resistor.”
Yes, I do.

I think that you call checkButton() too often, from many places. On exit the state of soundOn with a bouncing button is random. What does the Serial Monitor say?

Not where I would start.

What is this buzzer you speak of and how is it wired?

Also you aren’t really using the LCD yet , try commenting out all reference to it and removing it from the circuit until you get the sound thing working.

a7

The serial prints messages to button presses as expected and the sound changes as well, but it does not turn off. I have added ifs that were supposed to remove button bounce and I’m pretty sure that part of code works.

It is a passive buzzer, plus pole is short circuted to Vcc and the minus pole is connected to a collector of a bipolar transistor. The base of the transistor is connected to the buzzerPin, which I use to make the sound. The emitter is connected to ground. I can post pictures if you want.
Also, that tip makes some sense. I will try it.

I hope you have used a current limiting resistor between pin and base,
otherwise the transistor and/or pin could already be damaged.
Leo…

Yes of course, a 1k resistor. I have done the tutorials, I know the basics.

Then you also should know that a piezo is kind of a capacitor, should be loaded and unloaded in turn. A transistor only loads it. Why don’t you connect it to the Arduino output pin for continued load/unload? Using the current limiting resistor, of course.

Are you suggesting not to use the transistor at all and to connect a pin to the buzzer? I thought using a bipolar transistor as an amplifier would give a louder sound (that’s how the tutorial showed it).

My thoughts apply to a piezo buzzer. Which buzzer type do you use?

it is listed as a “passive buzzer” on the component list. I’m not sure if that is the same thing as piezo buzzer.

Your code works perfectly.

If.

I remove the LCD.

I use an LED and digitalWrite(buzzerPin, HIGH) instead of tone.

Try

  noTone();

instead of

 digitalWrite(buzzerPin, LOW);

to turn off you buzzer.

Below is what I did, I tried very hard not to tinker with the structure and flow of your logic, so it’s the buzzer (probable) or the LCD (less so) that’s hagging you up…

int buzzerPin = 9;
int buttonPin = 4;


float sinVal;
int toneVal;

boolean soundOn = false;
boolean alarmSet = false;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);
  pinMode(5, OUTPUT);

  Serial.begin(9600);
}

void loop() {

  checkButton();
  alarmSound();

}

void alarmSound() {
  for (int x = 0; x < 25; x++) {    // fewer, just so
    checkButton();
    if (soundOn == true) {
      sinVal = sin(x * PI / 180);
      toneVal = 2000 + sinVal * 500;
 
      //      tone(buzzerPin, toneVal); no, blink an LED on the pin instead

      digitalWrite(buzzerPin, HIGH);
      delay(25);
      digitalWrite(buzzerPin, LOW);
      delay(25);

    }
    else {
      digitalWrite(buzzerPin, LOW);
    }
  }
}

void checkButton() {
  //pritisak gumba - mijenjaj stanje alarma
  // ifovi radi bouncea
  if (digitalRead(buttonPin) == LOW) {
    delay(10);
    if (digitalRead(buttonPin) == LOW) {
      checkSound();
      while (digitalRead(buttonPin) == LOW) {
        delay(10);
      }
    }
  }
}

void checkSound() {
  if (soundOn == true) {
    soundOn = false;
    Serial.println("Alarm ugašen! Danas će biti dobar dan.");
  }
  else if (soundOn == false) {
    soundOn = true;
    Serial.println("Ide gas!");
  }
}

Nice to learn a bit of Croatian in the process!

HTH

a7

Passive buzzers (they don’t make sound when connected to 5volt/ground) are usually piezo.
They must have a resistor across when driven by a single transistor, to discharge the piezo.
But they don’t need a transistor, and can be driven directly by a (push/pull) pin.
Use a 220 ohm resistor in series to protect the pin (a piezo is a capacitor).

Piezo buzzers are usually used with the toneAC library (not tone() ).
And connected between two pins (with a 220 ohm series resistor).
That drives the with AC, and makes them louder (piezos are rather quiet).

You could of course have an active piezo, in which case you shouldn’t use ‘tone’ at all.
Leo…

I finally got around to working on it, and noTone(buzzerPin) solved the problem. Didn't know that function exists!
Thank you very much.

Yay!

TBH neither did I…

a7