here is a demo-code that creates a pure software RTC. Depending on the used board and if this board has ceramic resonator or a chrystal as clock-source the deviation will be up to minutes per day from exact time.
calculating "MinutesOfDay by hour * 60 + minutes is much easier to compare than hours and minutes separately
/* This software belongs to the public domain
* Attention: a software-RTC like this one
* which uses the onboard-oscillator of the microcontroller-board
* has a deviation from exact time of up to multiple seconds per day
* This means of you want real time with a higher precision use a
* hardware based RTC which will be much more precise
*/
unsigned long RTC_Timer = 0;
unsigned long MyTestTimer;
int RTC_Hour = 0;
int RTC_Minute = 59;
int RTC_Second = 50;
int RTC_10nth_Seconds = 0;
int minutesOfDay;
long secondsOfDay;
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void PrintRTC_Data() {
Serial.print("Software RTC time: ");
Serial.print(RTC_Hour);
Serial.print(":");
Serial.print(RTC_Minute);
Serial.print(":");
Serial.print(RTC_Second);
minutesOfDay = RTC_Hour * 60 + RTC_Minute;
secondsOfDay = RTC_Hour * 3600 + RTC_Minute * 60 + RTC_Second;
Serial.print(" minutesOfDay:");
Serial.print(minutesOfDay);
Serial.print(" secondsOfDay:");
Serial.print(secondsOfDay);
Serial.println();
}
void SoftRTC() {
if ( TimePeriodIsOver(RTC_Timer, 100) ) { // once every 100 milliseconds
RTC_10nth_Seconds ++; // increase 1/10th-seconds counter
if (RTC_10nth_Seconds == 10) { // if 1/10th-seconds reaches 10
RTC_10nth_Seconds = 0; // reset 1/10th-seconds counterto zero
RTC_Second++; // increase seconds counter by 1
if (RTC_Second == 60) { // if seconds counter reaches 60
RTC_Minute++; // increase minutes counter by 1
RTC_Second = 0; // reset seconds counter to zero
}
}
if (RTC_Minute == 60) { // if minutes counter reaches 60
RTC_Hour++; // increase hour counter by 1
RTC_Minute = 0; // reset minutes counter to zero
}
if (RTC_Hour == 24) { // if hours counter reaches 24
RTC_Hour = 0; // reset hours counter to zero
}
}
}
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
}
void loop() {
SoftRTC(); // must be called very regular and repeatedly to update the 0.1 second time-ticks
// this means you CAN'T use delay().
// Each and every single delay() must be replaced NON-blocking timing
if ( TimePeriodIsOver(MyTestTimer, 1000) ) { // if 1000 milliseconds have passed by
PrintRTC_Data(); // print time
}
}
best regards Stefan