Elapsed event time using RTC

Ok, first things first, I'm feeling like a moron at the moment.

I have been so deep in a rabbit hole trying to figure out this simple task, reading libraries, searching google, blah blah, that my brain hurts.

So, what I need is help from the community.

I'm using DS1307RTC with TimeLib.h and DS1307RTC.h on the MEGA2560.

There are two things I want to accomplish:

  1. I need to trigger a RTCNOW() event at the beginning of a bit of code and display the time elapsed in D:H:M:S format. This needs to be an increasing value.

  2. I have a button on interrupt to set a flag to pause the code, but I need to put the clock in a pause state as well. This is to say I know the RTC will continue to run, but I need the elapsed time to pause until the flag is cleared by another button press.

Does anyone have code that did similar things and care to share it? I can't thank the community enough for all the support. I've been lurking for a couple years, but first time asking for help.


Oh, another REALLY important point. I can't use delay() or milli.

I have modified timers for other uses and these will not work.

void timerwait()
unsigned int cntdown = 0;
while (1)
    tmElements_t tm; //--(The tmElements_t object is a structure. You can create an instance of the structure,)-- 
    //--(populate the members of the structure, and then pass the structure to makeTime.)--

    RTC.read(tm); //--(Read time from RTC)--

    lcd.setCursor(0, 2);
    lcd.write("Real Time ");
    RTCtime(); //--(Call RTCtime() function)--
    lcd.setCursor(0, 3);
    lcd.write("Remain ");

    //--(RTCdelay set in inline code prior to timerwait() function call)--
    cntdown = ((timeEnd - timeStart) + RTCdelay);
    lcd.setCursor(8, 3);
    lcd.write(" ");
    lcd.write("sec  ");
    if (pFlag == 0) //--(If 1, pause is active and we want counter to stop)--
       timeStart = ((tm.Hour * 60 * 60) + (tm.Minute * 60) + tm.Second); //--(Convert time to seconds)--
    if (flag == 1)
      timeEnd = timeStart; //--(Save an end variable for comparison)--
      flag = 0; //--(flag disables this if statement so end variable is not overwritten)--

    //--(Not a fix for pause issue)--
    if (cntdown > RTCdelay)
       flag = 1;

    if (pFlag == 1)//--(Triggered by pause interrupt button)--
       address = 41;
       val = timeEnd;
       writeAddress(address, val); //--(Save timeEnd variable to RTC RAM)--  
       address = 41;
       readVal = readAddress(address); //--(Read saved timeEnd variable from RTC RAM)--
       timeEnd = readVal;
    if ((timeStart == (timeEnd + RTCdelay)) && (flag == 0)) //--(RTCdelay is seconds, i.e. if RTCdelay = 1800 seconds = 30 minutes)--
      flag = 1; //--(Enable if statement for next time)--
      //--(Set program to kick out of timer and back to inline loop routine, this if statement is only triggered ONCE)--
      //--(Next round, else below will be true again)



This bit of code (function) directly relates to the pause issue I am having.

I don't even have code for issue 1. Well, that's not exactly honest. I've butchered the logger example for one of the libraries in an attempt to get an increasing elapsed time, but no progress in my hack and slash attempt.


time1 = start
time2 = when interrupt happens which sets flag
time3 = when flag is cleared
time4 = end

So, you want to ignore time2 to time3 ?

Not exactly. I need the countdown to pause when that flag is set with the switch on interrupt and resume where we left off when the flag is cleared.

Current code continues to count and the function exits as expected when the counter finishes, even if the pause is active.

I do have the pause functioning properly with other functions, just not where the RTC is concerned.

Seems I have a serious lack of understanding when it comes to time! Lol

Does this answer your question and add some clarity? I know it can be extremely difficult to troubleshoot a problem without clear information. I’m so close to the program (about three months of development time) it is hard to know what to post and what is too much information.

Happy to provide additional information. I can’t post all the code, unfortunately. It’s thousands of lines of code and pretty specific to the other hardware I’m using.

On the other hand, thanks to the forum, I’ve managed to solve quite a few smaller issues others may find useful as code snippets. I’m going to try and strip those out and give back to the community.


It might help to stop thinking about “pausing” anything and instead think of it as two separate and distinct time periods and add them together later.

Happy to provide additional information. I can’t post all the code, unfortunately. It’s thousands of lines of code and pretty specific to the other hardware I’m using.

We can deal with big code. We can deal with code that is specific to some hardware. But you could always come up with some trivial example that we could work on if you don't want to work on your larger code. In many ways that would be the smarter thing to do.

Wow, forest for the trees! I do get lost sometimes. Makes sense to me. I’ll try to work on the two timing events in the morning!

As far as posting the whole code, you’re absolutely right. I know you guys can handle the whole package.

However, am I incorrect in thinking by posting the code that is giving me the issue is saving time and preventing confusion? I’m asking, not trying to be smart. I am appreciative for all the responses!


Posting code would definitely save time and prevent confusion. Nothing is worse than trying to suss something out only to find out later that the code is written in a completely different way and it won't work.

Posting code would definitely save time and prevent confusion.

Best would be to write a simple stand alone piece of code which reproduces the problem.

You would not be the first forum user to find the solution when you were doing that.

Ok, I stripped this down to bare requirements. If you have the hardware, this will compile and run. I should have done this in the first place to test the problem and find the solution. DOH

If you want a puzzle to solve, I will accept all help, to include solutions. If I solve it on my own, you can be certain I will post it here!

Thanks for the guidance and support. I appreciate you giving me your most valuable asset, which is your time!


RTC_pause_debug.ino (14.2 KB)

So I made zero progress trying to solve this using UNIX time. Seems like time in general is my kryptonite.

Not being one to give up, I made adjustments to the timer0 to enable the use of millis() again.

I managed to get the elapsed timer function to work using millis(), but broke my pause function. I suspect, since millis() uses an interrupt AND I’m using an interrupt to bool a flag for the pause function I’ve now got a conflict with interrupts.

I’ll post the updated code Monday. Any suggestions are welcome!

delay(2000); //--(Time delay-20000 is about 5 seconds)

That is 2 seconds, not 20, and not 5.

Actually, it was exactly as I commented when used in the whole program, since I used a different scaling factor to timer0.

That said, in the code I provided, you are absolutely correct. Apologies for neglecting to pay closer attention to detail there. Pressure and time...

If anyone reads this looking for help, I did finally solve this issue. PM me if you are interested in the solution.

If anyone reads this looking for help, I did finally solve this issue. PM me if you are interested in the solution.

Don't be like that. Post it out here where someone searching can find it. You might not be around later to answer a PM. We helped you out in the open, post the solution out in the open. Don't hide it away. That's just rude.

Rude? Wrong word choice. Lazy might be a better option. LOL

here is the snippet that got me there:

//void time_elapse() //--(For cycle only)--
  DateTime now = rtc.now();
  timeStart = ((now.hour() * 60 * 60) + (now.minute() * 60) + now.second()); //--(Convert time to seconds)--

  if (timeElapse1 == 0)
    elapsetime = timeStart; //--(Save variable for calculation on first call of function)--
    timeElapse1 = 1; //--(toggle elapse time variable to stop cycle timer on next function call)--

  if (timeElapse1 == 1)
    elapsetime = timeStart - elapsetime; //--(calculate in seconds how long a piece of code took to run)--
    lcd.setCursor(11, 1);
    timeElapse1 = 0; //--(toggle elapse time variable to start cycle timer on next function call)--
    elapsetime = 0; //--(zero out variable for next use)--


Hope this is helpful

See, now you post it and I spot a big ole bug hiding in it. You never would have known that if you kept it secret. And it might have been some considerable time before it bit you.

timeStart = ((now.hour() * 60UL * 60) + (now.minute() * 60) + now.second());

DOH, how right you are. Funny how that works...

I thank you!


timeStart = ((now.hour() * 60UL * 60) + (now.minute() * 60) + now.second());

That still doesn’t deal with midnight.

What kind of overall intervals are we talking about?
What kind of precision over that interval?
I suspect all this could be a LOT simpler.