マイクロビット(e_17)DS3231 リアルタイムクロックモジュール(1)
RCT DS3231 日時カレンダ
DS3231を搭載したリアルタイムクロック(RTC)モジュールを使ってみようと思います。このRTCモジュールにはAT24C32 32Kビット(4Kバイト)のEEPROMも付いています。I2C通信で接続します。※以後は単にDS3231、モジュールと記す場合があります。
DS3231 AT24C32モジュールの外観を下図に示します。リチウムコイン電池は充電可能なLIR2032を使うそうです。けっこう価格が高いです。安価なリチウムコイン電池CR2032を使う場合はダイオードかチップ抵抗を外して充電できないようにする必要があります。※コイン電池をセットしなくても動作の確認はできます。
AT24C32のスレーブアドレスはモジュールに抵抗追加で変更できるようです。※詳細はモジュールのデータシートなど参照ください。
接続例
DS3231のデータシートをみると3.0Vで動作するので、micro:bitから電源供給できます。I2C通信で接続します。スレーブアドレスを調べると、RTC_DS3231が 0x68(104)、 EEPROM_AT24C32が 0x57(84) です。
接続は以下の図のようにしました。
micro:bitのクロック信号SCL(pin19)、データ信号SDA(pin20)とDS3231モジュールのSCL、SDAと接続します。スレーブアドレスは0x68(104)です。
以下は実体写真です。
日時カレンダの設定
データーシートをみると日時カレンダを設定するレジスタがあります。0x00~0x06です。下の表の形式に合わして日時などを書きこむだけです。
例えば、15時のデータを24h表示する場合には、0b0001_0101(0x15)を書きこむことになります。hexでみると分かりやすいかもしれません。
スクリプト
カレンダ日時の設定と設定状態の確認をします。スクリプトは以下のようにしました。ただし時間は24時間表示、曜日は日曜を’0’にしました。
from microbit import *
#RTC DS3231 0x68(104) EEPROM : 0x50~0x57
adr_rtc=0x68
# read register
def read_reg(reg,num): # reg:読込むレジスタのアドレス、num:読込むバイト数
buf=bytearray(1)
buf[0]=reg
i2c.write(adr_rtc,buf) # 読込み開始レジスタのアドレスを送信
sleep(5)
r_reg=i2c.read(adr_rtc,num) # 設定バイト数のデータを読出し
sleep(5)
return r_reg # 読出したデータを返す
# min sec date day month year>> register
def d2reg(dat): # 秒、分、日付、曜日、月、年のレジスタに送るデータ
s= (dat//10 << 4) | (dat%10)
return s
def h24reg(dat): # 時 24H形式でレジスタに送るデータ
#p= (0<<6)|(dat//10 << 4) | (dat%10)
p= (dat//10 << 4) | (dat%10)
return p
def reg2d(dat): # 秒、分、日付、曜日、月、年のレジスタデータを10進に戻す
H_bit=dat >> 4
L_bit=dat & 0x0f
d_num=H_bit*10+L_bit
#return H_bit,L_bit,d_num
return d_num
# register >> 24h
def reg24h(dat): # 時間のレジスタデータを10進に戻す
H_bit=(dat >> 4)&0b0011
L_bit=dat & 0x0f
d_num=H_bit*10+L_bit
return d_num
## ---------------------------------------------------
# 2018/5/30 23:30:45 Wed
#d=([2021, 11, 29, 20, 47, 00, 1]) この形式でカレンダ日時を入力する
def set_ds3231(d_set): # カレンダ日時データを書込むデータに変換する
d=d_set
#06h year
yy=d2reg(d[0]-2000)
#05h Mounth
mo=d2reg(d[1])
#04h date
dd=d2reg(d[2])
#02h hour
hh=h24reg(d[3])
#01h min
mm=d2reg(d[4])
#00h sev
ss=d2reg(d[5])
#03h weekday
ww=d2reg(d[6])
set_data=[ss,mm,hh,ww,dd,mo,yy] # レジスタ順に変換したデータを並べる
#### set_dataに書き込み開始アドレス0x00を追加してバイトアレイ化する
#### write regista addr
st_reg=0
wr_data=[st_reg,ss,mm,hh,ww,dd,mo,yy]
set_buf=bytearray(8) # データが8個あるので
# k << bytearrayの位置
k=0
for x in wr_data:
set_buf[k]=x
k=k+1
i2c.write(adr_rtc,set_buf) # データを送信(書込む)する
sleep(5)
print('## SET DONE ##')
def read_ds3231(): # カレンダ日時レジスタから読出し、設定値を確認
wday=['sun','mon','tue','wed','thu','fri','sat'] # 表示用 日曜が0
#00h - 0x07h RTC-Data
rtc_data=read_reg(0x00,7) # 関数へ 0x00から7バイト読込む
#print( list(rtc_data) )
r_yy=reg2d(rtc_data[6])+2000
#05h Mounth
r_mo=reg2d(rtc_data[5])
#04h date
r_dd=reg2d(rtc_data[4])
#02h hour
r_hh=reg24h(rtc_data[2])
#01h min
r_mm=reg2d(rtc_data[1])
#00h sec
r_ss=reg2d(rtc_data[0])
#03h weekday
r_ww=reg2d(rtc_data[3])
r_wd=wday[r_ww]
print('DS3231 DATA READ')
print(r_yy,'/',r_mo,'/',r_dd,' ',r_wd,' ',r_hh,':',r_mm,':',r_ss)
# ここに時計カレンダ設定値を記載すればよい
# 2021/11/30 11:30:45 thu ( 0:sun 1:mon 2:tue 3:wed...)
s=([2021, 12, 10, 15, 33, 15, 3])
print("DS3231 set_data",s)
# 確認だけならset_ds3231をコメントアウトする
set_ds3231(s)
read_ds3231()
実行結果
>>> %Run 1130_ds3231_day_time_set_0b.py
DS3231 set_data [2021, 12, 10, 15, 33, 15, 3] # 設定するカレンダ日時のデータ(入力値)
## SET DONE ##
DS3231 DATA READ
2021 / 12 / 10 wed 15 : 33 : 15 # 設定されたデータの確認
カレンダの日時設定が出来たようです。
まとめ
DS3231モジュールのカレンダ日時を作成したスクリプトで設定できました。これでmicro:bitビットでリアルタイムが確認できると思います。