【Raspberry Pi】温湿度センサからデータを取得する 

 在宅勤務が増えたことで、自室の環境が気になり始めるこの頃。自室の温度と湿度を管理したいと思い、温湿度センサ(SHT31)を購入しました。そのデータ取得方法を記載します。実装はPythonで実施していますが、私自身がPython初心者のため、書き方等でご指摘があればコメントをお願いします。

環境

配線

 HPより見ることができる取扱説明書と仕様書をもとにつなげていきます。取扱説明書に記載されている端子の接続先をもとにGPIOへの接続を行います。

実際に接続したものが以下の写真です。

実装

 pythonで温度と湿度を測定する処理を実装していきます。順番に実装してみます。

通信の設定

 I2C通信を使用するための設定を行います。I2Cアドレスはオープン(ADRを使用しない)のため、0x45に設定します。

import smbus

# i2cのアドレス
i2c_addr = 0x45
# SMBusモジュールの設定
bus = smbus.SMBus(1)

実行部分

 測定部分を実装する前に、実行部分を記述します。今回は「周期的連続測定コマンド」を使用するため、仕様書の以下の内容に乗っ取り、コマンドを送信します。とりあえず、繰返し精度レベルは高、測定頻度は1mps(赤枠)とします。

また終了するときは、この「周期的連続測定コマンド」を終了するため、中止のコマンドも送信します。コマンドの内容は以下の通りです。

上記の内容を踏まえ、実装したコードが以下の通りです。Ctrl+Cで終了できるようにし、取得・計算した(SHT31メソッド)のデータを表示できるようにします。SHT31メソッドの実装は次節にて。

from time import sleep

# i2c通信の設定     
bus.write_byte_data(i2c_addr, 0x21, 0x30)
sleep(1)
try:
    while True:
        data = SHT31()
        print( str('{:.4g}'.format(data[0])) + "C" )
        print( str('{:.4g}'.format(data[1])) + "%" )
        print("------")
        sleep(1)
except KeyboardInterrupt:
    # 測定終了
    bus.write_byte_data(i2c_addr, 0x21, 0x30)
    print( "Finish!" )

温度と湿度を測定と計算

 ここが一番重要な部分ですね。温度と湿度の取得・計算を実施するSHT31メソッドを実装します。仕様書ではモジュールから取得できるデータは以下のように紹介されています。前節で記載した通り、「周期的連続測定コマンド」を使用します。読み通り方法は以下の通りです。

取得したデータは以下のように、6バイトで構成されるため、6バイト分の読み取りを行います。

温度(MSB)温度(LSB)チェックサム
湿度(MSB)湿度(LSB)チェックサム

また測定したデータはそのまま使うことができないため、計算する必要があります。取扱説明書では以下のような計算式があります。こちらの通りに計算をした結果を返すメソッドを作成します。

上記の内容をもとに実装したコードが以下の通りです。

# SHT31(温湿度センサ)の測定
def SHT31():
    bus.write_byte_data(i2c_addr, 0xE0, 0x00)
    data = bus.read_i2c_block_data(i2c_addr, 0x00, 6)

    # 温度計算
    temp_mlsb = ((data[0] << 8) | data[1])
    temp = -45 + 175 * int(str(temp_mlsb), 10) / (pow(2, 16) - 1)

    # 湿度計算
    humi_mlsb = ((data[3] << 8) | data[4])
    humi = 100 * int(str(humi_mlsb), 10) / (pow(2, 16) - 1)
    return [temp, humi]

コード全体

 最終的なコードは以下です。

import smbus
from time import sleep

# i2cのアドレス
i2c_addr = 0x45
# SMBusモジュールの設定
bus = smbus.SMBus(1)

# SHT31(温湿度センサ)の測定
def SHT31():
    bus.write_byte_data(i2c_addr, 0xE0, 0x00)
    data = bus.read_i2c_block_data(i2c_addr, 0x00, 6)

    # 温度計算
    temp_mlsb = ((data[0] << 8) | data[1])
    temp = -45 + 175 * int(str(temp_mlsb), 10) / (pow(2, 16) - 1)

    # 湿度計算
    humi_mlsb = ((data[3] << 8) | data[4])
    humi = 100 * int(str(humi_mlsb), 10) / (pow(2, 16) - 1)
    return [temp, humi]

# i2c通信の設定     
bus.write_byte_data(i2c_addr, 0x21, 0x30)
sleep(1)
try:
    while True:
        data = SHT31()
        print( str('{:.4g}'.format(data[0])) + "C" )
        print( str('{:.4g}'.format(data[1])) + "%" )
        print("------")
        sleep(1)    
except KeyboardInterrupt:
    # 測定終了
    bus.write_byte_data(i2c_addr, 0x21, 0x30)
    print( "Finish!" )

実行

 あとは保存して実行するだけです。以下のように表示されます。実際に作成してみた方はいかがでしたでしょうか?データの測定に関する設定やデータの計算などいろいろ実装する内容があるかと思います。何通りも設定方法があるため、いじってみてください。

$ python3 measure_temp_humi.py 
19.74C
65.34%
------
19.81C
65.25%
------
19.8C
65.28%
------
^CFinish!