Arduino Forum

Using Arduino => Programming Questions => Topic started by: epicgamer on Feb 10, 2019, 10:27 pm

Title: "while()" statement won't exit
Post by: epicgamer on Feb 10, 2019, 10:27 pm
I am trying to make an alarm clock. When the button is bushed the
Code: [Select]

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.
Code: [Select]
#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);

   }
}
Title: Re: "while()" statement won't exit
Post by: PaulS on Feb 10, 2019, 10:29 pm
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.
Title: Re: "while()" statement won't exit
Post by: epicgamer on Feb 10, 2019, 10:35 pm
So all I have to do is, inside the while() statement,
Code: [Select]

    while(now.hour() == 16 && now.minute() == 19){
      Buzz();
      digitalRead(button);
     if(buttonState == 1){
       break;
     }
    }
Title: Re: "while()" statement won't exit
Post by: PaulS on Feb 10, 2019, 10:37 pm
Quote
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.
Title: Re: "while()" statement won't exit
Post by: epicgamer on Feb 10, 2019, 10:43 pm

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 :( can you rephrase it again?
Title: Re: "while()" statement won't exit
Post by: Blackfin on Feb 10, 2019, 11:14 pm
Something like:

Code: [Select]
while(now.hour() == 16 && now.minute() == 19)
{
    Buzz();
    buttonState = digitalRead(button);
    if(buttonState == 1)
       break;
}//while
Title: Re: "while()" statement won't exit
Post by: MarkT on Feb 11, 2019, 02:33 am
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.
Code: [Select]

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.
Title: Re: "while()" statement won't exit
Post by: DrAzzy on Feb 11, 2019, 03:29 am
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?