Calender/Time/Temperature using the Chronodot

hbl2013

Senior Member
Here is a Calender/Clock/Temperature display using the PICAXE 18M2 with the DS3231 based Chronodot. It does not have any provision to adjust the DS3231 because once you have programmed the correct data into it, it will keep track of the passage of time as long as the battery backup is connected.
The program has therefore two versions, one has a way of initially programming the DS3231, while the other does not, and is used to run the clock on a day by day basis. The selection is made by commenting out the statement that will prohibit the programming of the DS3231. (Line 79 of the program).
This means that you have to load the program twice, first to allow the Chronodot to be programmed, then the second time to run the program with the now programmed Chronodot. Hopefully you should not have to reset it untill your battery goes out. (abt 8 years)
The program is using parts of previously written snippets by other authors. Any comments are wellcome!

Code:
#rem

Display on a 16x2 LCD display the weekday, month, date,and year on 1st line
and time and temperature on the 2nd line using the Sparkfun LCD serial Adaptor.
Use the Chronodot DS3231 module as a time keeping device.

LCD display:
            ------------------
1st line   | THU,SEP 19  2013 |
           |                  |
2nd Line   | 11:46:23 A  78.5 |
            ------------------
            
(Re-arrange to display Date and 24H clock according to European Standards).            

PICAXE 18M2 Port assignments:

Program Serial OUT = C.3  -- Use standard circuit
Program Serial IN  = C.4  -- for this

I2C SCL            = B.3  -- connect to SCL Pin of Chronodot-Use 4K7 pull up resistor
I2C SDA            = B.4  -- connect to SCA Pin of Chronodot-Use 4K7 pull up resistor

Serial LCD output  = B.7


#endrem

'===============================================================

	SYMBOL LCD     = B.7  'LCD serial output
	
'-----------------------------		
	      
 SYMBOL chr1     = B2
	SYMBOL chr2     = B3
	SYMBOL chr3     = B4  
	SYMBOL chr4     = B5  
	SYMBOL chr5     = B6 
	SYMBOL chr6     = B7

	
	SYMBOL hrs      = B10
 SYMBOL mins     = B11
	SYMBOL secs     = B12
	SYMBOL wkday    = B13 
	SYMBOL date     = B14
	SYMBOL month    = B15
	SYMBOL year     = B16
	SYMBOL ampm     = B17
			
'-------------------------------
			
'Used only in Temp Display
	
	SYMBOL temp     = W4 'b9-b8
	SYMBOL TempMsb  = B9
	SYMBOL TempLsb  = B8

'------------------------------------------------------      

#picaxe 18M2
#no_data

setfreq M16

HI2Csetup I2Cmaster, %11010000, I2Cfast_16, I2Cbyte 

'----------------------------------------------------------------------------------

clr:													  	                 'Clear LCD Window Subroutine
serout LCD,T9600_16,($FE,$01)
pause 500							                     'needs some time to process

'----------------------------------------------------------------------------------

'Comment the following statement out if you want to set the clock.
 
goto version 
'----------------------------------------------------------------------

'Set the Chronodot here

let secs  = 0
let mins  = $39
let hrs   = $62  '41-52 =AM, 61-72 =PM (1-12) Use $0-$24 for 24HR clock and change AM/PM reading
let date  = $18 
let wkday = 4
let month = 9
let year  = $13

'prog time          (secs,mins,hours,day,date,month,year) ' hours AM 1-12 ($41 to $52) 
                                                          ' hours PM 1-12 ($61 to $72)  
Program:            
HI2Csetup I2Cmaster, %11010000, I2Cfast_16, I2Cbyte       ' set to 100kbps 
HI2Cout $0,( secs,mins ,hrs,wkday,date,month,year) ' write time to DS3231  example (11.58.00 PM)
HI2Cout 14, ($40)                                  ' control (turn off 1hz, =$0 )Pin3( and off $4)  

'-----------------------------------------------------

version:

serout LCD,T9600_16,($FE,$80," 18M2 Chronodot ")
pause 400
serout LCD,T9600_16,($FE,$C0,"  VERSION 1.0   ")
pause 15000

main:     

'Start with getting the Calender Data and Displaying it

HI2Cin $3,(wkday,date,month,year) 

'WEEKDAY

 	SELECT CASE wkday
          'cursor position12  line1
          
 '                            ($FE,$80,"0123456789ABCDEF")
 case $1 :serout LCD,T9600_16,($FE,$80,"SUN,")               
 case $2 :serout LCD,T9600_16,($FE,$80,"MON,")
 case $3 :serout LCD,T9600_16,($FE,$80,"TUE,")
 case $4 :serout LCD,T9600_16,($FE,$80,"WED,")
 case $5 :serout LCD,T9600_16,($FE,$80,"THU,")
 case $6 :serout LCD,T9600_16,($FE,$80,"FRI,")
 case $7 :serout LCD,T9600_16,($FE,$80,"SAT,")

      ENDSELECT

'-----------------------------------------------------------------------      

'MONTH
           
SELECT CASE month:

 '                            ($FE,$84,"456789ABCDEF")
 case $1 :serout LCD,T9600_16,($FE,$84,"JAN ")            
 case $2 :serout LCD,T9600_16,($FE,$84,"FEB ")
 case $3 :serout LCD,T9600_16,($FE,$84,"MAR ")
 case $4 :serout LCD,T9600_16,($FE,$84,"APR ") 
 case $5 :serout LCD,T9600_16,($FE,$84,"MAY ")
 case $6 :serout LCD,T9600_16,($FE,$84,"JUN ") 
 case $7 :serout LCD,T9600_16,($FE,$84,"JUL ") 
 case $8 :serout LCD,T9600_16,($FE,$84,"AUG ") 
 case $9 :serout LCD,T9600_16,($FE,$84,"SEP ") 
 case $A :serout LCD,T9600_16,($FE,$84,"OCT ") 
 case $B :serout LCD,T9600_16,($FE,$84,"NOV ") 
 case $C :serout LCD,T9600_16,($FE,$84,"DEC ")
      ENDSELECT

'CALENDER
  
 BCDTOASCII date,chr1,chr2
 BCDTOASCII year,chr3,chr4
   
'Suppress leading zero of Date
   
  if chr1 = "0" then goto disply_date
   goto disply_date1
disply_date:
   serout LCD,T9600_16,(" ",chr2,",","20",chr3,chr4) 'Like "TUE,SEP 9,2013" on first line  

'No leading zero here
      
disply_date1:   
   serout LCD,T9600_16,(chr1,chr2,"  ","20",chr3,chr4) 'Like "TUE,SEP 29,2013" on first line 

'===========================================================================================

'Now get the Time and display it 

HI2Cin $0,(secs,mins,hrs)
 
ClockDisplay:
     LET hrs = hrs - $40 :ampm = "A"                              ' 12 hour format   AM 
     IF hrs > $20 THEN : LET hrs = hrs - $20 : ampm ="P": ENDIF ' 12 hour format   PM 
    
   BcdTOASCII hrs,chr1,chr2 : IF chr1 = "0" THEN : chr1 = " " : ENDIF ' zero blanking chr1
   BcdTOASCII mins ,chr3,chr4
   BcdTOASCII secs ,chr5,chr6

'Now display the Time on 2nd Line
  
serout LCD,T9600_16,($FE,$C0)
serout LCD,T9600_16,(chr1,chr2,":",chr3,chr4,":",chr5,chr6," ",ampm," ") '(12:00:01 A)

'--------------------------------------------------------------------------------------------       
   
'Now the get the Temperature 

HI2Cin $11,(TempMsb,TempLsb) 	 
  
Convert: temp = temp +14080 **46080 -6700                  
            
         LET chr1 = " " ' chr1 (Sign) Display +
        
         IF TempMsb > 127 THEN : temp = - temp : LET chr1 = "-" : ENDIF ' chr1 (Sign) Display "-"

'Now display the temperature in Fahrenheit              
'(We do not display the Temp in the .01 ( 1/100th - chr5) place (No Room)  
                
Display: BinTOASCII temp,chr1,chr2,chr3,chr4,chr5         ' 101.25
               IF chr1 = "0" THEN : chr1 = " "            ' zero blanking 
               IF chr2 = "0" THEN : chr2 = " " : ENDIF    ' zero blanking 
               ENDIF

  serout LCD,T9600_16,(chr1,chr2,chr3,".",chr4) '101.6 or -10.4 (F)

    
goto main


'-------------------------------------------------------------------------

end
 
Last edited:

hippy

Technical Support
Staff member
You have to load the program twice, first to allow the Chronodot to be programmed, then the second time to run the program with the now programmed Chronodot. Hopefully you should not have to reset it untill your battery goes out. (abt 8 years)
Though it seems you would have to reprogram it twice a year if you want to cater for DST.

It should be possible to add code to get it to display +0 or +1 times so the DS3231 itself does not have to be adjusted and it then won't need reprogramming.

Using an EEPROM marker you should be able to create a program that sets the clock after download yet never sets it again after further power losses. That way you only have one download to do.

Code:
Eeprom 0, (0)

PowerOnReset:
  Read 0, b0
  If b0 = 0 Then
    ' Set clock
    Write 0, 1
  End If
A simple trick to help keep clocks accurate after the initial time programming is to have a single 'reset to nearest hour' button. That saves having to be accurate when you hit the download button and every now and again you can then sync it to a time signal if it is drifting.
 

hbl2013

Senior Member
hippy - Thanks for your comments. For some reason, I never even considered the twice a year time change, possibly because I naively thought that the DS3132 took care of it automatically. Off course, a quick glance at its specs will reveal that it does not. Thus, as you pointed out, my statement of never having to re-program the Chronodot was incorrect. In my program, you do have to re-program the Chronodot twice a year to take care of these time changes.
I do not quite understand the little program you show as how to solve this this problem. Can you elaborate more on it
for I like the idea of automatically adjusting the time change. Also, I read something in the spec sheet about the calibrating the time generator in the chip, but do not quite get how to do it.

Some thoughts as to expand on the program - by using two LCDs or using a 4 Line LCD, you could include a kind of message center using the EEPROM in the chip. In that way you could display any important dates, such as anniversaries or birthdays, when displaying the Calender information. I was thinking here only about events that do not change, so that re-programming is not needed on a regular basis.
This might need a more powerfully X2 type PICAXE to accomplish. Something to do in the future.
 

hippy

Technical Support
Staff member
The example code above was only for pre-setting the start date and time and then running normally. That saves having to download one program to set time, edit it, and download again. It initialises the RTC immediately after download but never again, so just one download.

Determining DST is a bit complicated because it doesn't have fixed dates and times, it's usually a particular day, for UK the last Sunday of March, last Sunday of October. You need to work out which day number those days fall on. There's some example code which can be had here -

http://www.picaxeforum.co.uk/showthread.php?18468-DS1307-RTC-with-GMT-BST-auto-adjustment
 

MPep

Senior Member
Another way would be to toggle a switch (physical). Then you either add 1 hour, or you don't.
 

techElder

Well-known member
hbl2013, the PICAXE is a computer. Why don't you let it compute?

Add some switches like every other clock has.

If you can program what you have, you can program something even more useful.
 

hbl2013

Senior Member
hbl2013, the PICAXE is a computer. Why don't you let it compute?

Add some switches like every other clock has.

If you can program what you have, you can program something even more useful.
In my first attempt to write this program, I considered adding switches to set the Chronodot, but decided to publish the simplest program to get the project going, and see what others would suggest. I see that indeed, it generated some useful comments, which I intend to pursue.
In regard of programming the Chronodot, I have been working on a way to add a programming button using an Interrupt routine. In that way I can write the programming section independent of the rest of the program, and since the Chronodot keeps track of the time, it can take as long as it takes without having to worry about the existing data that you do not want to have changed with this routine.

hippy- Will use your starting code to set the Chronodot in next version, and I agree that the change in time is somewhat more complicated. That is why the suggestion by MPep is appealing, push a button to either add or subtract an hour. Simple, but effective.
 

hippy

Technical Support
Staff member
I agree that the change in time is somewhat more complicated. That is why the suggestion by MPep is appealing, push a button to either add or subtract an hour. Simple, but effective.
That's a good option. If you have two buttons ( -1 and +1 ) you can activate on release rather than push so that also caters for pushing both to sync to the nearest hour if you want to have that as well.

Alternatively you can have both pushed together take you into a data and time setting mode once both released. Once in that mode you could use one button to step round the parts ( year, month, day, etc ) and the other button incrementing the value.

One good suggestion - and apologies for forgetting who it came from - was to add an IR reciever and use an IR remote to adjust and set the time.

That all adds additional code so you may not want to do all that but the option is there if you do want to turn it into a bigger or more comprehensive project.
 
Top