マイクロビット(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)