Go Down

Topic: What is causing my time inaccuracy? (Read 2462 times) previous topic - next topic

dania25

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!
Code: [Select]

#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.
}

Coding Badly


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

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

mspguy

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.

Coding Badly

#3
Jan 20, 2011, 08:35 am Last Edit: Jan 20, 2011, 08:39 am by bcook Reason: 1
Quote
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

[size=16][glow]  NO THERE ISN'T!  [/glow][/size]

pluggy

I get 10 seconds a day accuracy out of a Uno and better than 2 seconds a day out of my Duemilanoves  with [size=20]crystals[/size]


sore point........
http://pluggy.is-a-geek.com/index.html

mspguy

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.

retrolefty

#6
Jan 20, 2011, 03:26 pm Last Edit: Jan 20, 2011, 03:27 pm by retrolefty Reason: 1
Quote
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.  ;)

Lefty

pluggy

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.
http://pluggy.is-a-geek.com/index.html

robtillaart

@Dania
It might be worth to consider a RTC e.g. from the datalog shield - http://www.ladyada.net/make/logshield/index.html - 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)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

dania25

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 :/

Coding Badly

Quote
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.

Go Up