0

I'm using RTC and when the if condition is true the Time gots stuck and the condition keeps looping. Please help

Here is my code:

// CONNECTIONS:
// DS1302 CLK/SCLK --> 5
// DS1302 DAT/IO --> 4
// DS1302 RST/CE --> 2
// DS1302 VCC --> 3.3v - 5v
// DS1302 GND --> GND
#include <Servo.h> 
#include <ThreeWire.h>  
#include <RtcDS1302.h>

ThreeWire myWire(4,5,2); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);
int servoPin = 3;
Servo Servo1;
void setup () 
{
    Serial.begin(57600);
    Servo1.attach(servoPin);
//    Serial.print("compiled: ");
//    Serial.print(__DATE__);
    Serial.println(__TIME__);

    Rtc.Begin();

    RtcDateTime compiled = RtcDateTime(__TIME__);
    printDateTime(compiled);
    Serial.println();

    if (Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was write protected, enabling writing now");
        Rtc.SetIsWriteProtected(false);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

    RtcDateTime now = Rtc.GetDateTime();
    if (now < compiled) 
    {
        Serial.println("RTC is older than compile time!  (Updating DateTime)");
        Rtc.SetDateTime(compiled);
    }
    else if (now > compiled) 
    {
        Serial.println("RTC is newer than compile time. (this is expected)");
    }
    else if (now == compiled) 
    {
        Serial.println("RTC is the same as compile time! (not expected but all is fine)");
    }
}

void loop () 
{
    RtcDateTime now = Rtc.GetDateTime();

    printDateTime(now);
    Serial.println();
    delay(5000);

//here is my problem>>>>


    if(now.Hour() == 22 && now.Minute() == 40)
    {
      Servo1.write(0);
      delay(1000);
      Servo1.write(90);
      delay(1000);

    }  

//////////////////////

    delay(5000); 


}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];
//%02u/%02u/%04u
    snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u:%02u:%02u"),
//            dt.Month(),
//            dt.Day(),
//            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}
  • Um... What does "Time gots stuck" mean? Your condition is true for a whole minute. – AnT May 6 at 15:16
  • when the condition is true the time interval of rtc gots stuck and the codition above keeps looping – kirby hipona May 6 at 15:18
  • It is loop() function keeps looping. That's what it is for, as the name suggests. What made you believe that "time interval of rtc gots stuck" is not clear to me. – AnT May 6 at 15:19
  • The time is stuck and the condition keeps triggering.. – kirby hipona May 6 at 15:20
  • What made you believe that "the time is stuck"??? The condition should keep triggering again, again and again for a whole minute. That's what you wrote in your code. – AnT May 6 at 15:20
2

What is being brought to your attention is the following part of your code...

//here is my problem>>>>

if(now.Hour() == 22 && now.Minute() == 40)
{
  Servo1.write(0);
  delay(1000);
  Servo1.write(90);
  delay(1000);
}  

In this code you use an "if" statement and ask: if the now.Hour is equal 22 AND if the now.Minute is equal 40 then write a 0 to your servo then delay for 1000 then write a 90 to your servo and wait another 1000

What is being brought to your attention is that until now.Hour changes or until now.Minute changes your write 0, delay, write 90, delay will continue on and on and on until now.Hour changes (which will take a while) or now.Minute changes. Since minutes are 60 seconds long your code will repeat for all of those 60 seconds...

If you were to change your code to include, oh, lets say now.Second() (like this)--

if(now.Hour() == 22 && now.Minute() == 40 && now.Second() == 00)

Then your code will repeat over and over until now.Second changes (which will take 1 second).

By the time your loop gets back to the "if" statement now.Second will no longer be 00 and it will not be "stuck" for you...


As has been brought to my attention, your 5 second delay will be a problem, so you might find that changing it will allow the now.Second "fix" to work.

In the following part of your code change delay(5000)

void loop () 
{
    RtcDateTime now = Rtc.GetDateTime();

    printDateTime(now);
    Serial.println();
    delay(5000);
}

to something like delay(1000) or so.

That way it will only wait 1 second before dropping out of the loop and checking the loop with the newly added now.Second(). This will make the printDateTime(now) happen every second instead of every 5 seconds, but it shouldn't get "stuck".

Hopefully this helps you to better understand how time (and its parts) work.

  • a state variable would be a much better solution. with the 5 sec delay in loop() the code could miss the exact second – Juraj May 6 at 17:32
  • 1
    Aiming for the exact equality with the scheduled time is a bad approach, regardless of how short the delay is. The proper condition should look as (current_time >= scheduled_time && event_has_not_been_triggered_yet). I.e. it should be a greater-or-equal comparison, not an equality comparison. – AnT May 6 at 21:51
  • Ah, experience speaks! I like that, a much better solution... – Wendall May 6 at 21:55
  • 1
    This approach might be further modified with extra tweaks like: if the above condition is true, but too much time has passed since the scheduled time (due to some unfortunate blocking operation in loop()), then just abandon the event. Depends on the specific application. Sounding an alarm to wake people up on a weekday morning is typically not a "discardable" event. Feeding the cat, if it is already well past its bedtime, probably is. – AnT May 6 at 22:07
  • Thank you Alexander! I do not know how to use the 'editor' as well as you, I was unable to add the OP's original code as well as you. Again, thanks! – Wendall May 15 at 13:44

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.