MicroPython Driver for DS3231

DS3231 Driver Code for micro:bit

Download as zip file

'''
 DS3231 Real Time Clock Driver
 for the BBC micro:bit

 Original author: shaoziyang
 Date: 2018.2
 http://www.micropython.org.cn

 Extended by fredscave.com
 DATE: 2024.9
'''

from microbit import i2c
from micropython import const

I2C_ADDR  = const(0x68)
REG_SEC   = const(0x00)
REG_MIN   = const(0x01)
REG_HR    = const(0x02)
REG_WDAY  = const(0x03)
REG_DAY   = const(0x04)
REG_MON   = const(0x05)
REG_YR    = const(0x06)
REG_A2MIN = const(0x0B)
REG_A2HR  = const(0x0C)
REG_A2DAY = const(0x0D)
REG_CTRL  = const(0x0E)
REG_STA   = const(0x0F)
REG_TEMP  = const(0x11)

class DS3231():
    def __init__(self):
        self.setReg(REG_CTRL, 0x4C)

    def DecToHex(self, dat):
        return (dat//10) * 16 + (dat%10)

    def HexToDec(self, dat):
        return (dat//16) * 10 + (dat%16)

    def setReg(self, reg, dat):
        i2c.write(I2C_ADDR, bytearray([reg, dat]))

    def getReg(self, reg):
        i2c.write(I2C_ADDR, bytearray([reg]))
        return i2c.read(I2C_ADDR, 1)[0]

    def Sec(self, sec = None):
        if sec == None:
            return self.HexToDec(self.getReg(REG_SEC))
        else:
            self.setReg(REG_SEC, self.DecToHex(sec%60))

    def Mins(self, mins = None):
        if mins == None:
            return self.HexToDec(self.getReg(REG_MIN))
        else:
            self.setReg(REG_MIN, self.DecToHex(mins%60))

    def Hr(self, hr = None):
        if hr == None:
            return self.HexToDec(self.getReg(REG_HR))
        else:
            self.setReg(REG_HR, self.DecToHex(hr%24))

    def Wday(self, wday = None):
        if wday == None:
            return self.HexToDec(self.getReg(REG_WDAY))
        else:
            self.setReg(REG_WDAY, self.DecToHex(wday%8))

    def Day(self, day = None):
        if day == None:
            return self.HexToDec(self.getReg(REG_DAY))
        else:
            self.setReg(REG_DAY, self.DecToHex(day%32))

    def Mon(self, mon = None):
        if mon == None:
            return self.HexToDec(self.getReg(REG_MON))
        else:
            self.setReg(REG_MON, self.DecToHex(mon%13))

    def Yr(self, yr = None):
        if yr == None:
            return self.HexToDec(self.getReg(REG_YR)) + 2000
        else:
            self.setReg(REG_YR, self.DecToHex(yr%100))

    def DateTime(self, dat = None):
        if dat == None:
            return [self.Yr(), self.Mon(),
                    self.Day(),self.Wday(),
                    self.Hr(), self.Mins(), self.Sec()]
        else:
            self.Yr(dat[0])
            self.Mon(dat[1])
            self.Day(dat[2])
            self.Wday(dat[3])
            self.Hr(dat[4])
            self.Mins(dat[5])
            self.Sec(dat[6])

    def Time(self, h=None, m=None, s=None):
        if (h==None) and (m==None) and (s==None):
            str_sec = "%02d" % self.Sec()
            str_min = "%02d" % self.Mins()
            str_hr = "%02d" % self.Hr()
            return str_hr + ':' + str_min + ':' + str_sec
        if (s != None):
            self.Sec(s)
        if (m != None):
            self.Mins(m)
        if (h != None):
            self.Hr(h)

    def Date(self, y=None, m=None, d=None, fmt=1):
        # fmt = 1; YMD
        # fmt = 2; DMY
        # fmt = 3; MDY
        if (y==None) and (m==None) and (d==None):
            str_day = "%02d" % self.Day()
            str_mon = "%02d" % self.Mon()
            str_yr = "%04d" % self.Yr()
            if fmt == 1:
                return str_yr + '-' + str_mon + '-' + str_day
            if fmt == 2:
                return str_day + '-' + str_mon + '-' + str_yr
            if fmt == 3:
                return str_mon + '-' + str_day + '-' + str_yr
            return None
        if (d != None):
            self.Day(d)
        if (m != None):
            self.Mon(m)
        if (y != None):
            self.Yr(y)

    def ALARMset(self, mins=None, hr=None):
        m4 = self.getReg(REG_A2DAY)
        m3 = self.getReg(REG_A2HR)
        m2 = self.getReg(REG_A2MIN)
        self.setReg(REG_A2DAY, m4 | 0b10000000)
        cr = self.getReg(REG_CTRL)
        self.setReg(REG_CTRL, cr | 0b00000110)
        if (mins==None) and (hr==None):
            self.setReg(REG_A2HR, m3 | 0b10000000)
            self.setReg(REG_A2MIN, m2 | 0b10000000)
        elif (hr==None):
            self.setReg(REG_A2HR, m3 | 0b10000000)
            self.setReg(REG_A2MIN, self.DecToHex(mins%60) & 0b01111111)
        else:
            self.setReg(REG_A2MIN, self.DecToHex(mins%60) & 0b01111111)
            self.setReg(REG_A2HR, self.DecToHex(hr%24) & 0b01111111)

    def ALARMclear(self):
        status = self.getReg(REG_STA)
        self.setReg(REG_STA, status & 0b11111101)

    def ALARMtriggered(self):
        status = self.getReg(REG_STA)
        trig = (status & 0b00000010)
        if trig:
            self.ALARMclear()
        return trig

    def Temperature(self):
        t1 = self.getReg(REG_TEMP)
        t2 = self.getReg(REG_TEMP + 1)
        if t1>0x7F:
            return t1 - t2/256 -256
        else:
            return t1 + t2/256