稼働中

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

EEPROM W/R

データ’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で作成したスクリプトは全般的にもっと改善できそうに思います。機会があれば再記載したいと思います。