I had a similar problem, so I starting keeping time with a soft RTC from RTClib. It offers a software RTC that uses the millis() counter to track time. You can use it just like a hardware RTC, except you need to set the time at startup (such as with your NTP routine) rather than relying on a hardware RTC's battery to maintain the time across resets.
RTClib is available in the library manager in the Arduino IDE. It comes with examples, one of which is called softrtc which illustrates the use of the software rtc.
Here is the "TimeRTC" example from TimeLib, modified to use RTClib's RTC_Millis clock:
/*
* TimeRTC.pde
* example code illustrating Time library with Real Time Clock.
*
*/
#include <TimeLib.h>
#include <Wire.h>
#include <RTClib.h> // supports millis() clock as well as several hardware clocks incl DS1307
RTC_Millis soft_rtc;
void initSoftRTC() {
// the soft rtc needs to be set at startup, this example uses the
// sketch compile time, use your "daily NTP routine" here instead
soft_rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
// DateTime constructor can also take unixtime
}
// a custom time provider for the soft RTC
time_t mySyncProvider() {
return soft_rtc.now().unixtime();
}
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
initSoftRTC(); // soft rtc clock must be set at startup
// tell TimeLib to use the RTC instead of it's internal NTP driver
setSyncProvider(mySyncProvider); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
}
void loop() {
if (timeStatus() == timeSet) {
digitalClockDisplay();
} else {
Serial.println("The time has not been set. Please run the Time");
Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
Serial.println();
delay(4000);
}
delay(1000);
}
void digitalClockDisplay() {
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
void printDigits(int digits) {
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
As the RTC is generally kept in UTC time, I also use the Timezone library (also available in the library manager) to present dates and timestamps in specific timezones when needed. It's a great library too.
- Darrin