Go Down

Topic: What is causing my time inaccuracy? (Read 2 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........

Go Up