Picaxe 20x2 scrolling 14 segment display clock with MAX6955 and DS3231

I really enjoy the 7 segment LED displays. I decided to try my hand at a 4-digit 14 segment display using the MAX6955 chip.
So I made a custom board and put this together.
Displays current time and alternates between temperature and scrolling date every 15 seconds.
Code is not optimized and is not fully tested for all month/day combinations.

I really like the look of the 14 segment display. Programming the MAX6955 was actually quite simple once you read the spec sheet.

14segment.JPG14segment3.JPG

Here's the youtube video
http://www.youtube.com/watch?v=5pFTJ-Oco_I

Code:
'scrolling clock/calendar/temp display using MAX6955
'14 segment LED driver and picaxe20x2
'aviatorbja
'24-March-2013
'some code by Marks and other Picaxe Forum Members

symbol digit0=b0
symbol digit1=b1
symbol digit2=b2
symbol digit3=b3
symbol memloc=b4
symbol dtime=b5
symbol linelength=b6
symbol secs=b7
symbol mins=b8
symbol hours=b9
symbol day=b10
symbol date=b11
symbol month=b12
symbol year=b13
symbol tempbyte=b14
SYMBOL character1    = b15 : symbol char1=b15
SYMBOL character2    = b16 : symbol char2=b16 
SYMBOL character3    = b17 : symbol char3=b17  
SYMBOL character4    = b18 : symbol char4=b18  
SYMBOL character5    = b19 : symbol char5=b19 
SYMBOL character6    = b20 : symbol char6=b20
symbol tempbyte2=b21
symbol Temperature=W12: symbol TempMSB=b25:symbol TempLSB=b24

dtime=200   'animation speed

#picaxe 20x2
#com3

'*****PROGRAM MESSAGES INTO MEMORY
eeprom 0,  ("SUNDAY   ")
eeprom 9,  ("MONDAY   ")
eeprom 18, ("TUESDAY  ")
eeprom 27, ("WEDNESDAY")
eeprom 36, ("THURSDAY ")
eeprom 45, ("FRIDAY   ")
eeprom 54, ("SATURDAY ")

eeprom 63,  ("January  ")
eeprom 72,  ("February ")
eeprom 81,  ("March    ")
eeprom 90,  ("April    ")
eeprom 99,  ("May      ")
eeprom 108, ("June     ")
eeprom 117, ("July     ")
eeprom 126, ("August   ")
eeprom 135, ("September")
eeprom 144, ("October  ")
eeprom 153, ("November ")
eeprom 162, ("December ")
 

timedisp:
'****Configure ds3231 chip
i2cslave %11010000, i2cslow, i2cbyte
readi2c 0, (secs,mins,hours,day,date,month,year,tempbyte)
IF hours = $20 OR hours = $21 THEN : LET hours = hours - $6 : ENDIF
IF hours > $12 THEN : LET hours = hours - $12 : ENDIF '24 to 12 hour format
BCDTOASCII date, char1, char2
read 200, tempbyte:read 201, tempbyte2
IF tempbyte <> char1 and tempbyte2 <> char2 then
	write 200,char1			'write date to memory once per day
	write 201,char2,17,17,17,17
endif
tempbyte=bcdtobin secs
tempbyte=tempbyte//30
IF secs = $00 THEN DateDisplay
IF secs = $15 THEN TempDisplay
IF secs = $30 THEN DateDisplay
if secs = $45 THEN TempDisplay

bcdtoascii hours,char1,char2
bcdtoascii mins,char3,char4
'  configure Max6955 chip - see spec sheet
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'I2c address is configurable
hi2cout $0C, (%0001111)   'write 14 segment mode

hi2cout $01, (%11111111)    'decode mode

hi2cout $04, (%00000001)    ''configuration
hi2cout $02, ($03)          'max intesitiy

hi2cout $03, (%00000011)    'scan limit digits 0-3 only
char2=char2+128   'add decimal point between hour and minute

hi2cout $60, (char1,char2,char3,char4)
goto timedisp:

DateDisplay:
tempbyte=bcdtobin day
memloc=tempbyte*9-9
select case memloc
case 0,9,45
	linelength=7
case 18,27,36,54
	linelength=0
endselect

gosub showtext	'show day of week
tempbyte=bcdtobin month
memloc=tempbyte*9+54
select case memloc
case 63,72,135
	linelength=9
case 81,90,99,108,117
	linelength=6
case 126,144,153,162
	linelength=8
endselect

gosub showtext	'show month

memloc=200
linelength=6
gosub showtext
goto timedisp:

TempDisplay:
HI2Csetup I2Cmaster, %11010000, I2Cslow, I2Cbyte        
HI2Cin $11,(TempMsb,TempLsb) ' read temperature DS3231SN  - 40.00 F  to  + 185.00 F 	 	 	 
 
Convert: Temperature = Temperature +14080 **46080 -6700                  
            
         LET character1 = " " ' character1 (Sign) Display +
        
         IF TempMsb > 127 THEN : Temperature = - Temperature : LET character1 = "-" : ENDIF ' character1 (Sign) Display -

    
Display: BinTOASCII Temperature,character2,character3,character4,character5,character6
               IF character2 = "0" THEN : character2 = " "            ' zero blanking 
                 IF character3 = "0" THEN : character3 = " " : ENDIF  ' zero blanking 
               ENDIF
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'MAX6955 chip configuration
hi2cout $0C, (%0001111)   'write 14 segment mode

hi2cout $01, (%11111111)    'decode mode

hi2cout $04, (%00000001)    ''configuration
hi2cout $02, ($05)          'max intesitiy

hi2cout $03, (%00000011)    'scan limit digits 0-3 only
character4=character4+128   'add decimal between whole and decimal degrees
hi2cout $60, (character3,character4,character5,"F")
PAUSE 2000 : GOTO timedisp






'******SUBROUTINE TO SCROLL TEXT
showtext:
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  
hi2cout $0C, (%0001111)   'write 14 segment mode

hi2cout $01, (%11111111)    'decode mode

hi2cout $04, (%00000001)    ''configuration
hi2cout $02, ($05)          'max intesitiy

hi2cout $03, (%00000011)    'scan limit digits 0-3 only
digit0=17   'set blanks on each digit
digit1=17
digit2=17
digit3=17
hi2cout $60 ,(digit0,digit1,digit2,digit3)  'print blanks on display
pause 200
for tempbyte=1 to linelength
read memloc,digit3
hi2cout $60, (digit0,digit1,digit2,digit3)    
pause dtime

digit0=digit1	'shift characters 1 space left
digit1=digit2
digit2=digit3   

inc memloc
next tempbyte

return
 

westaust55

Moderator
Well done.



A few comments:

1. The DS3231 can operate at the fast i2c bus comms rate, so the lines

Code:
timedisp:
    '****Configure ds3231 chip
	i2cslave %11010000, i2cslow, i2cbyte
can be chanegd to:
Code:
timedisp:
    '****Configure ds3231 chip
	HI2CSETUP I2CMASTER, %11010000, I2Cfast, I2CBYTE
which in using the newer HI2C.... commands is in keeping with the rest of the program.


2. The line of code:
Code:
	HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'I2c address is configurable
	hi2cout $0C, (%0001111)   'write 14 segment mode

	hi2cout $01, (%11111111)    'decode mode

	hi2cout $04, (%00000001)    ''configuration
	hi2cout $02, ($03)          'max intesitiy

	hi2cout $03, (%00000011)    'scan limit digits 0-3 only
appear three times.
You should be able to set up the MAX6955 chip once and then only issue the HI2CSETUP command each time you send data (in case you have read the RTC in the meantime).

3. There are sufficient comments to help others follow in your footsteps. The use of indenting in program code to enhance visibility of looping and test structures would be an advantage.
 
Thank you very much for the comments Westaust, posting to this forum is always a pleasure. I have a lot of cleanup to do in my program. Bits and pieces of the code come from other projects I have worked on over the years.
Also, I found out today that the scrolling date is not updating properly. The goal here is to store the current date into memory locations 200 and 201. The program will check to see if the date read from the DS3231 matches what is stored in memory. If not, it will write the new date into memory. Obviously, I only want to perfom the memory write once per day to conserve EEPROM duty cycle.

for some reason, the following code is not updating the date properly

Code:
BCDTOASCII date, char1, char2                           'convert current date into ASCII format
read 200, tempbyte:read 201, tempbyte2              'read date stored in memory locations 200 and 201
IF tempbyte <> char1 and tempbyte2 <> char2 then   'determine if current date is the same as date stored in memory
	write 200,char1			         'if not,  write new date to memory 
	write 201,char2,17,17,17,17                       'add four blanks (17) after the second digit for scrolling display
endif

Well done.



A few comments:

1. The DS3231 can operate at the fast i2c bus comms rate, so the lines

Code:
timedisp:
    '****Configure ds3231 chip
	i2cslave %11010000, i2cslow, i2cbyte
can be chanegd to:
Code:
timedisp:
    '****Configure ds3231 chip
	HI2CSETUP I2CMASTER, %11010000, I2Cfast, I2CBYTE
which in using the newer HI2C.... commands is in keeping with the rest of the program.


2. The line of code:
Code:
	HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'I2c address is configurable
	hi2cout $0C, (%0001111)   'write 14 segment mode

	hi2cout $01, (%11111111)    'decode mode

	hi2cout $04, (%00000001)    ''configuration
	hi2cout $02, ($03)          'max intesitiy

	hi2cout $03, (%00000011)    'scan limit digits 0-3 only
appear three times.
You should be able to set up the MAX6955 chip once and then only issue the HI2CSETUP command each time you send data (in case you have read the RTC in the meantime).

3. There are sufficient comments to help others follow in your footsteps. The use of indenting in program code to enhance visibility of looping and test structures would be an advantage.
 
Never mind that last post. I just figured out the issue.
Code:
IF tempbyte <> char1 and tempbyte2 <> char2 then
should be changed to
Code:
IF tempbyte <> char1 OR tempbyte2 <> char2 then
 
Board and Schematic files

Here is the board. The 14-segment module used is: Kingbright PDC54-11EWA, two are required.

Here is the revised code which I cleaned up a bit. The MAX6955 I2C address is set using the AD1 and AD0 pins, connecting them to ground or +5V as shown in Table 5 of the MAX6955 data sheet which is here: http://datasheets.maximintegrated.com/en/ds/MAX6955.pdf

If anyone needs the eagle files for this project, please let me know via this board or email.

I had a lot of fun and learned a great deal about I2C from this project.

Code:
'scrolling clock/calendar/temp display using MAX6955
'14 segment LED driver and picaxe20x2
'aviatorbja
'24-March-2013
'ds3231 code by Marks
'for EAGLE schematic and  board files please email:aviatorbja@yahoo.com

SYMBOL digit0=b0
SYMBOL digit1=b1
SYMBOL digit2=b2
SYMBOL digit3=b3
SYMBOL memloc=b4
SYMBOL dtime=b5
SYMBOL linelength=b6
SYMBOL secs=b7
SYMBOL mins=b8
SYMBOL hours=b9
SYMBOL day=b10
SYMBOL date=b11
SYMBOL month=b12
SYMBOL year=b13
SYMBOL tempbyte=b14
SYMBOL character1    = b15 : SYMBOL char1=b15
SYMBOL character2    = b16 : SYMBOL char2=b16 
SYMBOL character3    = b17 : SYMBOL char3=b17  
SYMBOL character4    = b18 : SYMBOL char4=b18  
SYMBOL character5    = b19 : SYMBOL char5=b19 
SYMBOL character6    = b20 : SYMBOL char6=b20
SYMBOL tempbyte2=b21
SYMBOL Temperature=W12: SYMBOL TempMSB=b25:SYMBOL TempLSB=b24

dtime=200   'animation speed

#picaxe 20x2
#com3

'*****PROGRAM MESSAGES INTO MEMORY
eeprom 0,  ("SUNDAY   ")
eeprom 9,  ("MONDAY   ")
eeprom 18, ("TUESDAY  ")
eeprom 27, ("WEDNESDAY")
eeprom 36, ("THURSDAY ")
eeprom 45, ("FRIDAY   ")
eeprom 54, ("SATURDAY ")

eeprom 63,  ("January  ")
eeprom 72,  ("February ")
eeprom 81,  ("March    ")
eeprom 90,  ("April    ")
eeprom 99,  ("May      ")
eeprom 108, ("June     ")
eeprom 117, ("July     ")
eeprom 126, ("August   ")
eeprom 135, ("September")
eeprom 144, ("October  ")
eeprom 153, ("November ")
eeprom 162, ("December ")


timedisp:
'****Configure ds3231 chip
HI2CSETUP I2CMASTER, %11010000, I2Cfast, I2CBYTE
HI2CIN 0, (secs,mins,hours,day,date,month,year,tempbyte)
IF hours = $20 OR hours = $21 THEN : LET hours = hours - $6 : ENDIF
IF hours > $12 THEN : LET hours = hours - $12 : ENDIF '24 to 12 hour format
BCDTOASCII date, char1, char2
read 200, tempbyte
read 201, tempbyte2
IF tempbyte <> char1 OR tempbyte2 <> char2 then 
                write 200,char1                                 'write date to memory if different from what is already stored in locations 200 and 201
                write 201,char2,17,17,17,17         'add spaces after second date digit 
endif

check:
IF secs = $00 THEN DateDisplay
IF secs = $15 THEN TempDisplay
IF secs = $30 THEN DateDisplay
if secs = $45 THEN TempDisplay

bcdtoascii hours,char1,char2
bcdtoascii mins,char3,char4
if char1="0" then
                char1=" "
endif

'  configure Max6955 chip - see spec sheet
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'I2c address is configurable
hi2cout $0C, (%0001111)   'write 14 segment mode

hi2cout $01, (%11111111)    'decode mode

hi2cout $04, (%00000001)    ''configuration
hi2cout $02, ($03)          'max intesitiy

hi2cout $03, (%00000011)    'scan limit digits 0-3 only
char2=char2+128   'add decimal point between hour and minute

hi2cout $60, (char1,char2,char3,char4)

goto timedisp:

DateDisplay:
tempbyte=bcdtobin day
memloc=tempbyte*9-9
SELECT CASE memloc
CASE 0,9,45
                linelength=7
CASE 18,27,36,54
                linelength=9
endSELECT

gosub showtext               'show day of week
tempbyte=bcdtobin month
memloc=tempbyte*9+54
SELECT CASE memloc
CASE 63,72,135
                linelength=9
CASE 81,90,99,108,117
                linelength=6
CASE 126,144,153,162
                linelength=8
endSELECT

gosub showtext               'show month

memloc=200
linelength=6
gosub showtext
goto timedisp:

TempDisplay:
HI2Csetup I2Cmaster, %11010000, I2Cslow, I2Cbyte        
HI2Cin $11,(TempMsb,TempLsb) ' read temperature DS3231SN  - 40.00 F  to  + 185.00 F                                  
 
Convert: Temperature = Temperature +14080 **46080 -6700                  
            
         LET character1 = " " ' character1 (Sign) Display +
        
         IF TempMsb > 127 THEN : Temperature = - Temperature : LET character1 = "-" : ENDIF ' character1 (Sign) Display -

    
Display: BinTOASCII Temperature,character2,character3,character4,character5,character6
               IF character2 = "0" THEN : character2 = " "            ' zero blanking 
                 IF character3 = "0" THEN : character3 = " " : ENDIF  ' zero blanking 
               ENDIF
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  'MAX6955 chip configuration

character4=character4+128   'add decimal between whole and decimal degrees
hi2cout $60, (character3,character4,character5,"F")
PAUSE 2000 : GOTO timedisp


'******SUBROUTINE TO SCROLL TEXT from right to left
showtext:
HI2CSETUP I2CMASTER, %11000000, I2Cfast, I2CBYTE  

digit0=17   'set blanks on each digit
digit1=17
digit2=17
digit3=17
hi2cout $60 ,(digit0,digit1,digit2,digit3)  'print blanks on display
pause 200
for tempbyte=1 to linelength
read memloc,digit3
hi2cout $60, (digit0,digit1,digit2,digit3)    
pause dtime

digit0=digit1       'shift characters 1 space left
digit1=digit2
digit2=digit3   

inc memloc
next tempbyte

return
 

Attachments

Top