Wio BG770A + SHT40 で温度・湿度を取得する

これまで、Wio BG770Aで主に内蔵のLTE-Mモジュールの使い方を調査してきました。 実際には、センサーから読んだ値をSORACOMやAWSなどのクラウドに送信することになるので、今回はSHT40という温度、湿度を測定するセンサーと接続して値を取得してみました。

この記事でわかること

  • SHT40をGroveで接続する手順と注意点
  • 温度・湿度を取得するコードの書き方

使用機材・環境

機材詳細
IoTデバイスWio BG770A(Seeed Studio)
センサーGrove - SHT40 温湿度センサー
開発環境PlatformIO + VSCode

Grove対応の温湿度センサーとしてDHT20もありますが、湿度精度がDHT20の±3%RHに対しSHT40は±1.8%RHと高いため、SHT40を選びました。 上位グレードのSHT41は最悪ケースの誤差がより小さいですが、品切れだったため今回はSHT40を使用しました。

本記事で使用したコードはGitHubで公開しています

Grove接続:右下のコネクタがI2C対応

Wio BG770AにはGroveコネクタが4つあります。 どれを使っても良いと思いきや、センサーでよく使われるI2Cで接続できるのは右下のコネクタだけです。

SHT40はI2C通信のため、本体右下のコネクタに接続します。

Wio BG770AにSHT40をGroveで接続した様子
右下のGroveコネクタの下にはI2Cの印字がある

Grove電源を有効化する

Wio BG770AのGroveコネクタへの電源供給は、デフォルトではOFFです。 そのため、プログラムのsetup() で明示的に有効化する必要があります。

digitalWrite(PIN_VGROVE_ENABLE, VGROVE_ENABLE_ON);
pinMode(PIN_VGROVE_ENABLE, OUTPUT);

有効化すると、基板上のGroveエリアにあるオレンジのLEDが点灯します。

Grove電源を有効化した様子
PIN_VGROVE_ENABLEをONにするとオレンジのLEDが点灯する

その後、Wire.begin() でI2Cバスを初期化します。 Wire.setClock() はI2Cの通信速度を指定するもので、100000(100kHz)は標準モードです。 I2Cには標準モード(100kHz)と高速モード(400kHz)があります。 SHT40は両方に対応していますが、ここでは互換性の高い100kHzを使っています。

Wire.begin();
Wire.setClock(100000); // 100kHz(標準モード)

I2Cアドレスを確認する

データシートによると SHT40のI2Cアドレスはモジュールによって 0x44 または 0x45 の2種類があります。

私が購入したモジュールには本体に 0x44 と書いてありました。 (書いてあるのに気づかず、両方のアドレスで試したりしていました...)

constexpr uint8_t kSht4xAddress = 0x44;

温度・湿度を取得する

計測は3ステップです。

SHT40は計測コマンドで繰り返し精度(repeatability)を選択できます。 繰り返し精度とは、同じ条件で連続計測したときの値のばらつき(ノイズレベル)のことです。 センサー自体の絶対精度(±1.8%RH / ±0.2°C)はどのモードでも変わりません。

データシート記載の値は以下のとおりです(計測時間は最大値)。

モードコマンド計測時間(最大)湿度のばらつきデメリット
0xFD8.2ms±0.08 %RH計測時間が長い・消費電力が高い
0xF64.5ms±0.15 %RH高モードよりばらつきがやや大きい
0xE01.7ms±0.25 %RHばらつきが最も大きい

電池駆動で計測頻度を上げたい場合は低モード、値の安定性を重視するなら高モードが向きます。 今回は特に制約がないため中モードを使いました。

  1. 1

    計測コマンドを送る

    0xF6(精度中)を送信します。送信後10ms待ってからデータを読み取ります。

  2. 2

    6バイトのレスポンスを読む

    温度上位・温度下位・CRC + 湿度上位・湿度下位・CRC の順で返ってきます。

  3. 3

    CRCを確認して値に変換する

    CRC8チェックでデータの破損を確認してから、変換式を適用します。

SHT40はレスポンスにCRC8チェックサムを含みます。 通信エラーによる誤った値を読まないよう、変換前にCRCを確認しています。

if (crc8(response, 2) != response[2] || crc8(response + 3, 2) != response[5]) {
  return false;
}

変換式はデータシートに記載されています。

reading.temperatureC    = -45.0f + 175.0f * static_cast<float>(temperatureTicks) / 65535.0f;
reading.humidityPercent = -6.0f  + 125.0f * static_cast<float>(humidityTicks)    / 65535.0f;
if (reading.humidityPercent < 0.0f)   reading.humidityPercent = 0.0f;
if (reading.humidityPercent > 100.0f) reading.humidityPercent = 100.0f;

変換式の性質上、湿度が0〜100%の範囲外になることがあるため、クランプしています。

この辺りのコードは書くのが大変なので、SHT4xデータシートをAI(GPT-5.4)に渡して生成しました。 コマンド・レスポンス形式・変換式がまとまっているので、こういうのはAIの得意分野ですね。

出力例

SHT4x configured at 0x44 (SCL=D4 SDA=D5)
temperature=19.89 C, humidity=63.15 %RH
temperature=19.93 C, humidity=63.13 %RH
temperature=19.92 C, humidity=63.14 %RH

2秒間隔で取得しています。値は安定していて、ばらつきは0.1°C・0.01%RH以下でした。

まとめ

Wio BG770AとSHT40のセンサーを使って、1時間程度で温度・湿度の取得ができました。

はんだ付け不要でケーブルで接続するだけでセンサーが読めるのは、Grove対応デバイスの大きなメリットですね。 マイコンを動かしてみたいなら、最初の1台はWioやM5StackなどのGrove対応デバイスを選んでおくと挫折することもないでしょう。

以前、Raspberry Pi PicoでBME680と接続した時の記事はこちらです。 センサーをはんだ付けしたり、ブレッドボード上でRaspberry Pi Picoと接続したりと色々やっています。

関連記事