ArduinoでSHT40Iをライブラリなしで使う方法

ArduinoでSHT40Iをライブラリなしで使う方法
スポンサーリンク

最近、秋月電子通商からSHT40Iという高精度な温湿度センサが新たに発売されました。I²C通信で手軽に使える上、-40℃から125℃まで対応する高性能センサです。ちょうど興味があったので、さっそくArduinoと組み合わせて動作を確認してみることにしました。今回はあえてライブラリを使わず、Wireライブラリだけを使って生データを取得する方法を紹介します。I2C通信の学習にもぴったりです。また、CRCチェックなしで手軽に試す方法と、正式なCRCチェック付きで正確な値を取得する方法の2段階に分けて解説します。

スポンサーリンク

🔧 1. ハードウェア接続方法

SHT40IピンArduino Nano
VDD3.3Vまたは5V
GNDGND
SDAA4
SCLA5

配線図

🔍 I²Cアドレス確認

SHT40IがI²Cで正しく接続されているかを確認

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("I2C Scanner");
  for (byte address = 1; address < 127; ++address) {
    Wire.beginTransmission(address);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found I2C device at 0x");
      Serial.println(address, HEX);
    }
  }
}

void loop() {}

0x44 が見つかればOK

🟢 CRCチェックなしで簡単に動かしてみる

まずはCRCチェックを省略して、とりあえず動作確認するコードを試してみましょう。

#include <Wire.h>

const uint8_t SHT40_ADDR = 0x44;
const uint8_t CMD_MEASURE_HIGH_PRECISION = 0xFD;

bool checkCRC(uint16_t data, uint8_t crc) {
  uint8_t bytes[2] = { (uint8_t)(data >> 8), (uint8_t)(data & 0xFF) };
  uint8_t crc_calc = 0xFF;

  for (int i = 0; i < 2; i++) {
    crc_calc ^= bytes[i];
    for (int j = 0; j < 8; j++) {
      if (crc_calc & 0x80)
        crc_calc = (crc_calc << 1) ^ 0x31;
      else
        crc_calc <<= 1;
    }
  }
  return crc_calc == crc;
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
  delay(100);
}

void loop() {
  Wire.beginTransmission(SHT40_ADDR);
  Wire.write(CMD_MEASURE_HIGH_PRECISION);
  Wire.endTransmission();

  delay(10);

  Wire.requestFrom((uint8_t)SHT40_ADDR, (uint8_t)6);
  if (Wire.available() == 6) {
    uint16_t t_raw = (Wire.read() << 8) | Wire.read();
    uint8_t t_crc = Wire.read();
    uint16_t h_raw = (Wire.read() << 8) | Wire.read();
    uint8_t h_crc = Wire.read();

    if (checkCRC(t_raw, t_crc) && checkCRC(h_raw, h_crc)) {
      float temp = -45 + 175.0 * (t_raw / 65535.0);
      float hum = 100.0 * (h_raw / 65535.0);

      Serial.print("Temp: "); Serial.print(temp); Serial.print(" C\t");
      Serial.print("Hum: "); Serial.print(hum); Serial.println(" %");
    } else {
      Serial.println("CRC ERROR");
    }
  }

  delay(2000);
}

これで正しく表示されれば、配線とI²C通信は成功しています。
このとき必ずシリアルモニターのボーレート今回(9600)とプログラムで設定したボーレート合わせてください。

🛡️ CRCチェックありで正式に通信する

#include <Wire.h>

const uint8_t SHT40_ADDR = 0x44;
const uint8_t CMD_MEASURE_HIGH_PRECISION = 0xFD;

bool checkCRC(uint16_t data, uint8_t crc) {
  uint8_t bytes[2] = { (uint8_t)(data >> 8), (uint8_t)(data & 0xFF) };
  uint8_t crc_calc = 0xFF;

  for (int i = 0; i < 2; i++) {
    crc_calc ^= bytes[i];
    for (int j = 0; j < 8; j++) {
      if (crc_calc & 0x80)
        crc_calc = (crc_calc << 1) ^ 0x31;
      else
        crc_calc <<= 1;
    }
  }
  return crc_calc == crc;
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
  delay(100);
}

void loop() {
  Wire.beginTransmission(SHT40_ADDR);
  Wire.write(CMD_MEASURE_HIGH_PRECISION);
  Wire.endTransmission();

  delay(10);

  Wire.requestFrom((uint8_t)SHT40_ADDR, (uint8_t)6);
  if (Wire.available() == 6) {
    uint16_t t_raw = (Wire.read() << 8) | Wire.read();
    uint8_t t_crc = Wire.read();
    uint16_t h_raw = (Wire.read() << 8) | Wire.read();
    uint8_t h_crc = Wire.read();

    if (checkCRC(t_raw, t_crc) && checkCRC(h_raw, h_crc)) {
      float temp = -45 + 175.0 * (t_raw / 65535.0);
      float hum = 100.0 * (h_raw / 65535.0);

      Serial.print("Temp: "); Serial.print(temp); Serial.print(" C\t");
      Serial.print("Hum: "); Serial.print(hum); Serial.println(" %");
    } else {
      Serial.println("CRC ERROR");
    }
  }

  delay(2000);
}

📌 温湿度の変換式

SHT40Iから受け取る生データ(16ビット)は、以下の式で変換します:

  • 温度(摂氏)
    T = -45 + 175 × (raw / 65535.0)
  • 湿度(相対湿度 %)
    RH = 100 × (raw / 65535.0)

🧪 応用のヒント

以下のような応用も可能です:

  • OLEDディスプレイに表示(SSD1306など)
  • SDカードへデータログ保存
  • RTCモジュールで時刻を付加
  • 複数センサの同時制御
  • ESP32と組み合わせてWebで表示

✅ まとめ

SHT40Iは、I²C通信と基本的な数式だけで扱える温湿度センサです。ライブラリを使わずとも、Wireライブラリのみで十分に制御可能です。
まずはCRCチェックなしで簡単に動作確認し、慣れてきたらCRCチェック付きで精度を高めるのが理想です。Arduino初心者から中級者へのステップアップにぴったりの題材なので、ぜひ試してみてください。

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