kopia lustrzana https://github.com/peterhinch/micropython-samples
Delta now returns mS. Cal delays in minutes, default 5.
rodzic
ddb3d391f9
commit
1fb0f40d9a
|
@ -1,6 +1,7 @@
|
||||||
# Pyboard driver for DS3231 precison real time clock.
|
# Pyboard driver for DS3231 precison real time clock.
|
||||||
# Adapted from WiPy driver at https://github.com/scudderfish/uDS3231
|
# Adapted from WiPy driver at https://github.com/scudderfish/uDS3231
|
||||||
# Includes routine to calibrate the Pyboard's RTC from the DS3231
|
# Includes routine to calibrate the Pyboard's RTC from the DS3231
|
||||||
|
# delta method now operates to 1mS precision
|
||||||
# Adapted by Peter Hinch, Jan 2016
|
# Adapted by Peter Hinch, Jan 2016
|
||||||
|
|
||||||
import utime, pyb
|
import utime, pyb
|
||||||
|
@ -24,9 +25,8 @@ def bcd2dec(bcd):
|
||||||
return (((bcd & 0xf0) >> 4) * 10 + (bcd & 0x0f))
|
return (((bcd & 0xf0) >> 4) * 10 + (bcd & 0x0f))
|
||||||
|
|
||||||
def dec2bcd(dec):
|
def dec2bcd(dec):
|
||||||
t = dec // 10
|
tens, units = divmod(dec, 10)
|
||||||
o = dec - t * 10
|
return (tens << 4) + units
|
||||||
return (t << 4) + o
|
|
||||||
|
|
||||||
class DS3231:
|
class DS3231:
|
||||||
def __init__(self, side = 'X'):
|
def __init__(self, side = 'X'):
|
||||||
|
@ -80,38 +80,46 @@ class DS3231:
|
||||||
self.ds3231.mem_write(dec2bcd(MM), DS3231_I2C_ADDR, 5)
|
self.ds3231.mem_write(dec2bcd(MM), DS3231_I2C_ADDR, 5)
|
||||||
self.ds3231.mem_write(dec2bcd(YY-1900), DS3231_I2C_ADDR, 6)
|
self.ds3231.mem_write(dec2bcd(YY-1900), DS3231_I2C_ADDR, 6)
|
||||||
|
|
||||||
def delta(self):
|
def delta(self): # Return no. of mS RTC leads DS3231
|
||||||
return utime.time() - utime.mktime(self.get_time()) # No. of secs RTC leads DS3231
|
self.await_transition()
|
||||||
|
rtc_time = now()
|
||||||
|
rtc_ms = rtc_time[0] * 1000 + rtc_time[1]
|
||||||
|
t_ds3231 = utime.mktime(self.get_time()) # To second precision, still in same sec as transition
|
||||||
|
return rtc_ms - 1000 * t_ds3231
|
||||||
|
|
||||||
def await_transition(self):
|
def await_transition(self): # Wait until DS3231 seconds value changes
|
||||||
data = self.ds3231.mem_read(7, DS3231_I2C_ADDR, 0)
|
data = self.ds3231.mem_read(7, DS3231_I2C_ADDR, 0)
|
||||||
ss = data[0]
|
ss = data[0]
|
||||||
while ss == data[0]:
|
while ss == data[0]:
|
||||||
data = self.ds3231.mem_read(7, DS3231_I2C_ADDR, 0) # Await a seconds transition
|
data = self.ds3231.mem_read(7, DS3231_I2C_ADDR, 0)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# Get calibration factor for Pyboard RTC. Note that the DS3231 doesn't have millisecond resolution so we
|
# Get calibration factor for Pyboard RTC. Note that the DS3231 doesn't have millisecond resolution so we
|
||||||
# wait for a seconds transition to emulate it.
|
# wait for a seconds transition to emulate it.
|
||||||
# This function returns the required calibration factor for the RTC (approximately the no. of ppm the
|
# This function returns the required calibration factor for the RTC (approximately the no. of ppm the
|
||||||
# RTC lags the DS3231).
|
# RTC lags the DS3231).
|
||||||
# For accurate results the delay should be at least 120 seconds. Longer is better.
|
# For accurate results the delay should be at least two minutes. Longer is better.
|
||||||
# Note calibration factor is not saved on power down unless an RTC backup battery is used. An option is
|
# Note calibration factor is not saved on power down unless an RTC backup battery is used. An option is
|
||||||
# to store the calibration factor on disk and issue rtc.calibration(factor) on boot.
|
# to store the calibration factor on disk and issue rtc.calibration(factor) on boot.
|
||||||
|
|
||||||
def getcal(self, seconds):
|
def getcal(self, minutes=5):
|
||||||
rtc.calibration(0) # Clear existing cal
|
rtc.calibration(0) # Clear existing cal
|
||||||
self.save_time() # Set DS3231 from RTC
|
self.save_time() # Set DS3231 from RTC
|
||||||
self.await_transition()
|
self.await_transition()
|
||||||
rtcstart = now()
|
rtcstart = now()
|
||||||
dsstart = utime.mktime(self.get_time())
|
dsstart = utime.mktime(self.get_time())
|
||||||
pyb.delay(seconds * 1000)
|
pyb.delay(minutes * 60000)
|
||||||
self.await_transition()
|
self.await_transition()
|
||||||
rtcend = now()
|
rtcend = now()
|
||||||
dsend = utime.mktime(self.get_time())
|
dsend = utime.mktime(self.get_time())
|
||||||
dsdelta = (dsend - dsstart) *1000
|
dsdelta = (dsend - dsstart) *1000
|
||||||
rtcdelta = rtcend[0] * 1000 + rtcend[1] - rtcstart[0] * 1000 - rtcstart[1]
|
rtcdelta = rtcend[0] * 1000 + rtcend[1] - rtcstart[0] * 1000 - rtcstart[1]
|
||||||
ppm = (1000000* (rtcdelta - dsdelta))/dsdelta
|
ppm = (1000000* (rtcdelta - dsdelta))/dsdelta
|
||||||
return -ppm/0.954
|
return int(-ppm/0.954)
|
||||||
|
|
||||||
def calibrate(self, seconds):
|
def calibrate(self, minutes=5):
|
||||||
rtc.calibration(self.getcal(seconds))
|
print('Waiting {} minutes to acquire calibration factor...'.format(minutes))
|
||||||
|
cal = self.getcal(minutes)
|
||||||
|
rtc.calibration(cal)
|
||||||
|
print('Pyboard RTC is calibrated. Factor is {}.'.format(cal))
|
||||||
|
return cal
|
||||||
|
|
Ładowanie…
Reference in New Issue