Stopping song with button input?

Hi ive only been using arduino for 21 and a bit hours i love it, but i cant get the passive buzzer to stop with inputs. Ive copied the song and duration also some code and it makes sense to me... ish.

been googling around but all the other help sites are for stuff waaaay yout my leage rn

#include "pitches.h"

int buzzerPin = 6;
int btn = 2;

int melody[] = {
  NOTE_G4, NOTE_C5, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_D4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_G4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_C5, NOTE_D5, NOTE_G4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_B4,
  NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_C5, NOTE_F5,
  NOTE_F5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_C5, NOTE_C5,
  NOTE_D5, NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_A4,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_C4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};

int noteDurations[] = {
  8, 4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 8, 8, 4, 8, 8, 4, 8, 8, 2,
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 6, 16, 
  4, 6, 16, 8, 8, 8, 8, 
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  4, 6, 16, 4, 6, 16, 4, 8, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  4, 6, 16, 4, 4, 2, 4, 4, 1
};

void setup() {
  for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(buzzerPin);
pinMode(btn,  INPUT);
 pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600); 
    
  }
}

void loop() {
 if (btn = LOW){
  digitalWrite(buzzerPin, HIGH);
 }
 else{
  digitalWrite(buzzerPin, LOW);
 }
}

formatted for forum now :wink:

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

[duplicate code removed]

done :slight_smile:

You have a for loop in setup() and until that is finished the code in loop() will not be executed, hence the button state will not be read. Do you see the a problem ?

Incidentally, why have you got

    noTone(buzzerPin);
    pinMode(btn, INPUT);
    pinMode(buzzerPin, OUTPUT);
    Serial.begin(9600);

in the for loop ?

that was also some of the code i copied, i tryed to move the int's outside the loop but it all failed then. i just assumed it had to be that way because it wouldnt work otherwise.

i do see the problem clealry now thanks, but i dont know how to solve it.

Unless you are doing something special, which you aren't, the pinMode()s should be executed only once near the start of setup(), as should the Serial.begin() and the noTone()

One (clumsy) way to stop the song with a button press would be to read the state of the button pin inside the for loop that is playing the song and break out of it. There are better ways but give it a try

1 Like

hey just wana say thanks for all the help. ive chaged the code to this and it still wont turn the song off when pressed

#include "pitches.h"

int buzzerPin = 6;
int btn = 2;

int melody[] = {
  NOTE_G4, NOTE_C5, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_D4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_G4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, 
  NOTE_A4, NOTE_G4, NOTE_F4, NOTE_G4, NOTE_C4, NOTE_C4, 
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5, 
  NOTE_E5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_C5, NOTE_D5, NOTE_G4, NOTE_G4, NOTE_B4, NOTE_C5, NOTE_D5,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_E4, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_B4,
  NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_C5, NOTE_F5,
  NOTE_F5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_C5, NOTE_C5,
  NOTE_D5, NOTE_C5, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_A4, NOTE_A4,
  NOTE_C5, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_C4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5
};

int noteDurations[] = {
  8, 4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 8, 8, 4, 8, 8, 4, 8, 8, 2,
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 8, 8, 
  4, 6, 16, 4, 6, 16, 
  4, 6, 16, 8, 8, 8, 8, 
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  2, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8,
  4, 6, 16, 4, 6, 16, 4, 8, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  2, 8, 8, 8, 8, 3, 8, 2,
  4, 6, 16, 4, 4, 2, 4, 4, 1
};

void setup() {
 pinMode(btn, INPUT);
 pinMode(buzzerPin, OUTPUT);
 Serial.begin(9600);
  noTone(buzzerPin);
}

void loop() {
   digitalRead(btn);
   for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
   
    digitalRead(btn);}

    if (btn=LOW){
    digitalWrite(buzzerPin, HIGH);
    }
    else{ 
    digitalWrite(buzzerPin, LOW);
  }
  
}

...3 errors in two lines...

  1. digitalRead() function reads the state of the pin and RETURNS it as HIGH or LOW. Calling it without saving return values is useless.
  2. Check the difference between "=" and "=="
  3. Your "btn" variable contains number of arduino pin to which the button is connected. It doesn't change and can't be LOW or HIGH
1 Like

hey, im still quite new to coding as a whole this all makes alot of sense now but what is - saving return values ?

When you read the state of the pin it is handy if you put the value into a variable so that you can use it later in the sketch or print it for debugging, or both

byte buttonState = digitalRead(btn);  //read the button and save its state
Serial.println(buttonState);  //print for debugging
if (buttonState == HIGH)
{
  //do something if the button state is HIGH
}
1 Like

still wont on or turn off, it reads the button once at the start ive tryed moving the code around. it looks to me like its always infinetly stuck on the for loop

void setup() {
 pinMode(btn, INPUT);
 pinMode(buzzerPin, OUTPUT);
 Serial.begin(9600);
  noTone(buzzerPin);
}

void loop() {
   byte btnstate = digitalRead(btn);  //read the button and save its state
Serial.println(btnstate);  //print for debugging
   
   digitalRead(btnstate);
   for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    digitalRead(btnstate);
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
   
    digitalRead(btnstate);}

btnstate = digitalRead(btn);  //read the button and save its state
Serial.println(btnstate);  //print for debugging
if (btnstate == LOW)
{
  digitalWrite(buzzerPin, LOW);
}
   else{
    digitalWrite(buzzerPin, HIGH);
    }

  }
  

You are reading the button state twice in the for loop and throwing away what it returns

  • read it at the start of the for loop
  • save its value in a variable (see my example)
  • if the button is pressed use the break; command to exit the for loop
  • after the for loop turn off the buzzer
1 Like

great news it now stops, but i cant get it off and on mid for loop. i put break; in and it just makes it go on and off constantly heres the code, again thanks for dealing with me mate :melting_face:

void setup() {
 pinMode(btn, INPUT);
 pinMode(buzzerPin, OUTPUT);
 Serial.begin(9600);
  noTone(buzzerPin);
}

void loop() {
   
   byte buttonState = digitalRead(btn);  //read the button and save its state
Serial.println(buttonState);  //print for debugging
if (buttonState == LOW)
{
  for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
}
}
Serial.println(buttonState); 
if (buttonState == HIGH){
 digitalWrite(buzzerPin, LOW);
}

I don't see where you try to break the "for" loop. To break the for cycle you should put button reading and testing in this loop, not to the loop() function

sorry i should have included, i honesty dont know where to put it. its my 1st time using it but i had it at the end of the for statement (on off constantly). if i put it in the if it would give me an error "break statement not within loop or switch"

ive put them below :slight_smile:

"break statement not within loop or switch"

void setup() {
 pinMode(btn, INPUT);
 pinMode(buzzerPin, OUTPUT);
 Serial.begin(9600);
  noTone(buzzerPin);
}

void loop() {
   
   byte buttonState = digitalRead(btn);  //read the button and save its state
Serial.println(buttonState);  //print for debugging
if (buttonState == LOW)
{
  for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
}
}
Serial.println(buttonState); 
if (buttonState == HIGH){
 digitalWrite(buzzerPin, LOW);
 break;
}

constanly beeps, but can be turned on and off

void setup() {
 pinMode(btn, INPUT);
 pinMode(buzzerPin, OUTPUT);
 Serial.begin(9600);
  noTone(buzzerPin);
}

void loop() {
   
   byte buttonState = digitalRead(btn);  //read the button and save its state
Serial.println(buttonState);  //print for debugging
if (buttonState == LOW)
{
  for (int thisNote = 0; thisNote < sizeof(melody) / 2; thisNote++) {
    int noteDuration = 2000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    break;
}
}
Serial.println(buttonState); 
if (buttonState == HIGH){
 digitalWrite(buzzerPin, LOW);
 //break;
}



} 
   

oh no...
Please take a break and try to read Arduino command reference.
Do not try to blindly pick up the right letters, programs are not written that way.

Read the button state inside the for loop and if the button is pressed then execute the break; command to exit the for loop