I'm working on a project and used a bit of code which I found on line to intergrate as a timer in my program. Once I got it working, I found that it gains aprox. 14 seconds every hour. I put in a couple lines to correct for this but I'm still curious as to why it's occuring in the first place. I would think a pulse width modulated signal would be more accurate. Anyway, as I'm new at this, I may be doing some little something wrong. If anyone sees the reason for the gained 14 seconds in my code, could you please let me know? Thanks.
const int buttonPin = 3; // the pin that the button is attached to
const int ledPin = 8; // to light an LED during development
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
int incomingByte; // to read input into
int TM[3]={0,0,0};
String readString;
int clockInt = 0; // digital pin 2 is now interrupt 0
int masterClock = 0; // counts rising edge clock signals
int seconds = 0; // variable
int minutes = 0; // variable
int hours = 0; // variable
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
attachInterrupt(clockInt, clockCounter, RISING);
// clockInt is our interrupt, clockCounter function is called
// when invoked on a rising clock edge
analogReference(DEFAULT);
analogWrite(10, 127); // this starts our PWM clock with a 50% duty cycle
}
void loop()
{
if (Serial.available() > 0) { //if any key is pressed
int incomingByte = Serial.read(); //read input into incomingByte
switch(incomingByte){ //depending on the value of incomingByte...
case 'z':
// z is just here so I can check the time without having to set it
Serial.print ("P Station time is ");
Serial.print(hours);
Serial.print(":");
Serial.print(minutes);
Serial.print(":");
Serial.println(seconds);
Serial.println ("");
break;
case 'J':
Serial.print ("Set Station time ");
if (hours < 10){
Serial.print("0");
}
Serial.print(hours);
Serial.print(":");
if (minutes < 10){
Serial.print("0");
}
Serial.print(minutes);
Serial.print(":");
if (seconds < 10){
Serial.print("0");
}
Serial.print(seconds);
Serial.print (" ");
hours = TimeProcess(); //hours, minutes, and seconds are populated
Serial.print(":"); //colons pops up between each set of 2 numbers
minutes = TimeProcess();
Serial.print(":");
seconds = TimeProcess();
Serial.println (""); // cariage return
Serial.print (" Station time ");
if (hours < 10){ //puts a "0" in the first digit location if needed
Serial.print("0");
}
Serial.print(hours);
Serial.print(":");
if (minutes < 10){ //same as was done for hours
Serial.print("0");
}
Serial.print(minutes);
Serial.print(":");
if (seconds < 10){ //same as was done for hours
Serial.print("0");
}
Serial.print(seconds);
Serial.println (" ");
break;
default:
Serial.println ("Invalid entry. Enter J to set the Time.");
}
}
}
void clockCounter() // called by interrupt
{
masterClock ++; //with each clock rise add 1 to masterclock count
if(masterClock == 489) // 490hz reached
{
seconds ++; //after one 490Hz cycle add 1 second
masterClock = 0; //Reset after 1 second is reached
//tone(13, 100, 500); //using tone to pulse LED without delay call
if (seconds == 60) // Now getting into real time keeping
{
minutes ++; //increments minutes by 1
seconds = 0; //reset the seconds variable
if (minutes == 30 || seconds == 30) //at each half hour and 30 seconds do this
{ //I could have put this anywhere within the hour. I just choose 30 min 30 sec
seconds = (seconds - 14); //corrects the clock
}
if (minutes == 60)//when minutes reach 60
{
hours ++;//incriments hours by 1
minutes = 0;//resets the minutes variable
if (hours == 24)//when hours reach 24
{
//days ++;
hours = 0;//rest the minutes variable
}
}
}
}
return;
}
long TimeProcess() //populates int hours, minutes, or seconds for easy printing
{
long var;
int cnt = 0;
for (int complete = 0; complete != 1;)//"complete" is initialized at 0 then the condition of the
// for loop is that "complete" is not 1
{ //loop will continue until "complete" becomes 1
while (Serial.available() > 0 )
{ //Serial.available recognizes digits pending in serial buffer
char c = Serial.read(); //reads data in serial buffer one byte at a time.
TM[cnt] = int(c - 48); //contents of c are copied to array TM
cnt++; //cnt is incrimented with each entery into the array
readString += c; //contents of char c are placed in readString
Serial.print (c); //prints each charicter as it's typed
delay(2);
if (cnt == 2) // when 2 digits are entered do this
{
Serial.print ("");
complete = 1; //make "complete" 1 which satisfies the for loop
}
}
}
if (readString.length()>0) //when readString gets content, do something
{
char carray[readString.length() + 1]; //creates an array of readString content
readString.toCharArray(carray, sizeof(carray)); // transfers readString into char array named carray.
long f = atol(carray); //creates long variable "f" equal to "array to long" conversion of data in carray.
var = f; //var is equal to "f" which we just converted to a number from array of chars.
readString=""; // make readString empty for next time around
readString[2]; //allocate 8 bytes of memory for readString
}
return var;
}