稼働中

マイクロビット(c_13)DS3231 用モジュール (1)

DS3231(I2C)  DS3231_c2.py

DS3231はリアルタイムクロックです。DS3231モジュールにはAT24C32 4KバイトのEEPROMも付いています。※詳細はデータシートを参照ください。
DS3231モジュールで使う自作の’DS3231_c2.py’を作成しました。使い方だけを記載します。(※記事e_017、記事e_018を元にクラスにしました。)
‘DS3231_c2.py’は末尾にあります。使い方だけを記載します。

使い方

ファイル転送
micro:bitへ’DS3231_c2.py’を送った後でimportして使います。micro:bitに直接ファイルをアップロード出来ない場合(Thonny 3.1.12など)は、microfsなどを使ってアップロードします。
※microfsについては、当サイト内のこちらを参照ください。
※ファイルシステムへ送って使わないとメモリーエラーになると思います。(micro:bit V1)

メソッド
‘DS3231_c2’をimportすると「read_Cal, write_Cal, read_Adata, write_Adata, read_Aflg, reset_Aflag, read_Aie, set_Aie」のメソッドが使えるようになります。
DS3231()で初期化します。
(1)read_Cal()
カレンダデータを読出します。
[‘2022’, ‘7’, ‘7’, ’17’, ‘0’, ’56’, ‘thu’]の形式で返します。
(2)write_Cal(l_data)
カレンダデータを書込みます。
l_data=[2022, 07, 07, 17, 00, 56, 4]のリストデータで与えます。
(3)read_Adata()
アラームデータを読出します。
レジスタ0x07~0xdを読出しbin形式で表示します。
(4)write_Adata(ldata)
アラームデータを書込みます。
ldata=[a1,a2,a1m,a2m,a1d,a2d]の形式で与えます。
a1,a2は0x07~0xdにセットするsec,min,hour,day/dateのアラーム値です。
以下は例です。
a1=[30,59,23,30] # sec,min,hour,day/date
a2=[21,23,30] # min,hour,day/date
a1m,a2m,a1d,a2dはアラームマスクビットの設定値です。
以下は例です。
a1m=[0,1,1,1] #alarm1 mask(bit7)[1,1,1,1][0,1,1,1][0,0,1,1][0,0,0,1]
a2m=[0,1,1] #alarm2 mask(bit7)[1,1,1][0,1,1][0,0,1]
a1d=[”] #day/date ”,’0′,’1′ ‘0’or’1’なら自動的に a1m=[0,0,0,0]になります。
a2d=[”] #day/date ”,’0′,’1′ ‘0’or’1’なら自動的に a2m=[0,0,0]になります。
(5)read_Aflg()
アラームフラグ |A2F|A1F|を読み値を返します。
(6)reset_Aflag()
アラームフラグ|A2F|A1F|をリセットします。
(7)read_Aie()
割込み許可|INTCN|A2IE|A1IE|を読み値を返します。
(8)set_Aie(num=3)
割込み許可|A2IE|A1IE|を設定します。デフォルトは|A2IE|A1IE|が|1|1|の3です。

使用例1

カレンダデータの設定、確認


DS3231_ex1.py
from microbit import *
from DS3231_c2 import DS3231

a=DS3231()    # instance
## Calendar setting
dat=[2022, 07, 07, 17, 00, 56, 4]
a.write_Cal(dat)
##------------------------------------
# カレンダデータの読出し
r_data=a.read_Cal()
print(r_data)

実行結果


>>> %Run DS3231_ex1.py
['2022', '7', '7', '17', '0', '56', 'thu']

使用例2

アラームデータの設定、確認


DS3231_ex2.py
from microbit import *
from DS3231_c2 import DS3231
# ゼロ穴埋め 8bit
def z_padd(dat):  # int
    dat=bin(dat)  # str
    value='0b'+'0'*(8-len(dat[2:])) + dat[2:]      # str 8bit
    return value

a=DS3231()    # instance
## アラームマスク設定
# 一致sec,min,hour,day/date
a1=[30,59,23,30] # sec,min,hour,day/date
a2=[21,23,30]    #     min,hour,day/date
# ALARM MASK BITS  [1,0,1,0]のような飛び設定は出来ない データシート参照
a1m=[0,1,1,1]   #alarm1 mask(bit7)[1,1,1,1][0,1,1,1][0,0,1,1][0,0,0,1]
a2m=[0,1,1]     #alarm2 mask(bit7)[1,1,1][0,1,1][0,0,1]
a1d=['']        #day/date '','0','1' 自動的に a1m=[0,0,0,0]
a2d=['']        #day/date '','0','1' 自動的に a2m=[0,0,0]

set_ldata=[a1,a2,a1m,a2m,a1d,a2d]
# wirte mach mask Adata
print(set_ldata)
a.write_Adata(set_ldata)
sleep(200)

##----------------------------------------
# アラームマスクデータの読出し
r_reg=a.read_Adata()
sleep(100)
print('read_Adata')
for i in range(7):    
    print(hex(7+i),z_padd(r_reg[i]))

実行結果


>>> %Run DS3231_ex2.py
[[30, 59, 23, 30], [21, 23, 30], [0, 1, 1, 1], [0, 1, 1], [''], ['']]
read_Adata
0x7 0b00110000
0x8 0b11011001
0x9 0b10100011
0xa 0b10110000
0xb 0b00100001
0xc 0b10100011
0xd 0b10110000
>>> 

使用例3

アラームフラグの読み、リセット、割込み許可の設定、確認


DS3231_ex3.py
from microbit import *
from DS3231_c2 import DS3231

a=DS3231()

##------------------------------------
# アラームフラグ、割込み許可状態の読出し
# read_Aflg reset_Aflag  read_Aie  set_Aie
print('|A2F|A1F|=',bin(a.read_Aflg()))
print('|INTCN|A2IE|A1IE|=',bin(a.read_Aie()))
##------------------------------------
# 割込み許可|A2IE|A1IE|の設定、確認
a.set_Aie(3)
print('|INTCN|A2IE|A1IE|=',bin(a.read_Aie()))
##------------------------------------
# アラームフラグリセット、確認
a.reset_Aflag()
print('|A2F|A1F|=',bin(a.read_Aflg()))

実行結果


>>> %Run DS3231_ex3.py
|A2F|A1F|= 0b1
|INTCN|A2IE|A1IE|= 0b100
|INTCN|A2IE|A1IE|= 0b111
|A2F|A1F|= 0b0
>>> 

DS3231 用モジュール


DS3231_c2.py
from microbit import *
#RTC DS3231
class DS3231:
    def __init__(self):
        # slave address hex(104)'0x68'
        self.adr=0x68        
    # 書込むデータを上位下位に分ける hex表示にすると読視できる
    def s_dat(self,dat):
        s_dat=(dat//10 << 4) | (dat%10)
        return s_dat

    ## d_lst(日時list-data)を各レジスタに書込み
    def write_Cal(self,l_data):
        dat=l_data
        s_reg=bytearray(1)
        s_reg[0]=0x00        # write start regi-num
        # Callender 24H表示 2022/12/04 14:15:00 wed ( 0:sun 1:mon 2:tue 3:wed...)
        #dat=([2022, 11, 23, 12, 34, 56, 0]) >> 7bytes
        buf=bytearray(7)
        # 0x00 seconds 
        buf[0]= self.s_dat(dat[5])
        # 0x01 minutes 
        buf[1]= self.s_dat(dat[4])
        # 0x02 hour 
        buf[2]= self.s_dat(dat[3])
        # 0x03 day of week
        buf[3]= self.s_dat(dat[6])
        # 0x04 date
        buf[4]= self.s_dat(dat[2])
        # 0x05  month  over century 
        buf[5]= self.s_dat(dat[1])
        # 0x06  year
        buf[6]= self.s_dat(dat[0]-2000)

        # writing to registers
        s_buf=bytearray(8)
        # regi-adr(1) + writedata(7)
        s_buf=s_reg+buf  # bytearray 足算可 開始レジスタ+データ
        i2c.write(self.adr,s_buf)

    ## write Adata
    def write_Adata(self,ldata):
        a1= ldata[0]
        a2= ldata[1]
        a1m=ldata[2]
        a2m=ldata[3]
        a1d=ldata[4]
        a2d=ldata[5]
        
        # write alarm data set-regi 0x07-0xd
        s_reg=bytearray(1)
        s_reg[0]=0x07              # write start regi-num

        buf=bytearray(7)
        for i in range(4):
            buf[i]=self.s_dat(a1[i])    #一致データを上位下位に変換する
            # mask bit
            if a1d[0]=='':
                buf[i]=buf[i] | a1m[i]<< 7
            else:
                buf[i]=buf[i] & 0x7f  # AM bit7= '0'               
                if a1d[0]=='1':
                    print('a1d=1')
                    buf[3]=buf[3] | 0x40  # DY/DT bit wo '1'          
            
        for i in range(3):
            buf[i+4]=self.s_dat(a2[i]) #設定データを上位下位に変換する
            #print('a2 mach-data',hex(buf[i+4]))
            # mask bit 
            if a2d[0]=='':
                buf[i+4]=buf[i+4] | a2m[i]<< 7
            else:
                buf[i+4]=buf[i+4] & 0x7f  # AM bit7 '0'               
            if a2d[0]=='1':
                buf[6]=buf[6] | 0x40  # DY/DT bit wo '1'

        # regi-addres,write-bytearray
        s_buf=s_reg+buf      # bytearrayなら足し算できる 開始レジスタ+データ
        i2c.write(self.adr,s_buf) # write mach data 

    # read 1-register 
    def read_reg(self,reg):
        s_reg=bytearray(1)
        s_reg[0]=reg
        i2c.write(self.adr,s_reg)
        read_reg=i2c.read(self.adr,1)
        return read_reg

    ## write |A2IE|A1IE| Control/Status(0x0e)
    def set_Aie(self,s_num=3):
        r_ie=self.read_reg(0x0e)[0] & 0xfc #|A2IE|A1IE| reset site kara kakikomu
        aie=s_num # 00,01,10,11(0,1,2,3)
        buf=bytearray(2)
        buf[0]=0x0e
        buf[1]=r_ie | aie
        i2c.write(self.adr,buf)

    # read register 24H nara saiku nai node sono mama de yoi
    ## reading to registers
    def read_Cal(self):
        wday=['sun','mon','tue','wed','thu','fri','sat']
        s_reg=bytearray(1)
        s_reg[0]=0x00        # write start regi-num

        # write regi-add send
        i2c.write(self.adr,s_reg)
        # read data
        r_reg=i2c.read(self.adr,7)
        
        #読み出したデータを可読に変換
        r_dat=[]
        for i in range(7):
            a=hex(r_reg[i])[2:]  #a='0x36' a[2:]='36' 0xを除く文字列に
            if i==3:             # 0x03 曜日に
                a=wday[int(a)]
            if i==6:
                a='20'+a         # 0x06 西暦に
            #print(i,a)
            r_dat.append(a)
        # [::-1][0:3] [::-1][4:7] [::-1][3:4]
        # 逆ソートしてから見やすい日時に並べ替え
        r_cal=r_dat[::-1][0:3]+r_dat[::-1][4:7]+r_dat[::-1][3:4]
        return r_cal

    # Alarm Data_Flag
    ## read alarm data
    def read_Adata(self):
        s_reg=bytearray(1)
        s_reg[0]=0x07
        i2c.write(self.adr,s_reg)
        r_reg=i2c.read(self.adr,7)
        return r_reg
    
    ## read Alarm Flag |A2F|A1F|
    def read_Aflg(self):
        a_flag=self.read_reg(0x0f)[0]& 0x03
        return a_flag

    # INTCON Alarm INT Enabel
    ## read |INTCN|A2IE|A1IE| Control/Status(0x0e)
    def read_Aie(self):
        a_ie= self.read_reg(0x0e)[0] & 0x07
        return a_ie
    ## reset Alarm Flag |A2F|A1F|
    def reset_Aflag(self):
        r_reg=self.read_reg(0x0f)
        buf=bytearray(2)
        buf[0]=0x0f
        buf[1]=r_reg[0] & 0xfc   # 0b_1111_1100
        i2c.write(self.adr,buf)