以前の記事では、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 のピン番号 | 説明 |
---|---|---|
VCC | 3.3V | 電源(3.3V) |
GND | GND | グラウンド |
SDA | GP4 | I2Cデータ信号 |
SCL | GP5 | I2Cクロック信号 |
※ 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通信を実装してみると、センサの仕組みがよく理解できます。ぜひ挑戦してみてください!