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

🔍 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初心者から中級者へのステップアップにぴったりの題材なので、ぜひ試してみてください。