What is causing my time inaccuracy?

Hello!, I have the code below to check the temp reading of a thermistor and send the output to both a serial LCD and a serial logger (well, just serial monitor for now)

It counts time with the time.h library, and controls the frequency of events with the aiko events library. It works, but I let it run for 24 hours and the time was off by approximately 2 minutes... Is this inherent in the time.h way of counting time, or does it have something to do with the processing time of my loops (which would I suppose get worse with more complicated loops)?

PS: I realize that for this simple thing the Aiko events library is overkill, but I'm building a much bigger version.

Thanks!

#include <Time.h>
#include <NewSoftSerial.h>
#include <math.h>
#include <AikoEvents.h>
using namespace Aiko;

NewSoftSerial LCD(2,3); // serial LCD


//user definable variables//
int LCDrefreshrate = 1; //lcd refresh rate in seconds
int templograte = 5; // temp log freq in seconds

double Thermister(int RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0;// // Convert Celcius to Fahrenheit
 return Temp;
}

void setup()
{ 
  Events.addHandler(updatelcdtime, 1000);
  Events.addHandler(updatelcdtemp, LCDrefreshrate * 1000);
  Events.addHandler(templogserial, templograte * 1000);
  setTime(16,28,00,03,01,11);
  backlightOn();
  clearLCD();
}

void loop()
{  
  Events.loop();
}
void updatelcdtime(){
  LCD.begin(9600);
  selectLineOne();
  if(hour() < 10){
    LCD.print("0");// these ifs turn single digits to leading zero numbers
  }
  LCD.print(hour());
  LCD.print(":");
  if(minute() < 10){
    LCD.print("0");
  }
  LCD.print(minute());
  LCD.print(":");
  if(second() < 10){
    LCD.print("0");
  }
  LCD.print(second());
  LCD.print("        ");
}
void updatelcdtemp(){
  selectLineTwo();
  LCD.print(float(Thermister(analogRead(0))));
  LCD.print(" Celsius   ");
  
}

void templogserial(){ //modify this to reach logger properly
  LCD.begin(9600);
  goTo(10);
  LCD.print("Log");
  Serial.begin(9600);
  Serial.print("#S|LOGFILE|[");
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(":");
  Serial.print(second());
  Serial.print(" ");
  Serial.print(float(Thermister(analogRead(0))));
  Serial.println("]#");
}
  
void selectLineOne(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(192, BYTE);    //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+128), BYTE);    //position
}else if (position<32){LCD.print(0xFE, BYTE);   //command flag
              LCD.print((position+48+128), BYTE);    //position 
} else { goTo(0); }
}

void clearLCD(){
   LCD.print(0xFE, BYTE);   //command flag
   LCD.print(0x01, BYTE);   //clear command.
}
void backlightOn(){  //turns on the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    LCD.print(0x7C, BYTE);   //command flag for backlight stuff
    LCD.print(128, BYTE);     //light level for off.
}

(2 / (24 * 60)) * 100 = 0.14 %

...within the accuracy of a resonator. Which board are you using?

I there was a post about this last month. Basically, the timer0 (the one that is in charge of real time) can only be divided by powers of two and then causes periodic interrupts. The problem is it takes a non integer number of interrupts to equal 1 ms, so there is a small rounding error that accumulates.

If you want better time keeping you clock your timer from a watch crystal (=32,768khz) which can be divided down by powers of two into seconds.

I there was a post about this last month. Basically, the timer0 (the one that is in charge of real time) can only be divided by powers of two and then causes periodic interrupts. The problem is it takes a non integer number of interrupts to equal 1 ms, so there is a small rounding error that accumulates

NO THERE ISN'T!

I get 10 seconds a day accuracy out of a Uno and better than 2 seconds a day out of my Duemilanoves with crystals

sore point........

Woah, I'm sorry. It would have been more helpful to explain your self.

In any case I reread the relevant section of wiring.c and it appears that the fractions of MS are taken care of. My mistake.

I get 10 seconds a day accuracy out of a Uno and better than 2 seconds a day out of my Duemilanoves with crystals

sore point........

Well now you have a solution don't you? Just load your older 328 board, that has a crystal, with the new and improved and fixed opto-dewanko bootloader and presto a uno board that keeps time better.

Call it your Uno2009 and use your real Uno as a blink the led demo board. :wink:

Lefty

Now if the Uno used the same port in Linux, they could be interchangeable......

Honestly though, would real crystals break the budget on the Uno ?, mine has one crystal on the 8U2 serial USB chip, why not on both ?

I've no issues with resonators on a low end stuff, but surely a real genuine made in Italy Arduino Uno isn't low end ?

They are still flogging 2009 knockoffs on Ebay that have crystals.

@Dania
It might be worth to consider a RTC e.g. from the datalog shield - Data-Logger Shield for Arduino - although I never have investigated the accuracy my gut feeling says its less than 10 seconds a day.

If you need higher accuracy you must consider syncing with a timeserver using the NTP protocol (e.g. every hour)

Thank you all for the responses. It's an Uno board that I just purchased, so it's probably the latest one. I was just so surprised that the accuracy was THAT bad using the chip.

I already ordered the Sparkfun RTC, our choices are very limited here in Singapore as far as local suppliers which we don't need to wait 2 weeks for. The local companies seem to have 95% Sparkfun products :confused:

Thank you all for the responses. It's an Uno board that I just purchased, so it's probably the latest one. I was just so surprised that the accuracy was THAT bad using the chip.

I suggest testing the board's clock. The problem may be software. It's just more likely that the problem is the resonator. If you need help running the test, report back.