Making a 24 hour clock

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 5.
To post in this forum you must have a registered copy of Flowcode 5 or higher.

Moderator: Benj

Post Reply
billduck
Posts: 162
Joined: Thu Jul 01, 2010 1:57 am
Has thanked: 23 times
Been thanked: 16 times
Contact:

Making a 24 hour clock

Post by billduck »

I need the time for a solar tracking application. The choices are to use a GPS, or to use a RTC, or to use onboard timers with a correction. The correction is with a light sensor detecting sunrise and sunset. The mean time value will be applied to the clock at noon or midnight. The GPS approach is $$. The RTC clock drifts over time. So I am going to try light sensors. I can tolerate a daily error in terms of knowing where the sun is located. I have tried the following: Timer1 is used to increment the clock. Timer1 register is 16 bytes long = 65536 (2 to 16 power = 65536) The Mega clock goes at 16 mega Hz. The pre-scalar is 8. An additional loop scales the speed by 30. So 16,000,000/8/30 = 66666 Hz. The time for the 16 bit register to fill is 1.0172 seconds. (66666/65536 = 1.0172). The error is about 1 minute per hour. 1/ (1.0172-1) = 57.96 I am seeing the the accumulated error is more than 1 minute per hour, and am wondering why. Is it that the system clock has a tolerance (+/- ) ? Does anyone have a suggestion how the program could be modified so the scale factor (30) could be more precise? I can tweek the result by adding 1 minute per hour.
The uploaded program is a modified version that was obtained thru the forum's.
Attachments
InternalClock3.fcf_avr
(28.6 KiB) Downloaded 338 times

brandonb
Posts: 438
Joined: Mon Aug 29, 2011 12:26 am
Location: arizona
Has thanked: 175 times
Been thanked: 173 times

Re: Making a 24 hour clock

Post by brandonb »

here's a avr 328 arduino clock project i coded for a friend, can set the time hours,min,days, and displays in am pm format, it has tmr1 running at one hz, if can follow code sorry its in c, as it the closest thing i have to avr

Code: Select all

/* DAY ZERO IS MONDAY (0-6)
HOUR ZERO IS 12AM  (0-23)*/

#include <LiquidCrystal.h> 
LiquidCrystal lcd(7,8,9,10,11,12);

char* string_day_array [7]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
const byte d2=2;
const byte d3=3;
const byte d4=4;
const byte d5=5;
const byte d6=6;
const byte d13=13;
boolean switch1;
boolean switch2;
boolean switch3;
boolean switch4;
boolean switch5;
byte tick=0;
byte second=0;
byte minute=0;
byte hour=0;
byte day=0;
byte old_minute=minute;
byte old_hour=hour;
byte old_day=day;
byte temp_hour;
boolean update_display=1;
boolean first=1;
unsigned int delay_value;

void setup()
{
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1  = 0;
OCR1A = 15625;   // 1HZ
TCCR1B = 5;     // 1024:1 PRESCALER
TCCR1B |= (1 << 3);  
TIMSK1 &= ~(1 << 1);
interrupts();
  pinMode(d2,INPUT);
  pinMode(d3,INPUT);
  pinMode(d4,INPUT);
  pinMode(d5,INPUT);
  pinMode(d6,INPUT);
  pinMode(d13,OUTPUT);
  digitalWrite(d13,LOW);
  lcd.begin(16,2);
  lcd.clear();
  set_day();
  set_hour();
  set_minute();
  display_time();
}

void loop()
{
  if(update_display==1)
  {
    update_display=0;
    display_time();
  }
  /* THE CODE BELOW IS SET WHERE IT WILL TURN ON 
       THE D13 LED FRIDAY 11:20PM-11:22PM     */
  if((day==4)&&(hour==23))
  {
    if((minute>=20)&&(minute<22))
    {
      digitalWrite(d13,HIGH);
    }
    else
    {
      digitalWrite(d13,LOW);
    }
  }
}

//...........................................................................
   ISR(TIMER1_COMPA_vect)       
 {
     update_display=1;
     second=second+1;
     if(second==60)
     {
       second=0;
       minute=minute+1;
       if(minute==60)
       {
         minute=0;
         hour=hour+1;
         if(hour==24)
         {
           hour=0;
           day=day+1;
           if(day==7)
           {
           day=0;
         }
       }
     }
   }
 }
 //..........................................................................
  void display_time() 
 {
   if(first==1)
   {
     second=0;
     TIMSK1 |= (1 << 1);
     update_display=0;
     lcd.clear();
     lcd.setCursor(7,0);
     lcd.print(":");
     lcd.setCursor(10,0);
     lcd.print(":");
   }
   if((old_day>day)|(old_day<day)|(first==1))
   {
     if(day<10)
     {
     lcd.setCursor(1,0);
     lcd.print(string_day_array[day]);
     }
   }
   if((old_hour>hour)|(old_hour<hour)|(first==1))
   {
     temp_hour=hour;
     if(temp_hour>12){temp_hour=temp_hour-12;}
     if(temp_hour==0){temp_hour=12;}
     if(temp_hour<10)
     {
       lcd.setCursor(5,0);
       lcd.print(" ");
       lcd.setCursor(6,0);
       lcd.print(temp_hour);
     }
     else
     {
       lcd.setCursor(5,0);
       lcd.print(temp_hour);
     }
   }
   if((old_minute>minute)|(old_minute<minute)|(first==1))
   {
     if(minute<10)
     {
       lcd.setCursor(8,0);
       lcd.print("0");
       lcd.setCursor(9,0);
       lcd.print(minute);
     }
     else
     {
       lcd.setCursor(8,0);
       lcd.print(minute);
     }
   }
   if(second<10)
   {
     lcd.setCursor(11,0);
     lcd.print("0");
     lcd.setCursor(12,0);
     lcd.print(second);
   }
   else
   {
     lcd.setCursor(11,0);
     lcd.print(second);
   }
   lcd.setCursor(13,0);
   if(hour<12)
   {
   lcd.print("AM");
   }
   else
   {
   lcd.print("PM");
   }
   old_minute=minute;
   old_hour=hour;
   old_day=day;
   first=0;
 }
 //..........................................................................
  void set_day()
 {
  update_display=1;
  lcd.clear();
  do
   {
   lcd.setCursor(3,0);
   lcd.print("<SET DAY>");
   lcd.setCursor(5,1);
   switch1=digitalRead(d4);
   switch2=digitalRead(d5);
   switch5=digitalRead(d3);
   if(switch1==1)
   {
     day=day+1;
     delay_value=450;
     if(day>6){day=0;}
     update_display=1;
   }
   else if(switch2==1)
   {
     day=day-1;
     delay_value=450;
     if(day>6){day=6;}
     update_display=1;
   }
   if(update_display==1)
   {
     update_display=0;
     lcd.setCursor(6,1);
     lcd.print(string_day_array[day]);
     delay(delay_value);
     }
   }while(switch5!=1);
   delay(500);
 }
 //.................................................................
 void set_hour()
 {
   update_display=1;
   lcd.clear();
   do
   {
   lcd.setCursor(3,0);
   lcd.print("<SET HOUR>");
   lcd.setCursor(5,1);
   switch1=digitalRead(d4);
   switch2=digitalRead(d5);
   switch3=digitalRead(d6);
   switch5=digitalRead(d3);
   if(switch1==1)
   {
     hour=hour+1;
     if(switch3==1){delay_value=250;}
     else
     {
     delay_value=450;
     }
     if(hour==24){hour=0;}
     update_display=1;
   }
   else if(switch2==1)
   {
     hour=hour-1;
     if(switch3==1){delay_value=250;}
     else
     {
     delay_value=450;
     }
     if(hour>24){hour=23;}
     update_display=1;
   }
   if(update_display==1)
   {
     update_display=0;
     temp_hour=hour;
     if(temp_hour>12){temp_hour=temp_hour-12;}
     if(temp_hour==0)
     {
       temp_hour=12;
     }
     if(temp_hour<10)
     {
       lcd.setCursor(5,1);
       lcd.print(" ");
       lcd.setCursor(6,1);
       lcd.print(temp_hour);
     }
     else
     {
       lcd.setCursor(5,1);
       lcd.print(temp_hour);
       }
        lcd.setCursor(8,1);
   if(hour<12)
   {
   lcd.print("AM");
   }
   else
   {
   lcd.print("PM");
   }
   delay(delay_value);
     }
   }while(switch5!=1);
   delay(500);
 }
 //..................................................................
 void set_minute()
 {
   update_display=1;
   lcd.clear();
    do
   {
   lcd.setCursor(2,0);
   lcd.print("<SET MINUTE>");
   lcd.setCursor(5,1);
   switch1=digitalRead(d4);
   switch2=digitalRead(d5);
   switch3=digitalRead(d6);
   switch5=digitalRead(d3);
   if(switch1==1)
   {
     minute=minute+1;
     if(switch3==1){delay_value=120;}
     else
     {
     delay_value=250;
     }
     if(minute==60){minute=0;}
     update_display=1;
   }
   else if(switch2==1)
   {
     minute=minute-1;
     if(switch3==1){delay_value=120;}
     else
     {
     delay_value=250;
     }
     if(minute>60){minute=59;}
     update_display=1;
   }
   if(update_display==1)
   {
     update_display=0;
      if(minute<10)
     {
       lcd.setCursor(7,1);
       lcd.print(" ");
       lcd.setCursor(8,1);
       lcd.print(minute);
     }
     else
     {
       lcd.setCursor(7,1);
       lcd.print(minute);
       }
       delay(delay_value);
     }
   }while(switch5!=1);
 }
Last edited by brandonb on Tue Jun 04, 2013 3:07 am, edited 1 time in total.

billduck
Posts: 162
Joined: Thu Jul 01, 2010 1:57 am
Has thanked: 23 times
Been thanked: 16 times
Contact:

Re: Making a 24 hour clock

Post by billduck »

Thanks. In void setup (), I am seeing
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 15625; // 1HZ
......

Flowcode does not have the ability to count to a preset value yet - "15625", so I am doing a timer1 overflow. I wonder if I could add "OCR1A = 15625; // 1HZ" in c code.

brandonb
Posts: 438
Joined: Mon Aug 29, 2011 12:26 am
Location: arizona
Has thanked: 175 times
Been thanked: 173 times

Re: Making a 24 hour clock

Post by brandonb »

yes, thats why i posted it, that works great for a 328p, not sure about the one you are using... im using tmr1, also look at the tmr vector code, i can show you how it works when i get off work in 6 hours with a video
{edit} oops i guess i did use timer1, but i used compair instead of overflow as its more accurate and can calculate accurate values, here is the website that i learned about the avr interrupts http://letsmakerobots.com/node/28278
Last edited by brandonb on Tue Jun 04, 2013 3:11 am, edited 1 time in total.

User avatar
JohnCrow
Valued Contributor
Valued Contributor
Posts: 1367
Joined: Wed Sep 19, 2007 1:21 pm
Location: Lincolnshire
Has thanked: 364 times
Been thanked: 716 times

Re: Making a 24 hour clock

Post by JohnCrow »

Nice program.
Just had a quick look at it on my Arduino board. Seems to work fine, though not got time to have a close look at the code tonight.
Thanks.
1 in 10 people understand binary, the other one doesn't !

Post Reply