Button controlled piezo

So I am stuck on a portion of my project involving a pushbutton and a piezo speaker. I am trying to tell the speaker to beep on and off until a push button is pressed. I verified the button works I just cant get it to exit the do-while loop for some reason. I can attach more code if necessary. Thanks

 do
    {
      digitalWrite(speaker, HIGH);
      delay(250);
      digitalWrite(speaker, LOW);
      delay(100);
      digitalWrite(speaker, HIGH);
      delay(250);
      digitalWrite(speaker, LOW);
      delay(100);
      digitalWrite(speaker, HIGH);
      delay(500);
      digitalWrite(speaker, LOW);
      delay(100);

    }
    while(redButtonState==LOW)
do
    {
      digitalWrite(speaker, HIGH);
      delay(250);
      digitalWrite(speaker, LOW);
      delay(100);
      digitalWrite(speaker, HIGH);
      delay(250);
      digitalWrite(speaker, LOW);
      delay(100);
      digitalWrite(speaker, HIGH);
      delay(500);
      digitalWrite(speaker, LOW);
      delay(100);

    }
    while(redButtonState==LOW)

Where, in this block of code, will redButtonState ever change? If it is LOW when the loop starts, it will never end.

looks like you need a function if you don't already have it and just forgot the parenthesis.

#define redButtonGPIO 3 // or whatever digital pin it is
#define speaker 4 // or whatever digital pin it is

void setup() {
  // make it an innie
  pinMode(redButtonGPIO, INPUT);
 // make it an outie
  pinMode(speaker, OUTPUT);
}

byte redButtonState(void) {
  //figure out the state here
  return digitalRead(redButtonGPIO);
}

void loop() {
  //
  do
  {
    digitalWrite(speaker, HIGH);
    delay(250);
    digitalWrite(speaker, LOW);
    delay(100);
    digitalWrite(speaker, HIGH);
    delay(250);
    digitalWrite(speaker, LOW);
    delay(100);
    digitalWrite(speaker, HIGH);
    delay(500);
    digitalWrite(speaker, LOW);
    delay(100);
  } while (redButtonState() == LOW);

//some other stuff here.
}

and of course I assume you do something else after that. But this is in the loop() so it will just go back to beeping... I can't second guess where you would want to use this, as it will sit there until the button is pressed, but I think the whole thing should be in a different place. In simplest terms you'd want to test the condition for ringing the buzzer anyway, so:

void loop() {
  //
   if (buzzer needs to sound) {
     do
     {
       digitalWrite(speaker, HIGH);
       delay(250);
       digitalWrite(speaker, LOW);
       delay(100);
       digitalWrite(speaker, HIGH);
       delay(250);
       digitalWrite(speaker, LOW);
       delay(100);
       digitalWrite(speaker, HIGH);
       delay(500);
       digitalWrite(speaker, LOW);
       delay(100);
     } while (redButtonState() == LOW);
   }
//some other stuff here.
}

I'd make it a function or use an interrupt to regularly test if the buzzer needs to sound.

Anyway, hope that helps.

It works with the changes you recommended however the only way it will exit the do while loop is if the button is "HIGH" at the end of the loop. Is there a way to exit the loop at the instant the button is pressed regardless of where in the loop it occurs?

Get rid of the delay() functions and replace with a "many things at once" approach using millis() for timing.

I don't quite follow, could your write a quick example code?

Thanks!

rpmccarty:
I don't quite follow, could your write a quick example code?

It's already written... not by me... many things at once