Making 24 hour clock

t06afre

Joined May 11, 2009
5,934
why not just making the counter with a simpel varibel, do we have space for it ?
Yes as it stands now you have used about 40 bytes of the RAM. And you have 255 bytes of RAM. Goto view and select Momory gauge usage. You can use a few bytes on counter for the rain. No problem. But I would still use a interrupt function for the rain counter
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
but i can also see an other little problem, if it rains when ex the time is adjustet, it will not count, if it has to check an input pin,
But how often do that happens ;)
i know it's late to make other things, but since i proberly have enough EEprom to data, i would like to store ex. today is "wed" then "tue" "mon-sun-sat-fri-thu" and last "wed", then it could write day -8, day -9 and up to 30 days. it shouldt be possible to make, but that is not importian yet.
but i think i will have some rewritten, cause i need to have the "rain" on display at normal readout, and the clock later in the selecting area.. hope u can understand my bad english.
 

t06afre

Joined May 11, 2009
5,934
Then RA2 is used as an interrupt pin it will be edge trigged. You can choose if you want to trig an interrupt on rising edge of RA2/INT pin, or Interrupt on falling edge of RA2/INT pin. Using an egde trigged interrupt is much more simple than polling a pin your case. All you have to do is to enable interrupt on RA2 pin and sett the correct edge. Well some programming is also needed. But I have shown you have to add an extra interrupt functionality in the interrupt service routine
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Then RA2 is used as an interrupt pin it will be edge trigged. You can choose if you want to trig an interrupt on rising edge of RA2/INT pin, or Interrupt on falling edge of RA2/INT pin. Using an egde trigged interrupt is much more simple than polling a pin your case. All you have to do is to enable interrupt on RA2 pin and sett the correct edge. Well some programming is also needed. But I have shown you have to add an extra interrupt functionality in the interrupt service routine
Will try again later today / tonight.
i works okay right now, just it counts with 1:2 ,
i my old days i made a very god debouncer, better that just the one cap..
Maybe i should go with that, it still counts many timer on each button press prell.JPG
 

t06afre

Joined May 11, 2009
5,934
As I said my design was only conceptual. The caps in debouncing circuit may be to small. And also software debouncing is possible. Just do as you self find it best, for your project.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Here is something that simply works.

Rich (BB code):
#include <htc.h>
//#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (FCMEN_ON & IESO_OFF & BOREN_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTRCIO);
#define LED RC0
#define set_hour RC4
#define set_minut RC5
#define set_week RC6
#define set_time RC3
#define _XTAL_FREQ  4000000
//global defs
volatile unsigned char week_day;
volatile unsigned char hour, minut, sec, mm;
volatile bit minut_tick, set_time_flag, regn_tick;
volatile bit blink;
const char * const day_of_week_names[] = {"Mandag ",
                                          "Tirsdag",
                                          "Onsdag ",
                                          "Torsdag",
                                          "Fredag ",
                                          "Lordag ",
                 "Sondag " 
                                         };

char timestr[3], regn[4];
static void interrupt
isr(void)   // Here is interrupt function - the name is unimportant.
{
 if(TMR1IF) 
  {// Was this a timer overflow?
      TMR1IF=0;//Clear interrupt flag, ready for next
   TMR1H=0x80;
        //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
      regn_tick=1;
   blink=!blink;
         LED=blink; 
         sec++;
  if (sec==2)
   {
   minut_tick=1;
  sec=0;
   }
 
     }//we are done here
}
void setup(void)
{   TRISA0=0;
    TRISA2=1;
    TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
    TRISB=0; //All port B output
 GIE = 0;  // Global interrupt disable just in case
 ANSEL=0;
 ANSELH=0;//turn off all analog functions
//timer1 settings
 TMR1H=0x80;
 TMR1L=0;
 //T1CON=0b00000110;//used during debug
    T1CON=0b00001110;
 // See datasheet REGISTER 6-1: T1CON: TIMER 1 CONTROL REGISTER
 // bit order T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN !T1SYNC TMR1CS TMR1ON
 //Timer1 Interrupt prepare
 TMR1IE=1;// PIE1 register
 PEIE=1; //INTCON register
 PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
   //todo now in order to generate interrupt GEI=1 and TMR1ON=1
//timer0 settings.
//INTCON=0b01100000;
 //setup LCD
    lcd_init();
 lcd_goto(0); // select first line
 //set the globals
week_day=5;
minut=0;
sec=0;
hour=0;
minut_tick=0;
blink=0;
regn_tick=0;//clear the tick
    }
void lcd_format_and_send(void)
{   
lcd_goto(0x08);
utoa(timestr, hour, 10);
 if (hour<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, minut, 10);
 if (minut<10)lcd_puts("0");
lcd_puts(timestr);
 lcd_goto(0x47); // Select second line
 for (unsigned char i=0;i<7;i++) lcd_putch(day_of_week_names[week_day]);
lcd_goto(0x00);
}
 
void midnat (void)
{
week_day++;
if (week_day==7) week_day=0;
lcd_format_and_send();
}
void vis_regn (void)
{
lcd_goto(0x00);
utoa(regn, TMR0, 10);
lcd_puts(regn);
lcd_goto(0x00);
}
void ur (void)
{
  
  minut++;
  if (minut>=60)
{   minut=0;
   hour++;
   if (hour>=24)
  { hour=0;
       midnat();
   }
}
 lcd_format_and_send();
}
void stil_ur (void)
{
 GIE = 0;  // Global interrupt disable as we are setting the time
 TMR1ON=0;       //timer1 off
 sec=0;
 TMR1H=0x80;
 TMR1L=0;
 LED=1;
 set_time_flag=1;
  do
   { 
    if (!set_hour)
                 {
                         hour++;
                  if (hour==24) hour=0;
                   lcd_format_and_send();
                  __delay_ms(200); 
                } 
    if (!set_minut)
               {
      minut++;
      if (minut==60) minut=0;
      lcd_format_and_send();
                   __delay_ms(200); 
               }    
    if (!set_week)
               {
      week_day++;
                  if (week_day==7) week_day=0;
                  lcd_format_and_send();
                 __delay_ms(200); 
                }    
         
    } while (!set_time);
 GIE = 1;  // Global interrupt enable
 TMR1ON=1;       //timer1 on
    set_time_flag=0;
}
 
void main (void) //hovedprogram
 { setup();
timestr[2]='\0';
lcd_format_and_send();
      GIE=1;
   TMR1ON=1;
TMR0=0;
       while (1)
         {
            if (minut_tick)
       { 
    ur();
    minut_tick=0; 
    }  // end if (minut_tick)
if (!set_time)
{
stil_ur();
}
if (regn_tick)
{
regn_tick=0;
vis_regn();
}
}
}
 // flere hvis.....
 //end while endless loop
//End main


It counts 1 pr input on RA2, just need to do something if TMR0 = 255 , cause it then will make an interrupt. with owerflow.
When i solder the cap good, it then works ok.
 

t06afre

Joined May 11, 2009
5,934
So it works that good to hear. About timer0. It will not create an interrupt unless you enable it The Timer0 interrupt enable is the T0IE bit of the INTCON register
T0IE: Timer0 Overflow Interrupt Enable bit
1 = Enables the Timer0 interrupt​
0 = Disables the Timer0 interrupt
After power on this bit default to 0
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
meaning it's not neasesarry to do anything, couse it will work as counter .
Any hints on making a sub routine that will run for approx 10 sec, if nothing is pressed. ?
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Here is my master plan. ;)
now it just need som coding :(

RC3 Set time.
RC4 Select / Set hour.
RC5 Reset / Set minut.
RC6 Yes / Weekday.

Normal only "set time" and "Select" and "reset" can be pushed.

Normal readout:
"Regn total : "xxx "MM".
"Regn Mandag : "xx "MM".

Select pressed.
First line remains.
"Regn Søndag : "xx "MM".
nothing pressed for 10 sec, it returns to "mandag"..
if pressed again before 10 sec.
"Regn Lørdag : "xx "MM".
Ect. until 7 days.

When pressed after those 7 days, readout will be
"Regn dag - 8 : "xx "MM".
ect to day -30
all will remain on LCD until 10 sec, or until next press on "select"
end of select.,

If "set time" is pressed.
Shift to read out:
"Stil ur : 00:00"
"Idag er "Mandag ".
and the clock can be altered.
if nothing pressed for 10 sec, return to normal.

IF "Reset" pressed,
Readout will be.
"Reset total ?"
"JA / NEJ"
nothing pressed in 10 sec, return to normal.
if "Yes / weekday" pressed,
"Nulstillet !!" for 3 sec. return to normal.

All data "Regn total" + Regn day0 - day-30 is stored in EEProm.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
will this be usefull little loop for 10 sec ?

Rich (BB code):
x=0;
while (x<100)
{if (!set_week) x=0;
__delay_ms(100);
x++;
}
remains in the loop for 10 sec, and if button pressed within 10 sec, it remains for 10 sec more.
When 10 sec is up, it exit loop and go back to "normal" readout.
 

t06afre

Joined May 11, 2009
5,934
I can not why not. The clock is controlled by interrupt. So the time keeping will be "served" with no interference.
By the way. I see you do not want to show the clock. You know that you can use the LCD goto function. To write something in the right corner of the display. Without overwriting the full content on the line.
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
i have nothing to use the clock for, so thats why it is not showing,
But showing by selecting it, still need it for midnight shift...
I can write to EEprom like "eeprom_write(31,TMR0);"
But i cant get i to work to read from it.
"x=eeprom_read(week_day);
What am i doing wrong ?

Here is code with error.
Rich (BB code):
x= eeprom_read(week_day);
 lcd_puts(x);
Here error msg.
Rich (BB code):
Error   [195] FroceMaster display demo_v2.c; 236.1 expression syntax
Error   [187] FroceMaster display demo_v2.c; 236.25 too few function arguments
Error   [194] FroceMaster display demo_v2.c; 236.25 ")" expected
Error   [195] FroceMaster display demo_v2.c; 236.25 expression syntax
Warning [357] FroceMaster display demo_v2.c; 237.11 illegal conversion of integer to pointer

Fixed.... :)
Rich (BB code):
x= eeprom_read(week_day);
utoa(regn, x, 10);
 lcd_puts(regn);
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Also made so it wont refresh LCD every second, can see it flashing a little.
But fixed by this way

Rich (BB code):
if (TMR0>mm);
{
lcd_clear();
lcd_goto(0x00);
lcd_puts("Regn Total  : ");
if (TMR0<100)lcd_puts(" ");
if (TMR0<10)lcd_puts(" ");
utoa(regn, TMR0, 10);
mm=TMR0;
eeprom_write(31,TMR0);
lcd_puts(regn);
lcd_puts(" MM");
and when returning from ex clock, it set mm to -1, so it will update when returning.
 

t06afre

Joined May 11, 2009
5,934
Would it not be more easy to put the LCD update. Inside the minute counter loop;)
Something like this
Rich (BB code):
void ur (void)
{
 
minut++;
if (minut>=60)
{ minut=0;
hour++;
if (hour>=24)
{ hour=0;
midnat();
}
lcd_format_and_send();
}
}
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
699
Was just now thinking the same, couse it do not work correct,
btw, how do i fix the daily counter , TMR0 is total counter.
is it something like, i store total i EE, at midnight, and the daily readout must then be
something like (totalrain - Stored at midnigt) = today ....
 

t06afre

Joined May 11, 2009
5,934
Was just now thinking the same, couse it do not work correct
Then you have probably not done it correct;) Most probably placed the LCD function in the wrong place
TMR0 is total counter.
is it something like, i store total i EE, at midnight, and the daily readout must then be
something like (totalrain - Stored at midnigt) = today ....
From the top of head. Do something like this then the day change. Here I have assumed that you have total rain data back log of seven days
Rich (BB code):
void rain_FIFO (void)
{ 
    unsigned char data;
    unsigned char target;
    for(target=6;target!=0;target--)
         {     
               data=EEPROM_READ(target-1);
                EEPROM_WRITE(target,data);
         }
    EEPROM_WRITE(0,TMR0);
 
}
 
Top