2022/09/16

RaspberryPiでI2Cを使って温湿度センサSHT31と通信する


RaspberryPiには、I2Cという通信インターフェースが予め搭載されています。
I2Cを使うと、様々なセンサやデバイスと通信を行うことができます。

本記事では、SHT31という温湿度センサとI2Cで通信する方法をまとめています。
以下の手順で説明しています。

  1. I2Cを有効にする
  2. ラズパイとSHT31を導線で繋ぐ
  3. 接続確認する
  4. pythonでI2C通信を行うプログラムを作成する
  5. 取得したセンサ値をテキストファイルに追加していく

1. I2Cを有効にする

ラズパイの設定メニューでI2Cを有効化します。

RaspberryPiのI2Cを有効にする方法1 RaspberryPiのI2Cを有効にする方法2

2. ラズパイとSHT31を導線で繋ぐ

ラズパイのI2Cのピンは以下になります。

RaspberryPiのピンの解説

(公式ページより引用)


SHT31のI2Cのピンにそれぞれ合うように接続します。

RaspberryPiとSHT31の接続の写真

3. 接続確認する

ラズパイのターミナルコマンドで、I2Cの接続確認ができます。
以下のように打ち込みます。

i2cdetect -y 1

正常に接続できていれば、下記のようにI2Cに接続されているデバイスのアドレスが表示されます。

RaspberryPiのI2C接続確認コマンド

4. pythonでI2C通信を行うプログラムを作成する

ラズパイのThonny Python IDEを使用します。

RaspberryPiでThonny Python IDEを開く方法 Thonny Python IDEの説明

I2C通信には、smbusライブラリを使用します。
ラズパイに標準でインストールされています。

以下のプログラムを実行すると、IDE下部のターミナル部分に温度と湿度が表示されます。

import smbus
import time

bus = smbus.SMBus(1)
address_sht31 = 0x45

bus.write_byte_data(address_sht31, 0x24, 0x00)
time.sleep(0.1)
readData = bus.read_i2c_block_data(address_sht31, 0x00, 6)
        
temp = 0.00267 * ((readData[0] << 8) + readData[1]) -45  # 温度情報
humi = 0.00152 * ((readData[3] << 8) + readData[4])      # 湿度情報

print(temp)
print(humi)

bus.write_byte_data(deviceAddress, data1, data2)

bus.read_i2c_block_data(deviceAddress, offset, bytes)

 例えば、read_i2c_block_data(0x45, 0x00, 0x06)ですと、デバイスアドレス0x45のデバイスにアクセスして、データアドレス0x00~0x05までのデータを読み出すことになります。

SHT31の制御

詳しくはSHT31のデータシートを見る必要がありますが、概要を抜き出すと以下のようになります。

■温湿度の測定実行

"0x24 0x00"を書き込むと、クロックストレッチなし高精度測定となります。
データ読み込み前に、毎回実行する必要があります。

他の命令は下記のようになっています。

SHT31のコマンド例

■データ読み出し

offsetなしで6byte分のデータを読み出します。
読み出したデータの1byte目と2byte目が温度データ、4byte目と5byte目が湿度データになっています。
換算式は以下です。

5. 取得したセンサ値をテキストファイルに追加していく

取得した温湿度データはテキストファイルに随時出力していくと、後から変化の傾向など確認できます。

from datetime import datetime

start = datetime.now()

while True:
  now = datetime.now()
  if (now - start).seconds >= 5:    # 5秒おきに測定
    start = datetime.now()
           
    with open('/home/pi/Desktop/test.txt', 'a') as f:
      data = now.strftime('%Y/%m/%d %H:%M:%S') + ',temp,' +  str(temp) + ',humi,' + str(humi) + '\n'
      f.write(data)

with open(filepath, mode) as f:

f.write(data)

ソースコード全体

import smbus
import time
from datetime import datetime

bus = smbus.SMBus(1)
address_sht31 = 0x45
start = datetime.now()

try:
    while True:
        now = datetime.now()

        if (now - start).seconds >= 5:
            start = datetime.now()
            
            bus.write_byte_data(address_sht31, 0x24, 0x00)
            time.sleep(0.1)
            readData = bus.read_i2c_block_data(address_sht31, 0x00, 6)
        
            temp = round(0.00267 * ((readData[0] << 8) + readData[1]) -45, 2)
            humi = round(0.00152 * ((readData[3] << 8) + readData[4]), 2)
    
            print(now.strftime('%Y/%m/%d %H:%M:%S'))
            print(temp)
            print(humi)
        
            with open('/home/pi/Desktop/test.txt', 'a') as f:
              data = now.strftime('%Y/%m/%d %H:%M:%S') + ',temp,' +  str(temp) + ',humi,' + str(humi) + '\n'
              f.write(data)

except KeyboardInterrupt:
    print("finish")

参考 SHT31について

SHT31は、センシリオン社の高性能な温湿度センサです。
測定可能レンジは

とかなり優秀です。


以上です。




コメント(githubのアカウントが必要です)