I have a pressure measurement sensor attached to my boiler heating circuit. The sensor is attached to an arduino uno which also has an RFM12 radio. The radio transmits the boiler pressure and the time since the sketch started in millis.
I use the millis to calculate the actual uptime in days once the readings have been transmitted by radio.
Is there a feasable way to implement a forever timer using millis, which I can interpret once the readings are off the Arduino?
This is what I know
millis starts as soon as the sketch starts
millis on the 328p processor is 32-bits, or 4,294,967,295 increments from start, which is about 49.7 days.
millis rolls over. It does not crash when it rolls over after 49 or so days
How can I achieve a low overhead forever counter that goes well past 49.7 days, potentially into many years, so that I can periodically check the uptime - and see by looking at it that everything is running ok.
You could check to see if millis() returns a number smaller than the previous value returned, which would be a good sign that the internal counter rolled over.
If your power company is anything like those in my area, the chance that an Arduino will not lose power in the course of any one year is pretty small.
Here's a simple clock code. Add some lines to keep track of the number of days passed. Perhaps write to EEPROM hourly in case of power loss.
Each EEPROM address can be written to once an hour for 11+ years before the address Might stop working. Use multiple bytes to spread the 11 years even more if you're concerned about it.
Or, use a battery backed Real Time Clock, most have battery backed SRAM you can write indefinitely if you want to.
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;
// Initial time to start, adjust as needed.
byte hundredths;
byte tenths;
byte oldTenths;
byte secondsOnes = 0;
byte oldSecondsOnes;
byte secondsTens = 0;
byte minutesOnes = 2;
byte minutesTens = 3;
byte hoursOnes = 4;
byte hoursTens = 0;
void setup() {
Serial.begin(115200); // make serial monitor match
Serial.println ("Setup Done");
}
void loop() {
currentMicros = micros();
// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >= 10000UL) { // 0.01 second passed? Update the timers
previousMicros = previousMicros + 10000UL;
hundredths = hundredths + 1; // increment
if (hundredths >= 10) {
hundredths = 0; // else rollover and increment next digit
tenths = tenths + 1;
if (tenths >= 10) {
tenths = 0;
secondsOnes = secondsOnes + 1;
if (secondsOnes >= 10) {
secondsOnes = 0;
secondsTens = secondsTens + 1;
if (secondsTens >= 6) {
secondsTens = 0;
minutesOnes = minutesOnes + 1;
if (minutesOnes >= 10) {
minutesOnes = 0;
minutesTens = minutesTens + 1;
if (minutesTens >= 6 ) {
minutesTens = 0;
hoursOnes = hoursOnes + 1;
if ((hoursTens == 2) && (hoursOnes == 4)) {
hoursOnes = 0;
hoursTens = 0;
}// hours total rollover check
if (hoursOnes >= 10) {
hoursOnes = 0;
hoursTens = hoursTens + 1;
} // hoursOnes rollover check
} // minutesTens rollover check
} // minutesOnes rollover check
} // secondsTens rollover check
} // secondsOnes rollover check
} // tenths rollover check
} // hundredths rollover check
}// hundredths passing check
if (oldTenths != tenths) { // show the elapsed time
oldTenths = tenths;
Serial.print(hoursTens);
Serial.print(hoursOnes);
Serial.print(":");
Serial.print(minutesTens);
Serial.print(minutesOnes);
Serial.print(":");
Serial.print(secondsTens);
Serial.print(secondsOnes);
Serial.print(".");
Serial.println (tenths);
} // end one second check
} // end loop