Okay, after using the following code (more of a timer), my clock has fallen behind 40 seconds after 10 hours.
#define displayPin 2
#define goPin 3
int second = 0, minute = 0, hour = 0;
boolean displayIsPressed = false;
boolean goPinIsPressed = false;
boolean startClock = false;
unsigned long aTime = 0;
unsigned long trigger;
unsigned long secondDelay = 1000;
void setup(){
Serial.begin(9600);
pinMode(displayPin, INPUT);
pinMode(goPin, INPUT);
trigger = millis();
}
void loop(){
/********** CHECK BUTTONS **********/
// Display time Button
if(buttonPressed(displayPin) && !displayIsPressed)
{
displayIsPressed = true;
serialOutputTime();
}
else if(!buttonPressed(displayPin))
{
displayIsPressed = false;
}
// Go button
if(buttonPressed(goPin) && !goPinIsPressed)
{
goPinIsPressed = true;
startClock = true;
aTime = millis();
}
else if(!buttonPressed(goPin))
{
goPinIsPressed = false;
}
if(startClock == true)
{
updateTime(aTime);
}
}
void updateTime(unsigned long adjustment){
/********** UPDATE TIME **********/
// Move forward one second every 1000 milliseconds
while(millis() - adjustment - trigger >= secondDelay)
{
second++;
trigger += secondDelay;
}
// Move forward one minute every 60 seconds
if(second > 59)
{
minute++;
second = 0;
}
// Move forward one hour every 60 minutes
if(minute > 59)
{
hour++;
minute = 0;
}
}
boolean buttonPressed(int aPin){
if(digitalRead(aPin) == HIGH)
{
return true;
}
return false;
}
void serialOutputTime()
{
Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
Serial.print(":"); // a colon between the hour and the minute
Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
Serial.print(":"); // a colon between the minute and the second
Serial.println(second, DEC); // the second, sent to the screen in decimal format
}
This is a much better error, but I would still like to make it a little closer, so I will try adding an adjustment.
By my calculations It seems my crystal is off by 40 seconds every 10 hours or 36000 seconds, so to compensate for this:
40 / (10 * 60 * 60) = 0.00111111111
Now:
0.00111111111 * 1 000 = 1.11111111
So I will adjust my "secondDelay" from 1000 to 998.99999.
Let me know if there are any errors in my math.