Button + Melody

I want to make a buzzer play one of two tunes according to the button I press. So far, the first song plays immediately without pressing any buttons and then it only works for one side, with the song playing till the end ignoring all button presses.

Here is my code:

#include "pitches.h"

// notes in the melody:
int melody1[] = {
   NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, 
   NOTE_E4, NOTE_GS4, NOTE_B4, NOTE_C5, 0, NOTE_E4, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, 
   NOTE_A4, 0, NOTE_C4, NOTE_E4, NOTE_A4, NOTE_B4, 0, NOTE_E4, NOTE_C5, NOTE_B4, NOTE_A4
};

int melody2[] = {
   NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_C5, NOTE_D5, 
   NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, 0, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, 0, NOTE_A4, NOTE_G4,
   NOTE_FS4, NOTE_A4, NOTE_C5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_A4, NOTE_D5, 0, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_C5, NOTE_E4, NOTE_C5, 
   NOTE_E4, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int notedurations1[] = {
   8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 8, 2
};

int notedurations2[] = {
   8, 8, 8, 4, 8, 4, 8, 3, 4, 8, 8, 8, 8, 8, 8, 4, 8, 4, 3, 4, 8, 8, 8, 4, 8, 4, 8, 2, 4, 8, 8, 8, 8, 8, 4, 8, 8, 8, 3, 4, 8, 8, 8, 4, 8, 
   4, 8, 3, 4, 8, 8, 8, 8, 8, 8, 4, 8, 4, 3, 4, 
};

const int button1 = 2;
const int button2 = 3;
const int piezo = 8;

int buttonState1 = 0;
int buttonState2 = 0;

void setup() {
   // iterate over the notes of the melody:
   

     // to calculate the note duration, take one second
     // divided by the note type.
     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. 

     pinMode(piezo, OUTPUT);
     pinMode(button1, INPUT_PULLUP);
     pinMode(button2, INPUT_PULLUP);
   
}

void playSong(int OutputPin, int Melody[], int NoteDurations[], int NumberOfNotes){
    for (int thisNote = 0; thisNote < NumberOfNotes; thisNote++) {
    
    int NoteDuration = 1000 / NoteDurations[thisNote];
    tone(OutputPin, Melody[thisNote], NoteDuration);
    int pauseBetweenNotes = NoteDuration * 1.30;
    delay(pauseBetweenNotes); 
   }
   noTone(OutputPin);
}

void loop() {
       
   buttonState1 = digitalRead(button1);
   buttonState2 = digitalRead(button2);
   
   if (buttonState1 == HIGH && buttonState2 == LOW) {
     playSong(8, melody1, notedurations1, sizeof(melody1)/sizeof(melody1[0]));
   }  
    
   else if (buttonState1 == LOW && buttonState2 == HIGH) {  
     playSong(8, melody2, notedurations2, sizeof(melody2)/sizeof(melody2[0]));
   }
   else { }
     // stop the tone playing:
     
}

I have posted about this before but no one responded to my recent update about a week ago so I decided to post it again.

Thanks!

Now you have two topics, and I don't know which one to answer. We don't like cross-posting on this forum.

As far as I know, you have two options: check the buttons while doing a delay during the melody, or run the melody from a table with millis() as timing. There is probably a working sketch somewhere for both options.

Keopel, I didn't exactly cross post over different forums. I just decided on a new post as no one responded to my update which was already a week ago.

Other thread locked.

itssohard:
I want to make a buzzer play one of two tunes according to the button I press. So far, the first song plays immediately without pressing any buttons and then it only works for one side, with the song playing till the end ignoring all button presses.

Here is my code:

Why do you think you can write a complicated program that works immediately without providing a few lines of debugging code which help you to find problems?

Serial debugging? (I.e. send a short Message "Play Melody 1" to the serial monitor when Button1 is pressed, acccordingly with Button2)

audible debugging? (i.e. play just one tone when Button1 is pressed and another tone when Button2 is pressed)

LED debugging? (i.e. blink LED on pin-13 for half a second if a button is pressed)
Why nothing of that?

Why fdid you write faulty non-working code and after one week there is still not a single line of debugging code included which might help in debugging the problem?

I have made a debugging code which includes playing one note when each button is pressed as well as turning the LED on pin 13 on and off.

Here it is:

#include "pitches.h"

// notes in the melody:
int melody1[] = {
   NOTE_C4
};

int melody2[] = {
   NOTE_D4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int notedurations1[] = {
   4
};

int notedurations2[] = {
   4, 
};

const int button1 = 2;
const int button2 = 4;
const int piezo = 8;
const int led = 13;

int buttonState1 = 0;
int buttonState2 = 0;

void setup() {
   // iterate over the notes of the melody:
   

     // to calculate the note duration, take one second
     // divided by the note type.
     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. 

     pinMode(piezo, OUTPUT);
     pinMode(button1, INPUT_PULLUP);
     pinMode(button2, INPUT_PULLUP);
     pinMode(led, OUTPUT);
}

void playSong(int OutputPin, int Melody[], int NoteDurations[], int NumberOfNotes){
    for (int thisNote = 0; thisNote < NumberOfNotes; thisNote++) {
    
    int NoteDuration = 1000 / NoteDurations[thisNote];
    tone(OutputPin, Melody[thisNote], NoteDuration);
    int pauseBetweenNotes = NoteDuration * 1.30;
    delay(pauseBetweenNotes); 
   }
   noTone(OutputPin);
}

void loop() {
       
   buttonState1 = digitalRead(button1);
   buttonState2 = digitalRead(button2);
   
   if (buttonState1 == HIGH && buttonState2 == LOW) {
     playSong(8, melody1, notedurations1, sizeof(melody1)/sizeof(melody1[0]));
     digitalWrite(led, HIGH);
     delay(1000);
     digitalWrite(led, LOW);
   }  
    
   else if (buttonState1 == LOW && buttonState2 == HIGH) {  
     playSong(8, melody2, notedurations2, sizeof(melody2)/sizeof(melody2[0]));
     digitalWrite(led, HIGH);
     delay(1000);
     digitalWrite(led, LOW);
   }
   else { }
     // stop the tone playing:
     
}

Now, the button that worked in the past plays the note and turns the LED on, while the other does nothing. I have also tried switching the pins around and changing the numbers on the code but the same button still doesn't work. I have also used a multimeter to see if everything is connected and it was.
What should I do now?

Thanks!

itssohard:
I have made a debugging code which includes playing one note when each button is pressed as well as turning the LED on pin 13 on and off.

Now, the button that worked in the past plays the note and turns the LED on, while the other does nothing. I have also tried switching the pins around and changing the numbers on the code but the same button still doesn't work. I have also used a multimeter to see if everything is connected and it was.
What should I do now?

Check the wiring of the buttons!
With pinmode INPUT_PULLUP the two button pins should be connected like that:
first button pin ==>Arduino-GND
second button pin ==> the Arduino pin defined ( button1 = 2; button2 = 4;)

And please take into consideration that you wrote your "playSong" function as a non-interruptable, blocking and busy-wating function (busy while playing notes), so that the reaction time on pressed buttons can become a nightmare: After "playSong" function has been started, there will happen nothing else in your program while the playSong function has not ended.

I.e: Your visible "debug LED" will not light up before or while the notes are playing, the LED will instead light up for one second, after the melody has been played in full length. That's how you wrote the code:

     playSong(8, melody1, notedurations1, sizeof(melody1)/sizeof(melody1[0]));
     digitalWrite(led, HIGH);
     delay(1000);
     digitalWrite(led, LOW);
   }

My buttons are wired to the pin and ground on the Arduino. I can change it so that the LED lights before the note but I still have no idea why the original code doesn't work other than one of the pins/buttons not doing anything although functional.

Thanks!