ここではデジタル接続型の温度・湿度センサである Sensirionの SHT11を使って見ます。 精度が湿度±3.5%RH,温度±0.5℃(@25℃)、 分解能が湿度:0.03%RH,温度:0.01℃(いずれも代表値)と アナログセンサを使うより便利です。 ストロベリーリナックスから購入したので付属の基板に実装しました。SHT10, SHT15, SHT71, SHT75も同様に使えるはずです。
SHT11の電源電圧範囲は 2.4Vから5.5Vです。3.3V, 5V のどちらで動作するArduinoにも直結できます。 センサのプロトコルは独自となっているのでデータシートをもとに実装しました。
このスケッチを使うには、SHT11の電源をArduinoと共通にし、 SHT11のクロックピンをArduinoの2ピンに、データピンを3ピンにつなぎます。 スケッチを実行すると温度と湿度がシリアルに出力されます。 ノイズが多い環境や、値に誤りがあると問題のある場合には、 データのCRCはチェックするように改変してください。
const int SHT_SCK = 2; const int SHT_DAT = 3; const byte SHT_MeasureTemperature = B00011; const byte SHT_MeasureHumidity = B00101; const byte SHT_ReadStatusRegistor = B00111; const byte SHT_WriteStatusRegistor = B00110; const byte SHT_SoftReset = B11110; struct SHT_result { unsigned short res; byte crc; byte err; }; inline void SHT_clk() { digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_SCK, LOW); } struct SHT_result SHT_read(byte cmd) { struct SHT_result ret; ret.err = 0; digitalWrite(SHT_DAT, HIGH); pinMode(SHT_DAT, OUTPUT); // send START digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_DAT, LOW); digitalWrite(SHT_SCK, LOW); digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_DAT, HIGH); digitalWrite(SHT_SCK, LOW); // send address = 000 digitalWrite(SHT_DAT, LOW); SHT_clk(); SHT_clk(); SHT_clk(); for (int i=0; i<5; i++) { if ((cmd & B10000) != 0) digitalWrite(SHT_DAT, HIGH); else digitalWrite(SHT_DAT, LOW); SHT_clk(); cmd <<= 1; } pinMode(SHT_DAT, INPUT); digitalWrite(SHT_DAT, HIGH); // wait for ACK unsigned long cur = millis(); while (digitalRead(SHT_DAT) == HIGH) { if ((millis()-cur)>1000) { ret.err = 1; return ret; } } // send clk SHT_clk(); // wait for data to come cur = millis(); while (digitalRead(SHT_DAT) == HIGH) { if ((millis()-cur)>1000) { ret.err = 1; return ret; } } ret.res = 0; for (int j=0; j<2; j++) { for (int i=0; i<8; i++) { ret.res <<= 1; if (digitalRead(SHT_DAT) == HIGH) ret.res |= 1; SHT_clk(); } // Send ACK pinMode(SHT_DAT, OUTPUT); digitalWrite(SHT_DAT, LOW); SHT_clk(); pinMode(SHT_DAT, INPUT); digitalWrite(SHT_DAT, HIGH); } ret.crc = 0; for (int i=0; i<8; i++) { ret.crc <<= 1; if (digitalRead(SHT_DAT) == HIGH) ret.crc |= 1; SHT_clk(); } // Skip ACK SHT_clk(); // CRC をチェックした方がいい return ret; } void setup() { digitalWrite(SHT_SCK, LOW); digitalWrite(SHT_DAT, HIGH); // pull-up pinMode(SHT_SCK, OUTPUT); pinMode(SHT_DAT, INPUT); Serial.begin(9600); } void loop() { struct SHT_result ret; float h, t; ret = SHT_read(SHT_MeasureHumidity); if (ret.err != 0) return; h = -4.0 + 0.0405*ret.res -2.8*0.000001*ret.res*ret.res; Serial.print(ret.res >> 8, HEX); Serial.print(ret.res & 0xff, HEX); Serial.print(" "); Serial.print(ret.crc, HEX); Serial.print(" "); ret = SHT_read(SHT_MeasureTemperature); if (ret.err != 0) return; t = -40.00 + 0.01*ret.res; Serial.print(ret.res >> 8, HEX); Serial.print(ret.res & 0xff, HEX); Serial.print(" "); Serial.print(ret.crc, HEX); Serial.print(" "); Serial.print(h); Serial.print("% "); Serial.print(t); Serial.print("C"); Serial.println(""); delay(1000); }
上記のスケッチです