マイクロビット(e_19)DS3231 リアルタイムクロックモジュール(3)
RTC DS3231 AT24C32
前回のDS3231を搭載したリアルタイムクロック(RTC)モジュールの続きです。DS3231には温度レジスタがあります。またモジュールにはAT24C32 32Kビット(4Kバイト)のEEPROMも付いています。温度の読出しとEEPROMの動作を確認しようと思います。
温度の読出し
温度のデータは0x11、0x12のレジスタにあります。符号付きの10bitのデータになります。UpperByteにLowerByteの2bitを加えた10bitで示されます。精度は0.25℃/bitです。温度データは64秒ごとにの更新されるようです。詳細はデータシートを参照して下さい。
from microbit import *
#RTC DS3231 0x68(104)
adr_rtc=0x68
# 2'complement 符号付き計算
def s_comp(value):
bits=10 # 10ビット
a = value[2:] # 0bを除く
b_dat = '0'*(bits-len(a)) + a # 0を埋める
# 最上位ビット状態で符号を付ける
conv_value = -int(b_dat[0]) << (bits-1) | int(b_dat,2)
return conv_value
# MSB(8)+LSB(2) 10bit
def add_bit(msb, lsb):
m = msb[2:] # 0bを除く
msb_dat = '0'*(8-len(m)) + m # 0で埋める
msb_8bit='0b'+msb_dat # 0bを付ける
l = lsb[2:]
lsb_dat = '0'*(8-len(l)) + l
lsb_2bit=lsb_dat[:2] # 上位2bitを抜き出す
# 10bit data = MSB a_8bit+LSB b_2bit
x_reg = msb_8bit + lsb_2bit # 10bitデータにする 文字の足し算
return x_reg
# read register レジスタを読む
def read_reg(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
# Temp Reg 0x11,0x12
r_reg=read_reg(0x11,2) # 温度レジスタ 0x11から2bytes読み出すMSB、LSB
# 10bit data
t_bit=add_bit(bin(r_reg[0]),bin(r_reg[1])) # MSB、LSBから10bitデータにする
# 2'complement 10bitの符号計算をする
t_dat=s_comp(t_bit)
print(t_bit,t_dat)
temp=0.25*t_dat # 温度換算式で温度を算出する
print('Temp=%6.2f'%temp,'℃')
実行結果(ThonnyのShellに表示されます)
DS3231のチップ温度は約22℃の結果でした。ちなみにmicro:bitビット関数で得たチップ温度は24℃でした。
>>> %Run 1205_ds3231_temp_read_0b.py
0b0001010111 87 # 10bitデータ、符号計算を表示
Temp= 21.75 ℃
>>> temperature() # micro:bitの関数で温度を表示
24
符号付きの計算例を示します。分かりやすいように4bitで示します。
ちなみに以下のように9は二進数で’0b1001’となります。符号付きに変換すると-7になります。-7を二進数にすると’-0b111’になります。これはpythonが見やすいように表示しているようです。そのため符号付きの二進数を表示するにはbin(-7 & 0xf)とする必要があります。
※上記のスクリプトで s_comp(value)の部分bits=10>>bits=4に変更して、一度、RUNさせるとs_comp(value)がThonnyのShellで使えます。ThonnyのShellに表示されます。
>>> bin(9)
'0b1001'
>>> s_comp(bin(9)) # 10bitを4にして計算
-7
>>> bin(-7)
'-0b111'
>>> bin(-7 & 0xf)
'0b1001'
>>>
4bitの符号計算の一覧を表示させてみます。
def s_comp(value):
bits=4
a = value[2:]
#0付きのc_bit桁にする 文字の足し算
b_dat = '0'*(bits-len(a)) + a
conv_value = -int(b_dat[0]) << (bits-1) | int(b_dat,2)
return conv_value
for s in range(16):
i=bin(s)
# 整数、符号付き(2の補数)、符号付きを二進数に戻す
print('%7s'%i, '%4s'%s_comp(i),'%7s'%bin(s_comp(i)) )
実行結果(ThonnyのShellに表示されます)
>>> %Run 1205_com2s_0b.py
bin(x) 符号付 bin(符号付)
0b0000 0 0b0000 # 整数を2進数 符号付き 符号付きをbin
0b0001 1 0b0001
0b0010 2 0b0010
0b0011 3 0b0011
0b0100 4 0b0100
0b0101 5 0b0101
0b0110 6 0b0110
0b0111 7 0b0111
0b1000 -8 -0b1000
0b1001 -7 -0b0111
0b1010 -6 -0b0110
0b1011 -5 -0b0101
0b1100 -4 -0b0100
0b1101 -3 -0b0011
0b1110 -2 -0b0010
0b1111 -1 -0b0001
AT24C32 のEEPROM
リアルタイムクロックモジュールに付属しているAT24C32の読み書きだけ確認します。
データシートをみると以下のように書込み先のアドレスの指定は16bit、2bytesのようです。実際の指定はAT24C32の大きさが4Kバイト(1024×4)なので0x000~0xfffまで設定できそうです。読出しも同様にアドレスの指定は16bit、2bytesです。
データ’ABC’を0x000から書込み、書込みしたデータの確認をします。ただ書込んで読み出すだけです。
スクリプトは以下のようにしました。
from microbit import *
# AT24C32 EEPROM : 0x50(80)~0x57(87) スレーブアドレスは0x57
adr_rom=0x57
# 16bit First Word Address,Second Word Address,Write bytearray
# data>>eeprom EEPROMに書込む Second Word Address、データ(ABC)3bytes
wr_dat=bytearray(5) # アドレスが2bytes、データ3bytes
wr_dat[0]=0x00 # First Word Address
wr_dat[1]=0x01 # Second Word Address
wr_dat[2]=ord('A') # データ
wr_dat[3]=ord('B')
wr_dat[4]=ord('C')
print("write_data>",wr_dat) # 書込みbytearrayデータの表示
i2c.write(adr_rom,wr_dat) # 送信
sleep(5)
# eeprom>>data EEPROMから読み出す
r_adr=bytearray(2) # 読出し開始アドレスの指定 2bytes
r_adr[0]=0x00 # First Word Address
r_adr[1]=0x01 # Second Word Address
i2c.write(adr_rom,r_adr) # アドレスデータ送信
sleep(1)
a=i2c.read(adr_rom,3) # 開始アドレスから3bytes読み出す
print("read_data>",a) # 読み出したデータの表示
print("read_hex>",hex(a[0]),hex(a[1]),hex(a[2])) # hex 表示
print("read_chr>",chr(a[0]),chr(a[1]),chr(a[2])) # chr 表示
実行結果です。(ThonnyのShellに表示されます)
以下のように、ABCのデータをEEPROMに書込み、EEPROMに書込んだデータを確認できました。
>>> %Run 1205_at24c32_eeprom_0b.py
write_data> bytearray(b'\x00\x01ABC') # 書込みデータ
read_data> b'ABC' # Readデータ
read_hex> 0x41 0x42 0x43 # hex 表示
read_chr> A B C # chr 表示
>>>
まとめ
micro:bitビットでDS3231の温度レジスタを読出し、温度データを確認しました。EEPROM AT24C32へのデータの読み書きを確認しました。アラーム条件などEEPROMに保存しておくと便利かも知れません。DS3231モジュールはデータロガーなどで使い勝手がありそうです。
DS3231で作成したスクリプトは全般的にもっと改善できそうに思います。機会があれば再記載したいと思います。