MicroPythonでSHT40I温湿度センサを使う方法

MicroPythonでSHT40I温湿度センサを使う方法
スポンサーリンク

以前の記事では、SHT40I温湿度センサをArduinoでライブラリを使わず制御する方法を紹介しました。今回はその応用として、同じSHT40IセンサをMicroPython環境で制御してみました。使用したマイコンは、RP2040-ZeroやRaspberry Pi PicoなどのRP2040シリーズです。

MicroPythonはスクリプト言語で簡潔に記述できるため、I2Cセンサの動作確認やデータ処理が手軽に行えるのが魅力です。この記事では、配線方法からセンサ読み取り、AQM1602の表示などライブラリを使わない方法で詳しく紹介します。

スポンサーリンク

SHT40I

SHT40IはSensirion社製の高精度温湿度センサです。温度は-40℃から125℃、湿度は0~100%RHまで対応しており、I²Cでの通信が可能です。モジュール型の製品が秋月電子などから販売されており、すぐに使用できる状態で手に入ります。

使用したもの

  • RP2040-Zero(またはRaspberry Pi Pico)
  • SHT40Iモジュール
  • ジャンパーワイヤ
  • USBケーブル
  • 開発用PC(Thonnyエディタを使用)

今回は、RP2040-Zeroにファームウェアが書き込まれていることを前提にしておりますので、もしファームウェアの書き方が分からない場合は私のこちらのブログで確認してください。

ピン接続(RP2040-ZeroとSHT40I)

SHT40I ピン名RP2040-Zero のピン番号説明
VCC3.3V電源(3.3V)
GNDGNDグラウンド
SDAGP4I2Cデータ信号
SCLGP5I2Cクロック信号

※ I2CはMicroPythonでは I2C(0) がGP4(SDA)/GP5(SCL)に割り当てられています。

回路図

動作確認

I2Cスキャンコードを使って、SHT40I AQM1602 が見えるか確認します。

from machine import I2C, Pin
i2c = I2C(0, scl=Pin(5), sda=Pin(4))
print(i2c.scan())  # [0x44] が表示されればOK

正しく接続されていればSHT40IとAQM1602のアドレス[62,68]が表示されます。

MicroPythonコード(CRCチェックなしの簡易版)

from machine import I2C, Pin
import time

i2c = I2C(0, scl=Pin(5), sda=Pin(4))
i2c.writeto(0x44, b'\xFD')
time.sleep_ms(10)
data = i2c.readfrom(0x44, 6)

t_raw = (data[0] << 8) | data[1]
h_raw = (data[3] << 8) | data[4]

temperature = -45 + (175.0 * t_raw / 65535.0)
humidity = 100.0 * h_raw / 65535.0

print("温度: {:.2f} ℃, 湿度: {:.2f} %".format(temperature, humidity))

このコードでは、センサに測定コマンドを送り、少し待ってから6バイト分のデータを読み取っています。CRCチェックは省略していますが、基本動作を確認するには十分です。
もしCRCチェックを実装したいのであれば、下記にCRCの使いかたを説明しましたので参考にしてください。

CRC-8 チェック用関数(SHT40/SHT40I用)

def check_crc(data):
    '''Sensirion SHT40用CRC-8チェック(polynomial 0x31)'''
    crc = 0xFF
    for byte in data:
        crc ^= byte
        for _ in range(8):
            if crc & 0x80:
                crc = (crc << 1) ^ 0x31
            else:
                crc <<= 1
            crc &= 0xFF  # 8ビットにマスク
    return crc

使い方の例(6バイトのデータに対して)

# CRCチェック(data = [T_MSB, T_LSB, T_CRC, H_MSB, H_LSB, H_CRC])
if check_crc(data[0:2]) != data[2]:
    print("温度データCRCエラー")
elif check_crc(data[3:5]) != data[5]:
    print("湿度データCRCエラー")
else:
    # CRC OKなら温湿度変換へ
    t_raw = (data[0] << 8) | data[1]
    h_raw = (data[3] << 8) | data[4]
    temperature = -45 + (175.0 * t_raw / 65535.0)
    humidity = 100.0 * h_raw / 65535.0
    print("温度: {:.2f} ℃, 湿度: {:.2f} %".format(temperature, humidity))

取得したデータを AQM1602に表示する

今回はCRCチェックを省き、またクラスを使わず関数だけで簡単に表示してみました。

from machine import Pin, I2C
import time

# I2Cの初期化(I2C0を使用)
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=100000)
#  ***********SHT40Iデータ********************
def sht40():
    i2c.writeto(0x44, b'\xFD')
    time.sleep_ms(10)
    data = i2c.readfrom(0x44, 6)

    t_raw = (data[0] << 8) | data[1]
    h_raw = (data[3] << 8) | data[4]

    temp = -45 + (175.0 * t_raw / 65535.0)
    hum = 100.0 * h_raw / 65535.0
    return (temp,hum)

# AQM1602 の I2C アドレス(一般的には 0x3E)
LCD_ADDR = 0x3E  

# コマンド送信
def lcd_command(cmd):
    i2c.writeto(LCD_ADDR, bytearray([0x00, cmd]))  # 0x00 はコマンド送信

# データ送信
def lcd_data(data):
    i2c.writeto(LCD_ADDR, bytearray([0x40, data]))  # 0x40 はデータ送信

# LCD 初期化
def lcd_init():
    time.sleep(0.05)  # 電源投入後の待機
    for cmd in [0x38, 0x39, 0x14, 0x70, 0x56, 0x6C]:
        lcd_command(cmd)
        time.sleep_ms(2)  
    time.sleep_ms(200)
    for cmd in [0x38, 0x0C, 0x01]:
        lcd_command(cmd)
        time.sleep_ms(2)
        
# LCD に文字列を表示
def lcd_print(text):
    for char in text:
        lcd_data(ord(char))  # 1文字ずつ送信
        
#   LCD 文字表示位置指定 col  row
def set_cursor(col, row):
        if row == 0:
            address = 0x00 + col
        elif row == 1:
            address = 0x40 + col
        else:
            print("error")
        
        lcd_command(0x80 | address) # Set DDRAM addre
        time.sleep_ms(2)
# 実行 for 文で10かい表示
for i in range(10):
    
    lcd_init()
    tem,hum=sht40()
    print(tem,hum)    # テスト表示
    t1 = "%.2f" % tem  # 浮動小数点変数を小数点以下2桁で変換
    h1 = "%.2f" % hum
    t1="Temp " + t1
    h1="Hum  " + h1
    lcd_print(t1)
    set_cursor(0,1)
    lcd_print(h1)
    time.sleep_ms(2000)

マイクロパイソンはC++ aruduinoと違って、数値から文字列変数、または浮動小数点数変数から文字列など簡単できてしまうので初心者に非常に扱いやすい言語です。

まとめ

MicroPythonとSHT40Iの組み合わせにより、簡単に高精度な温湿度データを取得することができました。配線もシンプルで、コードもわずか十数行とコンパクトです。

MicroPythonの柔軟性を活かして、今後はCRCチェック機能の追加や、OLEDディスプレイでのリアルタイム表示、SDカードへのログ記録などにも応用していくことができるでしょう。

ライブラリに頼らず、自分の手でI2C通信を実装してみると、センサの仕組みがよく理解できます。ぜひ挑戦してみてください!

タイトルとURLをコピーしました