DHT22
from http://www.henteko.org/fswiki/wiki.cgi?page=%B2%B9%C5%D9%A1%A6%BC%BE%C5%D9%A5%BB%A5%F3%A5%B5%A1%BC%A4%CE%B7%D0%C7%AF%CE%F4%B2%BD%A4%CB%A4%C4%A4%A4%A4%C6
from https://bokunimo.net/arduino/humidity.html
Aosong AM2302 / DHT22 / RHT03
GROVE SEN11301P / DHT11
Aosong AM2302 / DHT11共通 Arduino接続回路図
湿度センサーSHT-71とDHT22(AM2302)のバラつきの比較
/*********************************************************************
AM2302 DHT22の簡易湿度計 for Arduino
(sparkfun SEN-10167 Aosong RHT03 AM2302 MaxDetect RHT03)
本ソースリストおよびソフトウェアは、ライセンスフリーです。
個人での利用は自由に行えます。著作権表示の改変は禁止します。
Copyright (c) 2012-2014 Wataru KUNINO
http://www.geocities.jp/bokunimowakaru/
*********************************************************************/
/*
参考文献:
・DHT 11 Humidity & Temperature Sensor(D-Robotics社HDT用 IF)
D-Robotics 7/30/2010
・AM2302 Product Manual
Aosong (www.aosong.com)
・Grove - Temp&Humi Sensor [SEN11301P] Seeed Studio Bazaar
http://www.seeedstudio.com/depot/grove-temphumi-sensor-p-745.html
・Digital-output relative humidity & temperature sensor/module DHT22
Aosong Electronics Co.,Ltd http://www.humiditycn.com
・Arduinoをはじめよう (オライリージャパン)
Massimo Banzi著 船田功訳
・Arduino 日本語リファレンス
http://www.musashinodenpa.com/arduino/ref/index.php
*/
#define DHTport 17 // DHT_DATAポート番号(ANALOG 3)
#define SD_CS 10 // SDカードCS端子(デフォルト=10)
#include <SD.h>
const static byte DHTtype= 22; // AM2302時はDHT=22にする
// (#ifdefが使えないかった)
// DHTポートの初期化
void DHTInit(void) {
pinMode(DHTport,INPUT);
delay(250);
}
// DHT TSシーケンス
byte DHTTSSeq(void) {
byte dht11_in;
// start condition
// 1. pull-down i/o pin from 18ms
digitalWrite(DHTport, LOW);
pinMode(DHTport,OUTPUT);
if(DHTtype==22) delay(1);
else delay(30);
pinMode(DHTport,INPUT);
delayMicroseconds(20+40); // High 20us + Slave ACK 80us/2
dht11_in = digitalRead(DHTport); // 正常時 = LOW
if(dht11_in){
Serial.println("dht start condition 1 not met");
return(1);
}
delayMicroseconds(80);
dht11_in = digitalRead(DHTport); // 正常時 = HIGH
if(!dht11_in){
Serial.println("dht start condition 2 not met");
return(1);
}
while( digitalRead(DHTport) ); // LOW待ち
return(0);
}
// DHTデータ受信
byte read_dht11_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
while( !digitalRead(DHTport) ); // High待ち
delayMicroseconds(49); // 28us or 70us
if( digitalRead(DHTport) ){
result |=(1<<(7-i));
while( digitalRead(DHTport) ); // wait '1' finish
}
}
return result;
}
// DHT ACK
void DHT_ACK(void) {
while( digitalRead(DHTport) );
delayMicroseconds(50);
// pinMode(DHTport,OUTPUT);
// digitalWrite(DHTport, HIGH);
}
void setup() {
Serial.begin(9600);
Serial.print("DHT");
Serial.println(DHTtype,DEC);
// while( SD.begin(SD_CS) == false ){
// Serial.println("SD ERROR");
// delay(3000);
// }
}
void loop() {
byte dht11_dat[5];
byte dht11_check_sum;
byte i;
File file;
char filename[] = "dht_hum.csv";
char Str[16];
float hum,temp;
DHTInit();
DHTTSSeq();
for (i=0; i<5; i++) dht11_dat[i] = read_dht11_dat();
DHT_ACK();
dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
if(dht11_dat[4]!= dht11_check_sum){
Serial.println("DHT11 checksum error");
}
/* 表示 */
if(DHTtype==22){
temp = ((float)(dht11_dat[2]&0x7F)*256.+(float)dht11_dat[3])/10;
if( dht11_dat[2] & 0x80 ) temp *= -1;
}else temp = (float)dht11_dat[2];
Serial.print("DHT TEMP = ");
Serial.print( temp , 1 );
Serial.print(" degC\n");
if(DHTtype==22) hum = ((float)dht11_dat[0]*256.+(float)dht11_dat[1])/10;
else hum = (float)dht11_dat[0];
Serial.print("DHT HUM = ");
Serial.print( hum , 1 );
Serial.print(" %\n");
/* SDへ出力 */
// Serial.print("writing SD ... ");
// if( (file = SD.open( filename, FILE_WRITE )) != false ){
// file.print( temp , 1 );
// file.print( ", " );
// file.println( hum , 1 );
// file.close();
// Serial.println( "done" );
// } else Serial.println("failed file open");
delay(3000);
}
これまで使用した温度・湿度センサーについてまとめてみました。値段を調べるために秋月電子でHDC1000を探したのですが、取り扱いがなくなっていました(2017年4月28日現在)。SHT31の長期評価はでていませんが、SHT11とSHT31の価格差は400円程度です。趣味で数個使用する程度であればSHT11を使用したほうが良いと思われます。ただし、SHT11は変則的(I2Cライク)なシリアル通信です。プログラミングは、正式にI2Cに対応したSHT31が簡単です。
型名 | メーカー | 価格(円) | 購入先 | 精度(短期) | 精度(長期) | 備考 |
---|---|---|---|---|---|---|
CHS-UGR | TDK | 3456(共立電子) | 忘れました | 〇 | 不明 | 湿度のみ |
HS-15P | General Electric Company(GE) | 500 | 秋月電子 | △ | 不明 | 湿度のみ |
SHT11 | Sensirion | 2095 | ストロベリーリナックス | 〇 | 〇 | |
DHT22(RHT03) | MaxDetect | 940 | ストロベリーリナックス | △ | ×(1年程度) | |
HDC1000 | Texas Instrument | 680 | 秋月電子 | 〇 | ×(1年半程度) | |
SHT31 | Sensirion | 1680 | ストロベリーリナックス | 〇 | 評価中 |
今回使用したプログラムソ
from https://bokunimo.net/arduino/humidity.html
メーカー | 型番 | 別型番 | 温度 | 湿度 | 参考価格 | 販売店(例) | ||
精度 | 分解能 | 精度 | 分解能 | |||||
SENSIRION | SHT-11 | SHT-71 | ±0.4℃ | 12bit | ±3%RH | 14bit | 2200円 | Strawberry Linux |
Aosong | DHT22 | SEN-10167 | ±0.5℃ | 0.1℃ | ±2%RH | 0.1% | 987円 | Strawberry Linux |
GROVE | SEN11301P | DHT11 | ±2℃ | 1℃ | ±5%RH | 1% | 590円 | SWITCH SCHIENCE |
General Electric | HS-15P | - | - | - | ±5%RH | Analog | 500円 | 秋月電子 |
PIC応用装置温湿度計 | TMP-HUM UNIT HS-15P + LM61 | ±2℃ | 1℃ | ±5%RH | 1% | 2300円 | 秋月電子 | |
以下はI2Cインタフェース搭載の最新デバイス | Arduino用ドライバ | |||||||
SENSIRION | SHT31 | AE-SHT31 | ±0.3℃ | 0.015℃ | ±2%RH | 0.01% | 950円 | i2c_sht31.ino |
TI | HDC1000 | AE-HDC1000 | ±0.2℃ | 0.01℃ | ±3%RH | 0.006% | 680円 | i2c_hdc.ino |
Bosch | BME280 | AE-BME280 | ±1℃ | 0.01℃ | ±3%RH | 0.008% | 1080円 | bme280.ino |
SILICON LABS | Si7021 | 各社 | ±0.4℃ | 0.01℃ | ±3%RH | 0.03% | 400円 | i2c_si7021.ino |
AM2302 / DHT22 / RHT03
Aosong AM2302はAndroid用として良く用いられています。米spark fun が取り扱っている(spark fun 型番 SEN-10167)ことで普及したものと思います。国内ではストロベリーリナックス社が「中国製激安センサ」として販売しているほか、2013年10月からは秋月電子でも取り扱われるようになりました。
型番が様々ありDHT22やRHT03と書かれていることもあります。湿度の精度はカタログ値では SENSIRION製よりも良い値のように書かれていますが、実際の実力が高いかどうかは分かりません。(製作方法は後述)
Aosong AM2302はAndroid用として良く用いられています。米spark fun が取り扱っている(spark fun 型番 SEN-10167)ことで普及したものと思います。国内ではストロベリーリナックス社が「中国製激安センサ」として販売しているほか、2013年10月からは秋月電子でも取り扱われるようになりました。
型番が様々ありDHT22やRHT03と書かれていることもあります。湿度の精度はカタログ値では SENSIRION製よりも良い値のように書かれていますが、実際の実力が高いかどうかは分かりません。(製作方法は後述)
Aosong AM2302 / DHT22 / RHT03
DHT11
GROVE向けSEN11301PはDHT11を基板に実装した製品です。以降はDHT11と記すことにします。DHT22とインタフェースに互換性がありますが、カタログ値だけでなく実力的にも湿度の精度が悪いため、湿度の高低の目安にしかなりませんでした。(製作方法は後述)
GROVE向けSEN11301PはDHT11を基板に実装した製品です。以降はDHT11と記すことにします。DHT22とインタフェースに互換性がありますが、カタログ値だけでなく実力的にも湿度の精度が悪いため、湿度の高低の目安にしかなりませんでした。(製作方法は後述)
GROVE SEN11301P / DHT11
AM2302 / DHT22 / RHT03
Aosong AM2302/DHT22/RHT03は左側の1番ピンから順に(1)VDD、(2)DATA、(3)NULL、(4)GNDとなっています。(1)VDDと(4)GNDはArduinoのPOWERの5VとGNDに接続し、(2)DATAはANALOG 3へ接続します。(2)DATAは10kΩの抵抗で5V電源にプルアップします。(2)DATAをANALOG 3以外の端子へ接続したい場合はスケッチ(ソースコード)の#defineの設定を変更します。
Aosong AM2302/DHT22/RHT03は左側の1番ピンから順に(1)VDD、(2)DATA、(3)NULL、(4)GNDとなっています。(1)VDDと(4)GNDはArduinoのPOWERの5VとGNDに接続し、(2)DATAはANALOG 3へ接続します。(2)DATAは10kΩの抵抗で5V電源にプルアップします。(2)DATAをANALOG 3以外の端子へ接続したい場合はスケッチ(ソースコード)の#defineの設定を変更します。
Aosong AM2302 / DHT11共通 Arduino接続回路図
SHT-71がDHT22(AM2302)よりも高めの値を示していますが、それが正しい値なのか個々のバラつきなのかが分かりません。そこで、SHT-71とDHT22(AM2302)をもう一つずつ購入して比較してみることにしました。下図はエアコンを使って屋内の湿度を変化させた場合の測定結果です。SHT-71同士では、ほぼ一致した結果が得られました。少なくともSHT-71同士はバラつきが少なそうであり、値も信頼できるのではないかと思います。
湿度センサーSHT-71とDHT22(AM2302)のバラつきの比較
/*********************************************************************
AM2302 DHT22の簡易湿度計 for Arduino
(sparkfun SEN-10167 Aosong RHT03 AM2302 MaxDetect RHT03)
本ソースリストおよびソフトウェアは、ライセンスフリーです。
個人での利用は自由に行えます。著作権表示の改変は禁止します。
Copyright (c) 2012-2014 Wataru KUNINO
http://www.geocities.jp/bokunimowakaru/
*********************************************************************/
/*
参考文献:
・DHT 11 Humidity & Temperature Sensor(D-Robotics社HDT用 IF)
D-Robotics 7/30/2010
・AM2302 Product Manual
Aosong (www.aosong.com)
・Grove - Temp&Humi Sensor [SEN11301P] Seeed Studio Bazaar
http://www.seeedstudio.com/depot/grove-temphumi-sensor-p-745.html
・Digital-output relative humidity & temperature sensor/module DHT22
Aosong Electronics Co.,Ltd http://www.humiditycn.com
・Arduinoをはじめよう (オライリージャパン)
Massimo Banzi著 船田功訳
・Arduino 日本語リファレンス
http://www.musashinodenpa.com/arduino/ref/index.php
*/
#define DHTport 17 // DHT_DATAポート番号(ANALOG 3)
#define SD_CS 10 // SDカードCS端子(デフォルト=10)
#include <SD.h>
const static byte DHTtype= 22; // AM2302時はDHT=22にする
// (#ifdefが使えないかった)
// DHTポートの初期化
void DHTInit(void) {
pinMode(DHTport,INPUT);
delay(250);
}
// DHT TSシーケンス
byte DHTTSSeq(void) {
byte dht11_in;
// start condition
// 1. pull-down i/o pin from 18ms
digitalWrite(DHTport, LOW);
pinMode(DHTport,OUTPUT);
if(DHTtype==22) delay(1);
else delay(30);
pinMode(DHTport,INPUT);
delayMicroseconds(20+40); // High 20us + Slave ACK 80us/2
dht11_in = digitalRead(DHTport); // 正常時 = LOW
if(dht11_in){
Serial.println("dht start condition 1 not met");
return(1);
}
delayMicroseconds(80);
dht11_in = digitalRead(DHTport); // 正常時 = HIGH
if(!dht11_in){
Serial.println("dht start condition 2 not met");
return(1);
}
while( digitalRead(DHTport) ); // LOW待ち
return(0);
}
// DHTデータ受信
byte read_dht11_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
while( !digitalRead(DHTport) ); // High待ち
delayMicroseconds(49); // 28us or 70us
if( digitalRead(DHTport) ){
result |=(1<<(7-i));
while( digitalRead(DHTport) ); // wait '1' finish
}
}
return result;
}
// DHT ACK
void DHT_ACK(void) {
while( digitalRead(DHTport) );
delayMicroseconds(50);
// pinMode(DHTport,OUTPUT);
// digitalWrite(DHTport, HIGH);
}
void setup() {
Serial.begin(9600);
Serial.print("DHT");
Serial.println(DHTtype,DEC);
// while( SD.begin(SD_CS) == false ){
// Serial.println("SD ERROR");
// delay(3000);
// }
}
void loop() {
byte dht11_dat[5];
byte dht11_check_sum;
byte i;
File file;
char filename[] = "dht_hum.csv";
char Str[16];
float hum,temp;
DHTInit();
DHTTSSeq();
for (i=0; i<5; i++) dht11_dat[i] = read_dht11_dat();
DHT_ACK();
dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
if(dht11_dat[4]!= dht11_check_sum){
Serial.println("DHT11 checksum error");
}
/* 表示 */
if(DHTtype==22){
temp = ((float)(dht11_dat[2]&0x7F)*256.+(float)dht11_dat[3])/10;
if( dht11_dat[2] & 0x80 ) temp *= -1;
}else temp = (float)dht11_dat[2];
Serial.print("DHT TEMP = ");
Serial.print( temp , 1 );
Serial.print(" degC\n");
if(DHTtype==22) hum = ((float)dht11_dat[0]*256.+(float)dht11_dat[1])/10;
else hum = (float)dht11_dat[0];
Serial.print("DHT HUM = ");
Serial.print( hum , 1 );
Serial.print(" %\n");
/* SDへ出力 */
// Serial.print("writing SD ... ");
// if( (file = SD.open( filename, FILE_WRITE )) != false ){
// file.print( temp , 1 );
// file.print( ", " );
// file.println( hum , 1 );
// file.close();
// Serial.println( "done" );
// } else Serial.println("failed file open");
delay(3000);
}
留言
張貼留言