0

I have 2 buttons. Button 1 will start/stop the melody while the button 2 will reset the melody. My melody is "Happy Birthday".

How am I going to use the buttons to start/stop/reset the melody?

Here's the code:

#include "pitches.h" 

int melody[] = { 
    NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_C4, NOTE_B3,
    NOTE_G3,NOTE_G3, NOTE_A3,NOTE_G3, NOTE_D4, NOTE_C4,
    NOTE_G3, NOTE_G3, NOTE_G4,NOTE_E4,NOTE_C4, NOTE_B3, NOTE_A3,  
    NOTE_F4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_D4, NOTE_C4
}; 

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

boolean needtoPlay;

void setup() { 
    pinMode(4, OUTPUT); 
    pinMode(2, INPUT); //START/STOP
    pinMode(3, INPUT); //PAUSE
} 

void loop() { 
    for (int thisNote = 0; thisNote < 26; thisNote++) { 
        int noteDuration = 1000 / noteDurations[thisNote]; 
        tone(4, melody[thisNote], noteDuration); 
        int pauseBetweenNotes = noteDuration * 1.60; 
        delay(pauseBetweenNotes); 
        noTone(4);

        if (needToPlay == true) {
        }
    } 
}
  • 1
    Step one is to make it work without using delay(). – Majenko Feb 8 '17 at 16:18
  • this one? delay(pauseBetweenNotes); – Da Phuc Feb 9 '17 at 9:37
  • That's the only delay there is, yes... – Majenko Feb 9 '17 at 11:43
1

Modify your code so notes will play using timer interrupts instead of delay(). Once your program is inside delay(), no button will be responded. Done that, you just have to read buttons either by polling them with digitalRead or using interrupts.

1

Easiest way would be to add this to the end of the for loop (inside the loop). Assuming buttons are pulled up.

//setting pause with pause button
if (digitalRead(pauseButtom) == LOW) {
    //it will not play while in this loop
    while (true) {
      //if the button is pressed again, exit the loop
      if (digitalRead(pauseButtom) == LOW) {
        break;
      }
      delay(10);
    }
}

For the reset, just break; it will exit the for loop and start again.

Alternately, instead of using a for loop, use a counter and increment / reset it. You will need to store most variables globally.

if(!paused) {
  //play note
  if (counter < numNotes) {
    counter++;
  } else {
    counter = 0;
  } 
}

if (digitalRead(pauseButtom) == LOW) {
  pause = !pause;
}

if (digitalRead(resetButtom) == LOW) {
  counter = 0;
}

You could move those last 2 conditionals to interrupts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.