20X2 LED ClOCK 4 DIGIT 7 SEGMENT with DS1307 and DS18B20

marks

Senior Member
Clocks
uses a ds1307 to keep acurate time updates every minute
and a ds18b20 to read temperature.(cause every1 seems to have em)

temp will be displayed every minute for 14 secs approx
at the half minute mark
and then update time from the ds1307
pm time will be displayed in 12hr format

push the button to program ds1307
push to select hours 1 to 24

ie if your want 10.
push to select 9.
push and hold to get 10. then will jump to minutes 00

push to select 29
push and hold on 30 will display last digit 0
when you release clock starts at 10.30

Code:
	'             -- --   -- --   -- --   -- --
	' B0-A       |     | |     | |     | |     |
	' B1-B	
	' B2-C       |     | |     | |     | |     |
	' B3-D        -- --   -- --   -- --   -- --
	' B4-E       |     | |     | |     | |     |
	' B5-F
	' B6-G       |     | |     | |     | |     |
	' B7-dp       -- --   -- -- o -- --   -- --   
	'
	'Display        1       2       3       4
	'Common anode  C.3     C.2     C.1     c.0
                                      
eeprom 0,(192,249,164,176,153,146,130,248,128,144,255)     'Display (0,1,2,3,4,5,6,7,8,9,blank)
let dirsb = %11111111
let dirsc = %00111111

main:
let b31= bcdtobin b31                                      'sec
let  w3= bcdtobin b32 * 60                                 'min
let b33= bcdtobin b33                                      'hrs
 
if b33>12 then 
let w4= b33 -12*3600+w3+b31                                'pm
else                    
let w4= b33 *3600+w3+b31                                   'am 
endif

SETTIMER T1S_8           
 
let timer = w4                                             'up date time from ds1307 every minute 

clock:

 w1=Timer/3600                                             'time hours                                             
 
 w2=Timer//3600/60                                         'time minutes
  
 b34=timer//3600//60                                       'time seconds
 
high c.0                  
b0=10  : if w1 < 10 then dig1                              'Zero blanking
let b0 = w1 dig 1
Dig1: read b0,b11
  if pinc.6 = 1 then hours                                 'program time
  if b34=30 then temp                                      'display temp at 30 secs
 	           let pinsb = b11 : low c.3 : pause 1       'Display1 

let b0 = w1 dig 0	                                          
Dig2: read b0,b12 : let b12=b12-128                        'with d.p
	high c.3 : let pinsb = b12 : low c.2 : pause 1       'Display2 	
	
let b0 = w2 dig 1			
Dig3: read b0,b13 : let b13=b13-0                          '
	high c.2 : let pinsb = b13 : low c.1 : pause 1       'Display3
		
let b0 = w2 dig 0	                                                              
Dig4:read b0,b14  : let b14=b14-0                          '
	high c.1 : let pinsb = b14 : low c.0 : pause 1       'Display4 

goto clock
                              
Hours:w1=0
hrs:w20=0
Ho:  
b0=10  : if w1 < 10 then dig11                           'Zero blanking
let b0 = w1 dig 1
dig11: read b0,b11
high c.2 : let pinsb = b11 : low c.3 : pause 1           'Display1 
high c.1  :  high c.0
let b0 = w1 dig 0	                                         
 read b0,b12 : let b12=b12-128                           'with d.p

high c.3 : let pinsb = b12 : low c.2 : pause 1           'Display2
		 
if pinc.6=0 then hrs                                     'reset ready for next count
 
let w20=w20+1 
if w20 > 200 then Minutes                                'hold to goto Minutes                                              
if w20 > 1 then ho                                       'ignores button bounce

let w1=w1+1                                              'Add count by 1 
if w1=25 then hours                                      'Reset after 24 reached
goto ho

Minutes:w2=65535                                          ' start at 0 
mins:w21=0                                                
Mi:  	
let b0 = w2 dig 1			
 read b0,b13
	high c.0 : let pinsb = b13 : low c.1 : pause 1      'Display3
high c.3  :  high c.2	
let b0 = w2 dig 0	                                                              
 read b0,b14
	high c.1 : let pinsb = b14 : low c.0 : pause 1      'Display4 

if pinc.6=0 then mins                                     'reset ready for next count

let w21=w21+1
if w21 > 200 then prog                                    'hold to goto prog
if w21 > 1 then Mi                                        'ignores button bounce
                                         
let w2=w2+1                                               'Add count by 1 
if w2=60 then minutes                                     'Reset after 59 reached
goto Mi

prog:	                                     
 if pinc.6 = 1 then prog                                   'release to program 
 
 let b32= bintobcd w2
 let b33= bintobcd w1
 
 	hi2csetup i2cmaster, %11010000, i2cslow_8, i2cbyte    'prog time ds1307
	hi2cout 0, ($00, b32, b33, $03, $07, $05, $10, $10)   '(seconds,mins,hour,day,date,month,year,control)
goto prog1
	
temp: 
readtemp c.7,w1
let dirsb = %11111111                                       'read temp turns off b3 pin (restore pinsb)
	
for w14=1 to 1000                                           'display temp time about 14secs
let b0 = w1 dig 1
 read b0,b11	
 	  let pinsb = b11 : low c.3 : pause 1 : high c.3      'Display1    temp

let b0 = w1 dig 0	                                          
 read b0,b12 
	  let pinsb = b12 : low c.2 : pause 1 : high c.2      'Display2    temp
			
        let pinsb = 156 : low c.1 : pause 1 : high c.1      'Display3    o
        
        let pinsb = 198 : low c.0 : pause 1 : high c.0      'Display4    C
next w14
	
prog1:
 	hi2csetup i2cmaster, %11010000, i2cslow_8, i2cbyte     
hi2cin 0,(b31,b32,b33)                                      'read time ds1307
HI2cSetup OFF  
let dirsb = %11111111                                       'hi2c  leaves b5 b7 pins high (restore pinsb)
goto main
 

Attachments

Last edited:

marks

Senior Member
allways looking at improving code
ideas Welcome !!!

Code updated no longer writes to memory and resets
 
Last edited:

SAborn

Senior Member
As for improving code.

My biggest gripe with code posted on this forum is the distinct lack of using symbols and the lazy method of using straight variables b1..b2..w0... drives me insaine at reading someone elses jibber in code.

What ever happened to the standard practice of declearing variables with symbols?

Even the author of the codes will find it of great use in time to come, when a change is needed, as it saves a lot of time trying to workout what the hell it was you were trying to do where.

The whole beauty of using symbols, is code can read as a form of English and makes it so easy to understand and follow.

I personally see it as a lazy and bad coding practice without using symbols.

This is nothing personal against you or your code, but you did ask about improving your code, and if you used symbols i would bother to read your code.
 

westaust55

Moderator
As for improving code.

My biggest gripe with code posted on this forum is the distinct lack of using symbols and the lazy method of using straight variables b1..b2..w0... drives me insaine at reading someone elses jibber in code.

What ever happened to the standard practice of declearing variables with symbols?

The whole beauty of using symbols, is code can read as a form of English and makes it so easy to understand and follow.
Don't disagree with you SAb.

but . . .
"the standard practice of declearing variables"

That was the practice when people were formally taught programming.
However a great many here just buy a PICAXE chip and start playing.
Many do not even read the manuals thoroughly. Manual 1 Tutorial 2 covers Symbols, Comemnts and White-Space albeit briefly.

Most do not even read the sticky post at the start of the forum about etiquette such as the use of the [code] and [/code] markers.

My own scheme whch I endeavour to adhere to for my own code is:

All commands and keyworks/parameters (SYMBOL, READ, I2CFAST, etc) in capitals
All Labels start with a capital and lowercase thereafter (Main:, Init:, etc)
All variables generally in lowercase. (SYMBOL temperature = b1)

But getting a message to the masses is exceedingly difficult.
 
Last edited:

marks

Senior Member
Blimey I feel like a naughty sckool boy
never was good at english was always better doing maths.

have updated code tho i find symbols makes it a lot harder to read and understand myself
I know its not upto the queens english but hey i tried!
I just hope that Westy and Hippy can still pickup the occasssional code tweak.

have know used owin for the temp reads every minute
will show to 1 decimal point 23.1 c _
and if minus there will be a dash above the c

Code:
	'              -- --   -- --   -- --   -- --
	'B.0-A        |     | |     | |     | |     |        Picake  20x2  ver C.0
	'B.1-B	
	'B.2-C        |     | |     | |     | |     |        marks
	'B.3-D         -- --   -- --   -- --   -- --
	'B.4-E        |     | |     | |     | |     |
	'B.5-F                                               'B.5  SDA -- ds1307
	'B.6-G        |     | |     | |     | |     |
	'B.7-dp        -- --   -- -- o -- --   -- --         'B.7  SCL -- ds1307
	'
	'Display         1       2       3       4           'C.7  Ds18b20  
	'Common anode   C.3     C.2     C.1     c.0          'C.6  Pushbutton
	
	
	SYMBOL pushbutton    = PINC.6
	SYMBOL ds18b20       = C.7
	SYMBOL pushresponse  = B9
	SYMBOL hours         = B10
	SYMBOL mins          = B11
	SYMBOL secs          = B12
	SYMBOL date          = B14
	SYMBOL month         = B15
	SYMBOL year          = B16
	SYMBOL segmentvalue  = B18
	SYMBOL degrees       = B19
	SYMBOL temperature   = W1  
	SYMBOL updatetime    = W10 
	SYMBOL totalminutes  = W11 
	SYMBOL displayedtime = W12 
      
                                            
	EEPROM 0,(192,249,164,176,153,146,130,248,128,144,255)     'Segment Value (0,1,2,3,4,5,6,7,8,9,blank)
	LET dirsb = %11111111
	LET dirsc = %00111111
	secs = 31 GOTO dig1

    Main:
	LET secs = BCDTOBIN secs                                   'Time from ds1307 needs converting  
	LET totalminutes = BCDTOBIN mins * 60                                 
	LET hours = BCDTOBIN hours                                      
 
	IF hours > 12 THEN 
	LET updatetime = hours - 12 * 3600 + totalminutes + secs   'pm  
	ELSE                    
	LET updatetime = hours * 3600 + totalminutes + secs        'am 
	ENDIF

	SETTIMER T1S_8           
 
	LET TIMER = updatetime                                     'up date time from ds1307 every minute 

    Clock:

 	hours = TIMER /3600                       
 
 	mins  = TIMER //3600/60                                         
  
 	secs  = TIMER //3600//60                                       
 
   	 HIGH c.0                  
	b0=10  : IF hours < 10 THEN dig1                                        'Zero blanking
	LET b0 = hours DIG 1
    Dig1: READ b0,segmentvalue
  	IF pushbutton = 1 THEN hour                                           'program time
  	IF secs = 31 THEN temperatureread                                     'display temp at 30 secs
 	     	   		LET pinsb = segmentvalue       : LOW c.3 : PAUSE 1       'Display1 

	LET b0 = hours DIG 0	                                          
    Dig2: READ b0,segmentvalue 
      LET segmentvalue = segmentvalue - 128                             'with d.p
  	     	HIGH c.3 :  LET pinsb = segmentvalue       : LOW c.2 : PAUSE 1       'Display2 	
	
	LET b0 = mins DIG 1			
    Dig3: READ b0,segmentvalue
      LET segmentvalue = segmentvalue - 0                    
 	 	HIGH c.2 :  LET pinsb = segmentvalue       : LOW c.1 : PAUSE 1       'Display3
		
	LET b0 = mins DIG 0	                                                              
    Dig4:READ b0,segmentvalue  
      LET segmentvalue = segmentvalue - 0                   
  		HIGH c.1 : LET pinsb = segmentvalue        : LOW c.0 : PAUSE 1       'Display4 

	GOTO clock
                              
    Hour:hours=0
    Hrs:pushresponse=0
    Ho:  
		b0=10  : IF hours < 10 THEN dig11                                       'Zero blanking
      	 LET b0 = hours DIG 1
		dig11: READ b0,segmentvalue
	HIGH c.2 : let pinsb = segmentvalue : LOW c.3 : PAUSE 1                 'Display1 
	HIGH c.1  :  HIGH c.0
	LET b0 = hours DIG 0	                                         
	       READ b0,segmentvalue 
 	      LET segmentvalue = segmentvalue - 128                                  'with d.p
	HIGH c.3 : LET pinsb = segmentvalue : LOW c.2 : PAUSE 1                 'Display2
		 
	IF pushbutton = 0 THEN hrs                                              'reset ready for next count
	 
	LET pushresponse = pushresponse + 1 
 	if pushresponse > 200 THEN Minutes                                     'hold to goto Minutes   
 	if pushresponse > 1 THEN ho                                            'ignores button bounce

	LET hours = hours + 1                                                   'Add count by 1 
	IF  hours = 25 THEN hour                                                'Reset after 24 reached
	GOTO ho
	
    Minutes:mins=255                                                        ' start at 0 
    Mns:pushresponse=0                                                
    Mi:  	
	LET b0 = mins DIG 1			
	 READ b0,segmentvalue
		HIGH c.0 : LET pinsb = segmentvalue : LOW c.1 : PAUSE 1           'Display3
	HIGH c.3  :  HIGH c.2	
	LET b0 = mins DIG 0	                                                              
	 READ b0,segmentvalue
		HIGH c.1 : LET pinsb = segmentvalue : LOW c.0 : PAUSE 1           'Display4 

	IF pushbutton = 0 THEN mns                                              'reset ready for next count

	LET pushresponse = pushresponse + 1
	 IF pushresponse > 200 THEN program                                     'hold to goto prog
	 IF pushresponse > 1 THEN Mi                                            'ignores button bounce
                                         
	LET mins = mins + 1                                                     'Add count by 1 
	IF mins = 60 THEN minutes                                               'Reset after 59 reached
	GOTO Mi
	
    Program:	                                     
 	IF pushbutton = 1 THEN program                                         'release to program 
 
 	LET  mins = BINTOBCD mins
 	LET hours = BINTOBCD hours
 
 	HI2CSETUP I2CMASTER, %11010000, I2CSLOW, I2CBYTE                'prog time ds1307
	HI2COUT 0, ($00, mins, hours, $03, $07, $05, $10, $10)   '(seconds,mins,hour,day,date,month,year,control)
	GOTO program1
	
    Temperatureread: 
	OWOUT ds18b20,%1001,($CC,$44)                                        'reset(send skip rom ,send convert t)
	degrees = 167                                                        'temp positive     c
	OWOUT ds18b20,%0001,($CC,$BE)                                        'reset(send skip rom ,send read lsb msb)
	OWIN  ds18b20,%0000,(b2,b3)                                          'read in result 
 
	IF temperature => 2048 THEN                                    
	temperature = temperature + 2048
	temperature = 2048 - temperature * 5/8                               '                 _
	degrees = 166                                                        'temp negative    c
	ELSE
	temperature = temperature* 5/8
	ENDIF      
  
	LET dirsb = %11111111                                                'restore b pins after read
  	
	FOR displayedtime = 1 TO 1000                                        'display temp time about 14secs
	LET b0 = temperature DIG 2
	 READ b0,segmentvalue	
 	  LET pinsb = segmentvalue : LOW c.3 : PAUSE 1 : HIGH c.3      'Display1    temp

	LET b0 = temperature DIG 1	                                          
 	READ b0,segmentvalue
	 LET segmentvalue = segmentvalue - 128                               'd.p
	  LET pinsb = segmentvalue : LOW c.2 : PAUSE 1 : HIGH c.2      'Display2    temp
	  
	LET b0 = temperature DIG 0
 	READ b0,segmentvalue	
        LET pinsb = segmentvalue : LOW c.1 : PAUSE 1 : HIGH c.1      'Display3    temp
        
        LET pinsb = degrees      : LOW c.0 : PAUSE 1 : HIGH c.0      'Display4    c
	NEXT displayedtime
	
    Program1:
	 	HI2CSETUP I2CMASTER, %11010000, I2CSLOW, I2CBYTE     
	HI2CIN 0,(secs,mins,hours)                                           'read time ds1307
	HI2CSETUP OFF  
	LET dirsb = %11111111                                                'hi2c  leaves b5 b7 pins high (restore pinsb)
	GOTO main
 

Attachments

Last edited:

westaust55

Moderator
A few readability suggestions and a possible optimisation


add some more symbols at the top such as:
SYMBOL digit1 = C.3
SYMBOL digit2 = C.2
SYMBOL digit3 = C.1
SYMBOL digit4 = C.0

then for a line such as:
HIGH c.3 : LET pinsb = segmentvalue : LOW c.2 : PAUSE 1 'Display2​
can be written
HIGH digit1 : LET pinsb = segmentvalue : LOW digit2 : PAUSE 1 'Display2​

although it does not save any program space, you can write:
LET pushresponse = pushresponse + 1​
as:
INC pushresponse​


next, for the line:
LET segmentvalue = segmentvalue - 128 'with d.p​
modifying as:
LET segmentvalue = segmentvalue AND $7F 'with d.p​
IMHO makes it clearer that you are trying to mask of bit 7

for a line such as:
degrees = 167
can be more readable as:

SYMBOL pos_C_sign = 167 (put this at the top
degrees = pos_C_sign​


now a potential code optimisation (untested within your code):

instead of:


degrees = 167
IF temperature => 2048 THEN
temperature = temperature + 2048
temperature = 2048 - temperature * 5/8 ' _
degrees = 166 'temp negative c
ELSE
temperature = temperature* 5/8
ENDIF​

try
degrees = 167 ;or better as degrees = pos_C-sign
IF temperature > $8000 THEN ; temperature is negative
degrees = 166 ; or better degrees = neg_C_sign
temperature = - temperature
ENDIF
temperature = temperature* 5/8​

(was in fact testing the temp = -temp concept out myself last night in lieu of temp = temp ^$FFFF + 1 as a simplier method for two's compliment)
 
Last edited:

SAborn

Senior Member
It is great you bothered to rewrite your code, and it do read much clearer IMHO.

Your program is reasonably short compared to some you might do in the future, and after a few pages of raw variables used it becomes a night mare.

I hope you saved a copy before you added the symbols, as i would like you to go back and read through it in a year or two and then read the new version with symbols and see what makes sense.

As for Westys, use of hex in code i dont totally agree, To me is a pain in the ass, only because i am not fluent in hex and feel we all understand decimal.

Maybe i should get up to speed on hex but its hard teaching this old dog new tricks, and needing to reach for the calculator to view some code if excessive programming to me.

Hex might look neat but so do Chinese and i aint no good at that either.

Keep up the good work, and only wish others followed you lead.
 

marks

Senior Member
Hi all again thanks for the comments..
dam after i posted and then read your post westy had to change my commands t0 upercase lol

I do find it hard to think in hex i guess for big numbers like 2048
$8000 is a lot easier especially if 1 had a chart lol
lots of scribble on paper easy to rub out

=> iguess i dont need the -0 lol

i like your =- idea

never could get the AND $7F to work I think AND NOT $80 works
i guess i could use the AND b1 if i wanted to change it mm thnkin does make it hurt lol
do you think its made it easier to read lol
 

ValueAdd

Senior Member
I do find it hard to think in hex i guess for big numbers like 2048
$8000 is a lot easier especially if 1 had a chart lol

do you think its made it easier to read lol
Don’t mention “chart” or westy will whip up another of his tables

Oh no, I sense it is already too late . . .
 

BeanieBots

Moderator
When it comes to 'thinking' with numbers, the human decimal system is almost meaningless. Numbers within a micro are layout as a series of 1' and 0's --- binary.
Hex reperesentation is a convienient way of expressing both the number and the way it is actually constructed with 1's and 0's.

So, YES, hex DOES make it MUCH easier to read.
Binary representaion can also be very usefull for making things clearer.
 

westaust55

Moderator
I concur with BB.

If for example I want to extract out the state of just bit6 from a byte ;
then at the binary level AND with %01000000 (%0100 0000)
in hexadecimal that is AND with $40 where the 4 is the high nybble = %0100 and the 0 is the low nybble = %0000


but to use the decimal notation the I must AND with decimal 64
there is no immediate clear correlation that the 64 relates to bit6 of a byte
for most newer programmers and likely many old hands as well.

flipping back and forth between binary and hex values even with very large numbers (eg 32 bit or even more) becomes second nature when you understand the notation format.


And, I promise not to create any further number conversion charts - there is already one in the miscellaneous area. :)
 
Last edited:

hippy

Ex-Staff (retired)
I agree wholeheartedly with westaust55 on the convenience of hexadecimal representation of binary, especially when dealing with large number of bits. For example, where's the "1" in this, needed to determine the value in decimal or hex ... ?

w0 = %000010000000000

You cannot determine it easily without counting bits and that's an inconvenince, takes time and is error prone; w0 = $0400 is so much easier.
 

westaust55

Moderator
@Marks,

certainly not a complaint - just a thought.

As you are looking for feedback and ideas on code optimisation you could
consider posting in the active area initially and once you have ideas and fine tuned you project then post in the complete projects area. That way your prime project post is not lost in a trail of ongoing commentary.
 
I built this circuit over the weekend, and it worked perfectly on my first powerup. Thanks so much, Marks, for the code.

I'm wondering how the segment values in the line:
EEPROM 0,(192,249,164,176,153,146,130,248,128,144,255)
Create the digits 0-9. I can't seem to figure this out.

I'd like to modify the code to display °F, so I'd like "F" in the 4th digit rather than C. I think I can handle the math conversion based on some of Marks' other code postings.

In the states, we still think in terms of degrees F.

Thanks again for this brilliant project. I did not know about multiplexing LED displays.

Cheers,
Brian
 

hippy

Ex-Staff (retired)
I'm wondering how the segment values in the line:
EEPROM 0,(192,249,164,176,153,146,130,248,128,144,255)
Create the digits 0-9. I can't seem to figure this out.
This is a case where hex and particularly binary notation can help. Convert the decimal values to binary and then match the bits with the output connections to the 7-seg display. You will likely see that a bit is on to turn a particular segment on; which segments are lit will determine what the display shows.
 

marks

Senior Member
HI,and thanks for trying my code
its great you got it to work and no problems did you try the blue leds lol
i will up date my code when i get a chance hope this helps
marks

Code:
'       Common anode        MARKS
'                                                                               b7    b6    b5    b4    b3    b2    b1    b0

'                                                                               d.p    g     f     e     d     c     b     a

'                                                                               128    64    32    16    8     4     2     1

'     pinsb =(value determines whats displayed   255  Clear display    (   )     1     1     1     1     1     1     1     1 
   
'                                                  0  full display     ( 8.)     0     0     0     0     0     0     0     0
 
'                                                192                   ( 0 )     1     1     0     0     0     0     0     0

'                                                249  will display     ( 1 )     1     1     1     1     1     0     0     1

'                                                164                   ( 2 )     1     0     1     0     0     1     0     0

'                                                176  will display     ( 3 )     1     0     1     1     0     0     0     0

'                                                153                   ( 4 )     1     0     0     1     1     0     0     1

'                                                146  will display     ( 5 )     1     0     0     1     0     0     1     0

'                                                130                   ( 6 )     1     0     0     0     0     0     1     0

'                                                248  will display     ( 7 )     1     1     1     1     1     0     0     0

'                                                128                   ( 8 )     1     0     0     0     0     0     1     1

'                                                144  will display     ( 9 )     1     0     0     1     0     0     0     0

'                                                255  clear display    ( 0 )     1     1     1     1     1     1     1     1
        '                    a
	'                  -- --  
	' B0-A  ( 1 )     |     | 
	' B1-B  ( 2 )    f       b
	' B2-C  ( 4 )     |  g  | 
	' B3-D  ( 8 )      -- --   
	' B4-E  ( 16)     |     | 
	' B5-F  ( 32)    e       c
	' B6-G  ( 64)     |  d  | 
	' B7-dp (128)      -- --  o 
	
	' adding all the numbers up turns of all segments
	' if we want to display a  (F)   we turn off segments (  b   c   d    dp )   add values
      '                                            example    (  2 + 4 + 8 +  128)  = 142
 
Last edited:

marks

Senior Member
Hi all, i quickly modded this program i had on pc so should do 0-257 Fahrenheit .
it not a newy yet lol.
Code:
	'              -- --   -- --   -- --   -- --
	'B.0-A        |     | |     | |     | |     |        Picake  20x2  ver C.0
	'B.1-B	
	'B.2-C        |     | |     | |     | |     |        marks
	'B.3-D         -- --   -- --   -- --   -- --
	'B.4-E        |     | |     | |     | |     |
	'B.5-F                                               'B.5  SDA -- ds1307
	'B.6-G        |     | |     | |     | |     |
	'B.7-dp        -- --   -- -- o -- --   -- --         'B.7  SCL -- ds1307
	'
	'Display         1       2       3       4           'C.7  Ds18b20  
	'Common anode   C.3     C.2     C.1     c.0          'C.6  Pushbutton
	
	SYMBOL ds18b20       = C.7
	SYMBOL pushbutton    = PINC.6
	SYMBOL display6      = C.5
	SYMBOL display5      = C.4
	SYMBOL display1      = C.3     
	SYMBOL display2      = C.2
	SYMBOL display3      = C.1
	SYMBOL display4      = C.0
	SYMBOL output0       = A.0
	
	SYMBOL pushresponse  = B9
	SYMBOL hours         = B10
	SYMBOL mins          = B11
	SYMBOL secs          = B12
	SYMBOL date          = B14
	SYMBOL month         = B15
	SYMBOL year          = B16
	SYMBOL segmentvalue  = B18
	SYMBOL digit4        = B19
	SYMBOL temperature   = W1  ' note if changing  ( b2,b3 ) change in Temperatureread. 
	SYMBOL updatetime    = W10 '(b20,b21)
	SYMBOL totalminutes  = W11 '(b22,b23)
	SYMBOL displayedtime = W12 '(b24,b25)
      
                                            
	EEPROM 0,(192,249,164,176,153,146,130,248,128,144,255)     'Segment Value (0,1,2,3,4,5,6,7,8,9,blank)
	LET dirsb = %11111111
	LET dirsc = %00111111
	GOTO program1
	
    Main:
	LET secs = BCDTOBIN secs                                   'Time from ds1307 needs converting  
	LET totalminutes = BCDTOBIN mins * 60                                 
	LET hours = BCDTOBIN hours                                      
 
	IF hours > 12 THEN 
	LET updatetime = hours - 12 * 3600 + totalminutes + secs   'pm  
	ELSE                    
	LET updatetime = hours * 3600 + totalminutes + secs        'am 
	ENDIF

	SETTIMER T1S_8           
 
	LET TIMER = updatetime                                     'up date time from ds1307 every minute 

    Clock:

 	hours = TIMER /3600                       
 
 	mins  = TIMER //3600/60                                         
  
 	secs  = TIMER //3600//60                                       
 
   	 HIGH c.0                  
	b0=10  : IF hours < 10 THEN dig1                                           'Display1 Zero blanking
	LET b0 = hours DIG 1
    Dig1: READ b0,segmentvalue
  	IF pushbutton = 1 THEN hour                                                'program time
  	IF secs = 31 THEN temperatureread                                          'display temp at 30 secs
 	     	   		LET pinsb = segmentvalue       : LOW c.3 : PAUSE 1       'Display1 

	LET b0 = hours DIG 0	                                          
    Dig2: READ b0,segmentvalue 
      LET segmentvalue = segmentvalue - 128                                      'Display2 with d.p
  	     	HIGH c.3 :  LET pinsb = segmentvalue       : LOW c.2 : PAUSE 1       'Display2 	
	
	LET b0 = mins DIG 1			
    Dig3: READ b0,segmentvalue
      LET segmentvalue = segmentvalue - 0                    
 	 	HIGH c.2 :  LET pinsb = segmentvalue       : LOW c.1 : PAUSE 1       'Display3
		
	LET b0 = mins DIG 0	                                                              
    Dig4:READ b0,segmentvalue  
      LET segmentvalue = segmentvalue - 0                   
  		HIGH c.1 : LET pinsb = segmentvalue        : LOW c.0 : PAUSE 1       'Display4 

	GOTO clock
                              
    Hour:hours=0
    Hrs:pushresponse=0
    Ho:  
		b0=10  : IF hours < 10 THEN dig11                                 'Display1 Zero blanking
      	 LET b0 = hours DIG 1
		dig11: READ b0,segmentvalue
	HIGH c.2 : let pinsb = segmentvalue : LOW c.3 : PAUSE 1                 'Display1 
	HIGH c.1  :  HIGH c.0                                                   'Display3 off  'Display4 off
	LET b0 = hours DIG 0	                                         
	       READ b0,segmentvalue 
 	      LET segmentvalue = segmentvalue - 128                             'with d.p
	HIGH c.3 : LET pinsb = segmentvalue : LOW c.2 : PAUSE 1                 'Display2
		 
	IF pushbutton = 0 THEN hrs                                              'reset ready for next count
	 
	INC pushresponse 
 	if pushresponse > 200 THEN Minutes                                      'hold to goto Minutes   
 	if pushresponse > 1 THEN ho                                             'ignores button bounce

	LET hours = hours + 1                                                   'Add count by 1 
	IF  hours = 25 THEN hour                                                'Reset after 24 reached
	GOTO ho
	
    Minutes:mins=255                                                        ' start at 0 
    Mns:pushresponse=0                                                
    Mi:  	
	LET b0 = mins DIG 1			
	 READ b0,segmentvalue
		HIGH c.0 : LET pinsb = segmentvalue : LOW c.1 : PAUSE 1          'Display3
	HIGH c.3  :  HIGH c.2                                                  'Display1 off  'Display2 off	
	LET b0 = mins DIG 0	                                                              
	 READ b0,segmentvalue
		HIGH c.1 : LET pinsb = segmentvalue : LOW c.0 : PAUSE 1          'Display4 

	IF pushbutton = 0 THEN mns                                             'reset ready for next count

	INC pushresponse 
	 IF pushresponse > 200 THEN program                                    'hold to goto prog
	 IF pushresponse > 1 THEN Mi                                           'ignores button bounce
                                         
	LET mins = mins + 1                                                    'Add count by 1 
	IF mins = 60 THEN minutes                                              'Reset after 59 reached
	GOTO Mi
	
    Program:	                                     
 	IF pushbutton = 1 THEN program                                         'release to program 
 
 	LET  mins = BINTOBCD mins
 	LET hours = BINTOBCD hours
 
 	HI2CSETUP I2CMASTER, %11010000, I2CSLOW, I2CBYTE         'prog time ds1307  'info change date when programing ie 07/05/10
	HI2COUT 0, ($00, mins, hours, $03, $07, $05, $10, $10)   '(seconds,mins,hour,day,date,month,year,control)
	GOTO program1
	
    Temperatureread: 
      
	OWOUT ds18b20,%1001,($CC,$44)                                        ' reset(send skip rom ,send convert t) 
	OWOUT ds18b20,%0001,($CC,$BE)                                        ' reset(send skip rom ,send read lsb msb)
	OWIN  ds18b20,%0000,(b2,b3)                                          ' read in result
	
      IF temperature > 2001 and temperature < 65252 then program1          ' skip if not within valid sensor range
	IF temperature > 65251 THEN                                              '  info     +125 degrees / 0.0625 =  2000 
	temperature =  - temperature                                             '  info     - 55 degrees          = 64656 
	temperature = temperature* 9/8-320                                                       
	temperature =  - temperature
	ELSE    
	temperature = temperature* 9/8+320                                           '  info   ie w1=2570   display 257.F                                       
             ENDIF	      
	LET dirsb = %11111111                                                'restore b3 pins after read (may not need with 20x2 c.1)
  	
	FOR displayedtime = 1 TO 800                                   'display temp time about 10secs	 
             b0=10  : IF temperature < 1000 THEN dig111               'Display1 zero blanking               
	LET b0 = temperature DIG 3
    Dig111:	 READ b0,segmentvalue	
 	  LET pinsb = segmentvalue : LOW c.3 : PAUSE 1 : HIGH c.3      'Display1    temp
 	  
                      IF temperature < 100  THEN dig112              'Display2 zero blanking
	LET b0 = temperature DIG 2	                                          
    Dig112:  READ b0,segmentvalue
	  LET pinsb = segmentvalue : LOW c.2 : PAUSE 1 : HIGH c.2      'Display2    temp
	  
	LET b0 = temperature DIG 1	
           	 READ b0,segmentvalue
 	LET segmentvalue = segmentvalue - 128                          'Display3    with d.p	
        LET pinsb = segmentvalue : LOW c.1 : PAUSE 1 : HIGH c.1      'Display3    temp
        
        LET pinsb = 142          : LOW c.0 : PAUSE 1 : HIGH c.0      'Display4    F
	NEXT displayedtime
	
    Program1:
	 	HI2CSETUP I2CMASTER, %11010000, I2CSLOW, I2CBYTE     
	HI2CIN 0,(secs,mins,hours)                                  'read time ds1307
	HI2CSETUP OFF  
	LET dirsb = %11111111                                       'hi2c  leaves b5 b7 pins high (restore pinsb)(may not need with 20x2 c.1)
	GOTO main
 
Last edited:
Wow, thanks so much for the code. I will try that tonight.
YES, I did use blue LED's since I think they look very cool. I purchased four 7 segment LED's.

Take Care,
Brian Andonian
Plymouth, MI
 

marks

Senior Member
Hi Aviatorbja,nice snap
No major code update yet lol

I think its a good idea not to solder the display segments direct they are easily damaged
I would mount them on female headers or ic sockets(easy to replace and turn arround when we need too lol)

i havent come up with final hardware yet just more exploring todo it would be good if one board could run all my different projects lol might hav to modulise it lol.
here our preffered date format is dd/mm/yy i bet it different there lol.
thanks mark!
 
Last edited:
Thanks Marks. Your code is very easy to follow, and I now understand the multiplexing routine.

Oooops. I already soldered the LED's onto a perf board. They work OK so apparently I did not damage them.

I plan to have two push buttons, one for setting the time and the other to momentarily display the date in format dd.mm.

Looks like I have an available pin for that.

Thanks again for all of your help. I'm having fun with this stuff.

Cheers!
 

marks

Senior Member
Updated code
must be getting too long and messy as it said had too many characters to put here lol.

when u press the pushbutton it will now program date and time selecting a single digit at a
time to make the process quicker!
date 0 then 1 holding on each digit to select.
month 1 then 0
year 1 then 0 no this is not binary just happens to be 01/10/2010 lol
hour 0 then 1
min 0 then 0 and releasing to be 0100 lol...

at the 31 st stroke lol will display date then temperature then update from ds1307
and then display time.
 

Attachments

Last edited:
Finished clock

Special Thanks to Marks for the Code.

I built a small wood box with an acrylic lid. Also added a USB port since I have 5V available. Can use it as a desk light.

Fun project, but lots of work.
 

Attachments

william47316

New Member
i have made a clock using no more than 2 08M's, the clock is one 08M and one for the 8 digit display, using an external clock ticker setting off an interrupt on pin 3 of the clock 08M it increments the seconds variable and goes off from there the picaxe clock is set using 3 push buttons to set hours and minutes, pushing the ok button starts it going again from 0 seconds. the clock output is 4800 baud serial so it works on my 8 digit display, serial terminal or a serial LCD display sending the current time whenever the clock ticker pulses. this is accurate to the second, and on my 8 digit display it will beep and flash the colons on the hour




Code:
symbol seconds = b1
symbol tenssec = b2
symbol minutes = b3
symbol tensmin = b4
symbol hours10 = b10
symbol hoursu = b11
symbol hours = b5
symbol changeflag = bit0
symbol setflag = bit3
symbol timesetF = bit4

setint 1000,1000 'set pin 3 to interrupt (ticker)

mainloop:
     if input2 = 1 then
     gosub timeset
     end if


serdata:
if changeflag = 1 then
  hours10 = hours /10
  hoursu = hours //10
  sertxd (#hours10,#hoursu, b8,#tensmin,#minutes, b8,#tenssec,#seconds)
  changeflag = 0
end if
if timesetF = 1 then
 return
end if
goto mainloop

timeset:

setint 10000,10000 'set pin4 to interrupt (ok button)
seconds = 0 'reset seconds
tenssec = 0
timesetf = 1 'its in timeset mode so set timeset flag on

timeset2:
gosub serdata 'NB: the display updates only when changeflag is 1 eg the setting buttons are pushed
if input2 = 1 then 'minute set button
pause 250
setflag = 1 'take it to the code that increments the minutes
gosub minset
changeflag = 1 'when it returns the value is changed so it updates the display
end if
if input1 = 1 then
pause 250
setflag = 1
gosub hrset
changeflag = 1
end if

reinit:
if timesetf = 0 then
return

end if
goto timeset2


interrupt:
if timesetf = 1 then 'this is set when pin4 is an interrupt and ignored when the ticker is interrupting
setflag = 0
timesetf = 0
setint 1000,1000 'reset it back to pin 3 as an interrupt
goto reinit
end if

if b8 <> 58 then 'b8 is the "colon" positions if it was changed to the bell character
b8 = 58 'reset it back to colons
end if

if input3 = 0 then 'when the ticker pulses wait until the pulse recedes 
inc seconds 'this is the main number of seconds
if seconds = 10 then
seconds = 0
inc tenssec
if tenssec = 6 then
tenssec = 0
minset:
inc minutes
end if
end if
if minutes = 10 then
minutes = 0
inc tensmin
if tensmin = 6 then
tensmin = 0
if setflag = 1 then
return
end if
b8 = 7 'when the hours gets incremented change b8 to a bell character making the display beep and "flash" the colons
hrset:
inc hours


end if
end if
if hours = 24 then
hours = 0
end if
if setflag = 1 then
return
end if
changeflag = 1 'update the display
setint 1000,1000 'reset the interrupt for pin 3
return
end if
goto interrupt
 
Last edited:

hbl2013

Senior Member
Thanks fellows. This info will give me start. Unfortunately, I allready have wired 4 - 7 segments on my board. I am using a CD4511 to make it a little easier to program them.
BTW I have also wired on the board one of those cheap $0.99 1 Line Serial LCDs to experiment with. (Part #KTM-S1201, available on the Internet) Has anybody used them as yet? I think you can use the CLK and SI functions of the PICAXE for it, but I have not tried it as yet.
 
Hi to all,

I tried the code from mark to build my digital led clock, but not working very nice, looks like i am able to set time and date but then after while clock come back to 10:09.

Any idea? or good code
 

Paix

Senior Member
Welcome to the forum Olivertwistagain. That would be down to a typo I imagine. A copying error from Marks code.
Are you using the Picaxe 20X2, DS1307 and DS18B20 and is the temperature reporting OK?

You could put a few sertxd commands into your code to try and understand what values are going off the rails and then check back to find out where they depart from the norm. Put a label in your sertxd such as "AAA" or "BBB" etc, so that you know which instance is which.

Generic answer for a generic question. Crystal ball is inop at the moment.
 

marks

Senior Member
Hi olivertwistagain,
I hadn't looked at this for a while .
The picaxe 20x2 can be fussy with I2C.
I noticed the drawing shows 4.7K for pullups,
try using a 2k or 2.2k for the pullups which is much preferred,
this will give you cleaner Hi2C clock and data pulses.

I dont have a DS1307 to try but I plugged in a DS3231 using the same
code as post#25 using a 20x2 version c.1 which seems to run ok.
there are quit a few modules to be found on Ebay for just a few dollars
newer ones have some memory on the board and a smaller one again that plugs into a Raspberry Pi.
 

Attachments

oracacle

Senior Member
havent read through everything in this thread as of yet but thought i would add in what i have,

clock has, alarm, abilty to be set thought it buttons (both alarm time and actual time), battery monitor, tempurature read out and display of day, date month and year (adjustable with it buttons of course).

also found a pretty nice touch was to add a zero defult incase of issue with power and battery back up

code is still abit scrappy, but seem to work.
 

Attachments

Top