"while()" statement won't exit

I am trying to make an alarm clock. When the button is bushed the

while(now.hour() == 16 && now.minute() == 19){
      Buzz();
     if(buttonState == 1){
       break;
     }
    }

should exit the whole while statement and return to the loop, but it doesn't seem to do anything.

Here is the whole sketch in case it is anything else.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
//LiquidCrystal lcd(2,3,4,5,6,7);
LiquidCrystal lcd(7,8,9,10,11,12);
RTC_DS3231 RTC;
#define buz 13
const int buzzer = 13;
const int buzzer2 = 6;
const int button = 2;
int buttonState = digitalRead(button);

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2);
    pinMode(buzzer, OUTPUT);
    pinMode(buzzer2, OUTPUT);
    pinMode(button, INPUT);
}

void loop () {
    
    Serial.println(digitalRead(button));
    DateTime now = RTC.now();
    lcd.setCursor(0, 0);
    lcd.print(now.day(), DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.year(), DEC);
    lcd.print(' ');
    lcd.setCursor(0, 2);
     if (now.hour()<10)
    lcd.print('0');
    lcd.print(now.hour(), DEC);
    lcd.print(':');
     if (now.minute()<10)
    lcd.print('0');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    if (now.second()<10)
    lcd.print('0');
    lcd.print(now.second(), DEC);
    lcd.setCursor(12, 0);
    while(now.hour() == 16 && now.minute() == 19){
      Buzz();
     if(buttonState == 1){
       break;
     }
    }
    
}
void Buzz() {
    digitalWrite(buzzer2,HIGH);
    tone(buzzer, 3000); // Send 3KHz sound signal...
    delay(500);        // ...for 1 sec
    digitalWrite(buzzer2,LOW);
    noTone(buzzer);     // Stop sound...
    delay(500);        // ...for 1sec
  }

 void printTime() {
  int dayofweek;
   switch(dayofweek){
     case 1: 
     lcd.print("Mon");
     break;
     case 2:
     lcd.print("Tue");
     break;
     case 3:
     lcd.print("Wed");
     break;
     case 4:
     lcd.print("Thu");
     break;
     case 5:
     lcd.print("Fri");
     break;
     case 6:
     lcd.print("Sat");
     break;
     case 0:
     lcd.print("Sun");
     break;
    delay(1000);

   }
}

Apparently, you read the state of a pin before the while statement starts. Once it starts, you never read the state of the pin again, so the pin can change state a million times, and you'll never know.

Obviously, you need to read the state of the in IN the body of the while statement.

So all I have to do is, inside the while() statement,

    while(now.hour() == 16 && now.minute() == 19){
      Buzz();
      digitalRead(button);
     if(buttonState == 1){
       break;
     }
    }

So all I have to do is, inside the while() statement,

No. The digitalRead() function returns a value that you throw away. Make the digitalRead() call in the body of the statement look EXACTLY like the one before the body of the statement.

PaulS:
Make the digitalRead() call in the body of the statement look EXACTLY like the one before the body of the statement.

There is no other digitalRead() I wrote beforehand for the button pin, other than the Serial.println(digitalRead(button));

I don't understand :frowning: can you rephrase it again?

Something like:

while(now.hour() == 16 && now.minute() == 19)
{
    Buzz();
    buttonState = digitalRead(button);
    if(buttonState == 1)
       break;
}//while

In general using a variable to record the state of a pin tends to be a mistake.

Just read the pin directly and act on it.

while(now.hour() == 16 && now.minute() == 19)
{
    Buzz();
    if(digitalRead(button))
       break;
}

If you want to anything more advanced, call a function passing the result of digitalRead() to it,
lots of small functions with well chosen names makes for readable code.

Another way to structure code that responds to pins is using a state-machine.
Making states explicit can make code easier to read and modify.

Note that you're also not updating the time you read from the RTC during the while loop, so no matter how much time passes, now.Hour and now.Minute will never change. so until the button is pressed, it will never exit the while loop once it starts. Is this the behavior you want?