稼働中

Raspberry Pi Pico(d_13)RCTモジュール 温度データロガー

温度データロガー (I2C)

DS3231 RTCモジュールにはDS3231とAT24C32(EEPROM)が搭載されています。
RCTモジュールの外観や接続例は記事d_11d_12を参照ください。
DS3231で温度測定ができます。測定した温度をEEPROMに記録させたいと思います。

スクリプト

温度記録のスクリプトは以下のようにしました。
I2C通信にはI2C1のSDA(GP10)SCL(GP11)を使いました。
自作モジュールDS3231c.py(記事s_09)、AT24C32c.py(記事s_10)を使っています。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。
■ 記録する内容
記録の間隔   0x00~0x01
記録の点数   0x02~0x03
記録の開始時刻 0x04~0x09 曜日データを省いた値
温度データ記録 0x10~ 記録点数分
※DS3231はあらかじめ「時刻」と「Alarm Mask Bitsが秒ごと、分ごと」に設定されているものとしています。


DS3231_templog_01b.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import I2C,Pin
import time
from DS3231c import DS3231
from AT24C32c import AT24C32

a=DS3231(1, 10)  #init(num=1,sda=10)
b=AT24C32(1, 10) #init(num=1,sda=10,slave=0x57)

# カレンダデータをバイトアレイデータに変換
def c_arry(l_dat):
    b_array=bytearray(len(l_dat))
    for i in range(len(l_dat)):
        if i==0:
            b_array[0]=int(l_dat[0])-2000       #下2桁だけに
        else:
            b_array[i]=int(l_dat[i])
    return b_array

# リスト数値データをバイトアレイデータに変換
def b_arry(l_dat):
    b_array=bytearray(len(l_dat))
    for i in range(len(l_dat)):
        b_array[i]=int(l_dat[i])
    return b_array

# 数値を16bit 2bytesで示す H,L hex(1024)'0x0400' hl_sep(1024) > (4, 0)
def hl_sep(val):
    h=val >> 8       #H
    l=val & 0x00ff   #L
    #print(val,hex(val),hex(h),hex(l))
    return h,l
# msb,lsb(8,8bit)から数値に戻す hl_put(4,0) > 1024
def hl_put(h,l):
   val=(h << 8)| l
   #print(h,l,hex(val))
   return val

## インターバル値の設定とEEPROMへ保存
def wep_interv():
#    intval=num_sec # interval-time sec
#    volume=vol     # measure count 
    # インターバルの秒数をEEPROMに保管する
    l_val=hl_sep(intval)        # H,Lに分けたリストデータにする
    s_val=b_arry(l_val)         # リスト値をbytearrayに変換する
    b.d_write(s_val,r_pos=0x00) # 0x00から保管
    
    # 同様にvolumeデータを格納する
    l_vol=hl_sep(volume)
    s_vol=b_arry(l_vol)
    b.d_write(s_vol,r_pos=0x02) #write bytearray data

## 開始日時をEEPROMに保存する
def wep_stime():
    st_time=a.read_Cal()    #カレンダリスト値を得る
    s_time=st_time[0:6]     #曜日データ(文字)を除外
    buf=c_arry(s_time)      # カレンダリスト値をbytearrayに変換する
    b.d_write(buf,r_pos=0x04)       # bytearray dataを書込む

## EEPROM save data, temp record
# interval sec 間隔 秒単位 あらかじめA1Mの設定をper sec にしておく
def d_record():
    wep_interv()    #intval,volumeを記録 0x00~0x03
    wep_stime()     #start calenderを記録 0x04~0x09

    cnt=0                   # アラームフラグのリセット回数(測定間隔)
    r_pos=0x10              # 0x10からデータを記録
    a.reset_Aflag()         # アラームフラグをリセット

    print('Recoding -----',a.read_Cal(),intval,per,'x',volume,'times')
    
    while True:
        flag=a.read_Aflg()
        if per == 'min':            #分ごと?
            chk=(flag >>1)
        else:
            chk=(flag & 0b01)       #秒ごと?

        if chk ==1:
            a.reset_Aflag()     #分or秒ごとにフラグセット
            cnt += 1            #結局、分or秒数をカウント cnt(sec-min)
                          
            if cnt == intval:       # per step min
                # 1data ga 2byte nanode volume*2 no regi-address
                temp=a.read_Temp()                
                          # ------------- save data
                l_temp=hl_sep(int(temp/0.25))
                buf=b_arry(l_temp) # ------------- save data bytearray(2)
                b.d_write(buf,r_pos) #write bytearray data

                print(a.read_Cal(),temp,buf,hex(r_pos))  #記録例2ではコメントアウト
                
                cnt=0
                r_pos = r_pos + 2       # 0x10~ 2byte
                if r_pos >= (0x10 + volume*2):
                    break
                        
        time.sleep_ms(100) # 無くてもいい

## EEPROMに保存されているインターバル値と開始日時を表示
def disp_conf():
    conf=b.d_read(10,r_pos=0x00)
    print('Interval,Volume------------')
    r_cal=conf[4:]
    l_cal=[]
    for i in range(len(r_cal)):
        if i == 0:
            l_cal.append(r_cal[0]+2000)
        else:
            l_cal.append(r_cal[i])
    print('Rec_start=',l_cal)

    r_interv=(conf[0] << 8) + conf[1]
    print('Interval=',r_interv, per)
    
    r_volume=(conf[2] << 8) + conf[3]
    print('Volume=',r_volume) 

## EEPROMに保存されている温度データを表示
def disp_data():
    print('Temp EEPROM---------')
    r_temp=b.d_read(volume*2, r_pos=0x10)

    for i in range(volume):
        t=(r_temp[i*2] << 8) + r_temp[i*2+1]
        print(i,t*0.25)

## 測定パターン(測定間隔(秒or分)、測定点数)
def m_ptn(e,f,g):
    global intval
    global volume
    global per
    per=e            # 'min'or'sec'
    intval=f
    volume=g

## main------------------------
m_ptn('sec',2 ,5)   # 2sec間隔で5点測定

b.erase_EP()        # EEPROMデータを全消去
#b.read_EP()        # 書込みのあるデータを表示

d_record()          # 温度データ記録開始

disp_conf()         # 記録設定表示

disp_data()         # 記録された温度データを表示

部分説明

■m_ptn(e,f,g)
e:間隔の単位‘sec’or’min’
f:間隔の数値
g:測定点数

■d_record()
温度データを記録します。

■disp_conf()
測定開始時刻、間隔時間、記録点数を表示します。

測定は開始時刻からアラームフラグがセットされた時刻になります。
例えば、分ごとの記録なら
[‘2023’, ‘1’, ‘4’, ’11’, ’53’, ’25’, ‘wed’]に開始の場合、
初の記録は
[‘2023’, ‘1’, ‘4’, ’11’, ’54’, ‘0’, ‘wed’]になります。

■disp_data()
記録した温度を表示します。

実行結果

温度を2sec間隔で5点測定しEPPROMに記録。
記録した測定パターン、温度データを表示しています。
結果は以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
Recoding ----- ['2023', '1', '4', '12', '3', '58', 'wed'] 2 sec x 5 times
['2023', '1', '4', '12', '4', '0', 'wed'] 17.75 bytearray(b'\x00G') 0x10
['2023', '1', '4', '12', '4', '2', 'wed'] 17.75 bytearray(b'\x00G') 0x12
['2023', '1', '4', '12', '4', '4', 'wed'] 17.75 bytearray(b'\x00G') 0x14
['2023', '1', '4', '12', '4', '6', 'wed'] 17.75 bytearray(b'\x00G') 0x16
['2023', '1', '4', '12', '4', '8', 'wed'] 17.75 bytearray(b'\x00G') 0x18
Configuration------------
Rec_start= [2023, 1, 4, 12, 3, 58]
Interval= 2 sec
Volume= 5
Temp EEPROM---------
0 17.75
1 17.75
2 17.75
3 17.75
4 17.75
>>> 

次に、測定中の表示部はコメントアウトして、
m_ptn(‘min’,15 ,48) # 15min間隔で48点測定(12時間)
で記録し、記録した測定条件と温度データを表示してみました。


>>> %Run -c $EDITOR_CONTENT
Recoding ----- ['2023', '1', '5', '20', '29', '50', 'thu'] 15 min x 48 times

>>> disp_data()
Temp EEPROM---------
0 18.75
1 19.0
2 17.5
3 16.25
4 15.5
5 15.0
(省略)
40 10.5
41 10.5
42 10.5
43 10.5
44 10.5
45 10.75
46 10.75
47 10.5

表示したデータを表計算ソフトでグラフにしてみました。
うちの家は断熱が悪いようで朝にはかなり室温が下がっていました。
DS3231 室温データロガー

まとめ

Raspberry Pi PicoでDS3231 RTCモジュールを温度データロガーのように使えました。温度測定データをEPPROMに記録し確認することができました。