Project - Digital Clock

This project shows how to synchronise ESP date and time to an RTC module.
It is not actually necessary to sync the ESP, because it is perfectly feasible to manage all time-specific tasks directly using RTC time.
But for demonstration purposes this script will sync ESP date and time with the RTC at startup, then periodically sync at your specified frequency.
Again for demonstration purposes, the startup sync has been commented out and the sync frequency reduced to more easily show operation.


The larger upper display shows ESP time and date, while the lower RTC time and date is shown to the left of the 2 buttons.
The display will use the optional digital font if it is available (included in the zip below) otherwise it will just appear in the default system font.
Some RTC modules are shipped without battery, so after fitting a battery, the time and date will need to be set - that is what the pink button is for.
Obviously you could use the RTC.SETTIME year, month, date, hour, min, sec instruction, but the settings will only be correct for 1 second, so it is more tranquil to use the "Sync Time" button in the Toolkit File Manager to set ESP time, then use the pink button to set the RTC from ESP time.

After the RTC has been set, if the ESP is rebooted it will return to 01/01/1970 groundhog day (assuming no internet connection), then 15 seconds later the Output window will show the ESP time being synced to the RTC time ... this is just for demo purposes - when happy with the operation, un-comment the line to enableautomatic sync at startup, and set the periodic sync frequency to something more realistic, eg: hourly or daily.

CICCIOCBThe ESP date does not refresh in the display window until the browser is refreshed, even though the date has been synced ok.

An optional i2c scanner is included to check that the RTC module is available - it sends output to wlog for those with no serial connection.
Be aware that some RTC modules may contain additional i2c functionality such as temperature sensor or eeprom (check the device datasheet).

The i2c bus could be used for addressing other i2c modules if wished, including perhaps an OLED display.
This project, however, offers the option to use the cheaply available (less than a quid) TM1637 4-digit 7-segment LED display.
And although it is not actually an i2c device, it is close enough to be able to use the same i2c pins as the RTC without causing any problem.
The smaller 0.36" TM1637 modules are usually red, but for a few pennies more you can have 0.56" in either red, white, blue, yellow, or green.
(white and blue are particularly attractive). These later black pcb TM1637 versions will probably include i2c pullup resistors on board, and possibly some extra capacitors which may require setting the optional bit delay to eg:100 (see Docs TM1637.SETUP data_pin, clock_pin [, bit_delay]).



















Both the DS3231 RTC modules shown above have built-in 4.7K i2c pullups.
Others may require adding a pair of external pullup resistors (I use10K for a single i2c device, 4.7K for 2 devices, 2.5K for 3 or more i2c devices).




The centre dots toggle on and off every second to show that the clock is ticking.
LED brightness can be controlled by changing the script variable TMbrightness = 1 to 7 (0 turns the display off).
Change script variable TM1637 = 0 if you just want the RTC functionality without the clock display, or wish to use a different display device.

Basic:
'            RTC Clock plus optional TM1637 4-digit 7-segment LED display
I2C.SETUP 4, 5                            'I2C port on pins 4 SDA and 5 SCL
TM1637 = 1                                  'change to 0 if not using TM1637
'gosub i2cscanner                         'uncomment to scan i2c bus for RTC and show results in wlog window
'gosub rtc2esp                               'uncomment to sync date and time from RTC to ESP when script boots
syncfreq = 1 * 1000 '* 60 * 60       're-sync frequently - the specified value is for hourly, add * 24 for daily, or set =0 to disable re-sync
syncfreq = 15 * 1000       'temporary 15 sec demo resync ... delete this line after testing to enable the hourly line above
fontpath$ = "/font/"                         'path to optional font file
fontfile$ = "dig7monoitalic.ttf"        'filename.ext of optional font file
Print "The date is " + RTC.DATE$     'confidence printout
Print "The time is " + RTC.TIME$      'confidence printout
wlog  "RTC date is " + RTC.DATE$   'confidence printout
wlog  "RTC time is " + RTC.TIME$    'confidence printout
if TM1637 = 1 then
 TM1637 = 1
 TM1637.SETUP 4, 5                    'use same pins as used by RTC i2c.setup
 TMbrightness = 4                         '7=bright, 1=dim, 0=off
 TMdots = 0
endif
timer0 1000,ticker
timer1 syncfreq, sync
onhtmlreload paint
wait

ticker:
jscall |_$('CLOCK').innerHTML = "| + time$ + |"|   'displays ESP time
jscall |_$('ESP').innerHTML = "| + date$ + |"|     'displays ESP date
jscall |_$('RTC').innerHTML = "| + rtc.time$ + string$(2," ") + rtc.date$ + |"|  'displays RTC time+date
if TM1637 = 1 then
 t$ = time$
 t$ = word$(t$,1,":") + word$(t$,2,":")
 if TMdots = 0 then TMdots = 255 else TMdots = 0
 TM1637.PRINT t$, TMbrightness, TMdots
endif
refresh
return

sync:
gosub rtc2esp
return

paint:
cls
a$ = ""
a$ = a$ + |<br><div  style='display: table; margin-right:auto;margin-left:auto;text-align:center;borderx:1px solid gray;background:lightcyan;border:1px solid gray;'>|
a$ = a$ + |<style> @font-face { font-family: myfont; src: url('| + fontpath$ + fontfile$ + |');} </style>|
a$ = a$ + |<div id='CLOCK' style='font-family:myfont;color:dimgray;font-size:6.5em;text-align:center;|
a$ = a$ + |display: table; margin-right:auto;margin-left:auto;padding-left:.4em;padding-right:.4em;'>| + rtc.time$ + |</div>|
a$ = a$ + |<div ide='ESP' style='font-family:myfont;color:grey;font-size:2.3em;'>| + date$ + |</div></div>|
a$ = a$ + |<div><br>|
a$ = a$ + |<table align='center'><tr>|
a$ = a$ + |<td>RTC = </td>| + |<td id='RTC'>| + rtc.time$ + string$(2,"&nbsp;") + rtc.date$ +  |</td><td>| + string$(5,"&nbsp;")
a$ = a$ + button$("Set ESP from RTC",rtc2esp,"byel") + string$(5,"&nbsp;") + button$("Set RTC from ESP",esp2rtc,"bred") + |</td></tr>|
a$ = a$ + |</table>|
a$ = a$ + cssid$("RTC","background:AliceBlue;")
a$ = a$ + cssid$("byel","background:LemonChiffon;")
a$ = a$ + cssid$("bred","background:lightpink;")
a$ = a$ + |</div>|
html a$
a$ = ""
refresh
return

rtc2esp:
t$ = RTC.time$
d$ = RTC.date$
day  = val(word$(d$,1,"/"))
mth  = val(word$(d$,2,"/"))
year = val(word$(d$,3,"/"))
hour = val(word$(t$,1,":"))
min  = val(word$(t$,2,":"))
sec  = val(word$(t$,3,":"))
SETTIME year, mth, day, hour, min, sec
refresh
return

esp2rtc:
t$ = time$
d$ = date$
day  = val(word$(d$,1,"/"))
mth  = val(word$(d$,2,"/"))
year = val(word$(d$,3,"/"))
hour = val(word$(t$,1,":"))
min  = val(word$(t$,2,":"))
sec  = val(word$(t$,3,":"))
RTC.SETTIME year, mth, day, hour, min, sec
refresh
return

i2cscanner:
wlog "scanning..."
for i = 0 to 120
  i2c.begin i
  if i2c.end = 0 then
    print "found "; i, hex$(i)
    wlog "found " + str$(i) + "   " + hex$(i)
    pause 10
  end if
next i
wlog "ended"
end
return

'------------------- End --------------------






Margaret Baker,
Feb 4, 2018, 10:57 AM
v.1