Go Down

Topic: "while()" statement won't exit (Read 205 times) previous topic - next topic

epicgamer

Feb 10, 2019, 10:27 pm Last Edit: Feb 10, 2019, 10:28 pm by epicgamer
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);

   }
}

PaulS

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.
The art of getting good answers lies in asking good questions.

epicgamer

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;
     }
    }

PaulS

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.
The art of getting good answers lies in asking good questions.

epicgamer


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?

Blackfin

Something like:

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

MarkT

#6
Feb 11, 2019, 02:33 am Last Edit: Feb 11, 2019, 02:37 am by MarkT
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.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

DrAzzy

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?
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

Go Up