湿度センサー(HDC1000/AM2302)を動作させて見ます

〔Arduinoの動かせ方入門に戻る〕


湿度を測るセンサーのHDC1000とAM2302(DHT22)を接続して動作させて見たいと思います。
このセンサーは何れも温度と湿度の両方を測る事が出来ます

HDC1000  HDC1000です、秋月電子のこちらで購入しています。
 電源は2.7V〜5.5Vで、I2C接続のモジュールです。
 このモジュールは、SDA/SCL/RDY端子に10KΩのプルアップ
 抵抗付きとなります。

 RDY(DRDYn)ピン
 データの変換が終了するとLOWを出力する信号ピンです。

 I2Cアドレス
 HDC1000自体は4種類のアドレスが選択できますが、
 このモジュールは1種類固定(0b1000000x)となります。

※ HDC1000ですが、”新規設計に用いることは推奨しません”らしく代替えがHDC2010らしい、
  秋月電子通商でも取り扱いを止めたみたいでSHT31使用のこちらを販売しているが操作方法は異なる。
  Arduinoでの記事は現状割愛します。(>人<)
  こちらspicemanさんの"Arduino-温度・湿度センサ「SHT31」の使い方"HPを参考にしましょう。
  ライブラリを使いたい人は、GitHubに在る"Seeed-Studio/Grove_SHT31_Temp_Humi_Sensor"を
  利用すれば良いでしょう。
  尚、PIC16F18326での記事ですがこちらを参考にしてください。 *1)

AM2302  AM2302です、これも秋月電子のこちらで購入しています。
 また、スイッチサイエンスのこちら(GROVE)も同じ物です。
 (DHT22と呼ばれている物もAM2302と同じ物です)

 電源は3.3V〜5.5Vで、独自の1wire通信方式です。
 SDAピンで通信し、プルアップ抵抗は必要です。
 尚、NCピンは使用しません。

 データシートは、HDC1000とAM2302とも秋月電子の販売サイト
 からダウンロードすれば良いでしょう。

《 配線図 》

配線図
 左図がHDC1000とAM2302の実態配線図です。

 電源は5Vで動作させていますが、3.3Vでも
 OKです。

 AM2302のプルアップ抵抗はデータシートでは
 センサーの信号線が30mまで5.1KΩ、
 30mより短い場合は実際の状況に応じて抵抗値を
 選べって書いて有るがぁ...
 10KΩ程でしょうか?(図では4.7KΩですがぁ...)
 因みに、3.3Vなら1m以下の長さらしい。

 ArduinoUnoならI2C端子はSCL(アナログ5番ピン)・
 SDA(アナログ4番ピン)でも接続できます。

両センサーから1秒毎に温度と湿度を読出して、
Arduinoのシリアルモニターに表示を行いました。

HDC1000はWireライブラリで読書きを行っています

AM2302こちら"seeed studio"のページに有る
ライブラリ(Humidity Temperature Sensor pro.zip)を
利用しました。

《AM2302のライブラリ》

@ "seeed studio"のページを開き
  一番下に有る「Resources」の項の[Humidity Temperature Sensor pro.zip]をダウンロードします。
  私はファイル名が長いので[DHT.zip:DHTライブラリ]と変更しました、以下この名前で記述します。

A 次に、ここのページの登録方法1を参照してインストールしましょう。

B 「ファイル」→「スケッチの例」→「DHT」→[DHTtester]を順番にクリックします。

C 上記配線図ではAM2302の接続ピンがデジタル8番ピンなので、"DHTtester"ファイルの
  "#define DHTPIN 2"を"8"と変更します。

D コンパイルと書込みを行い、シリアルモニターを起動させればデータが表示されます。

DHTライブラリの使い方を説明

DHT
 AM2302(DHT22)用関数ライブラリを使用する為に必要な宣言(初期化)を行います。
 DHT dht(pin, type, count) ;
  pin     :センサーを接続しているピンの番号
  type   :使用しているセンサーの種類(DHT11,DHT22,DHT21,AM2301)
  count :デフォルト数は6、指定せず
 "dht"の名前は任意に変更可能です。
 例)
 #define DHTPIN 8 // what pin we're connected to  #define DHTTYPE DHT22 // DHT22 (AM2302)  DHT dht(DHTPIN, DHTTYPE) ;

dht.begin( )
 使用するピン等の初期化を行います。

ans = dht.readTemperature(s)
 センサーから温度値を読み出します。
  s   :true = 華氏 false = 摂氏(デフォルト)
  ans:温度値を返す(浮動小数点) 読込み失敗なら"NAN"を返す

ans = dht.readHumidity( )
 センサーから湿度値を読み出します。
  ans:湿度値を返す(浮動小数点) 読込み失敗なら"NAN"を返す

readTemperature( )/readHumidity( )関数は、関数内で前回読出しから2秒過ぎたらセンサー値を
  読出す様になっています、って事は2秒以内にコールしても戻される値は前回の値と同じ物です。

readHumidity( )関数のみコールしても実際は温度値も読み出されています、逆もまた然りです。
  尚、読出しタイムは300ms程(この間は割り込み禁止です)かかります。

読出し失敗で"NAN"値を返すので、isnan( )関数で数値かどうかを調べて下さい

《HDC1000のライブラリ》

↓ここからArduino用サンプルスケッチファイルをダウンロードして下さい。
HDC.zip

解凍すると下の様に展開されます。
[HDC]───┬─[examples]────[HDCtester]--- HDCtester.ino
      ├ HDC.cpp
      ├ HDC.h
      └ keywords.txt
ライブラリの登録方法は、ここのページの登録方法1を参照してインストールしましょう。

HDCtester.ino  ・・・・・本体のサンプルスケッチ
HDC.cpp ・・・・・・・・・・湿度センサ(HDC1000)用関数ライブラリソース
HDC.h ・・・・・・・・・・・・ヘッダファイル
keywords.txt ・・・・・・・キーワードファイル

HDCtester.ino

HDCtester.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「HDC」→[HDCtester]
をクリック操作すればファイルが開かれます。

次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。
シリアルモニターを起動させれば3秒後に湿度と温度データが1秒毎に表示されるでしょう。
エラーが表示された場合は、接続を確かめましょう。


HDC.h

湿度センサ(HDC1000)用関数のインクルードファイルです。
関数ライブラリを利用する場合は、メニューバーの「スケッチ」→「ライブラリを使用」→「HDC」を
クリック操作すれば、"#include <HDC.h>"がスケッチに追加されます。
まぁ、手動でキー入力しても良いんですけどね。

HDC.cpp

まず利用する場合は下記2行をスケッチの最初に記述します。
#include <Wire.h>
#include <HDC.h>

setup( )関数内で下の様にI2Cを使用する為の初期化処理を記述します。("HDCtester.ino"を参照)
Wire.begin() ;   // マスターとする

デバイスのI2C通信速度は最大400KHzまでの様ですがArduinoは100KHzで初期化されます。

湿度センサ(HDC1000)用関数の使い方を説明します。

HDC
 湿度センサ(HDC1000)用関数ライブラリを使用する為に必要な宣言(初期化)を行います。
 HDC hdc(id,address) ;
  id         :デバイスの識別IDを指定します(HDC1000_ID=0x1000)
  address :デバイス(スレーブ)のI2Cアドレスを指定します(HDC1000_ADRS=0x40)
 "hdc"の名前は任意に変更可能です。
 例)
 #define HDC1000_ADRS 0x40 // HDC1000のI2Cアドレス  HDC hdc(HDC1000_ID, HDC1000_ADRS) ;// HDC1000ライブラリを生成する

アドレス設定  アドレスは7ビットで表します、左図の1〜7ビットです。
 0ビット目はR/Wでこれはデバイスに対する読書き指示ビットです。
 R/W=0 : 書き込み要求です(デバイスは受信モード)
 R/W=1 : 読み込み要求です(デバイスは送信モード)

 HDC1000自体は4種類のアドレスが選択できますが、
 このモジュールは1種類固定("1000000":40H)("1000000"+R/W)となりますので
 R/W=0書き込みなら"1000000"+"0"で0x80、R/W=1読み込みなら"1000000"+"1"で0x81となりますが
 ここでは7ビットで指定なので
 #define SENSOR_ADRS  0x40  // デバイスのI2Cアドレス
 となっています。

ans = hdc.Init( )
 デバイスの初期値設定を行う処理です。
 デバイスの動作を確かめる為にデバイスIDのチェックを行い、エラーならans=6を返します。
 コンフィギュレーションレジスタの設定は、温度・湿度とも14ビットデータで、温度・湿度の読込みは
 個別に取り込むでの設定です。尚、エラー時はレジスタの設定は行っていません
 また、設定データの内容を変更する場合は、"HDC.h"のCONFIG_DT_Hを書き換え変更して下さい。

  ans   :戻り値   0=正常終了、それ以外はI2C通信エラーです
             1=送ろうとしたデータが送信バッファのサイズを超えた(32バイトMAX)
             2=スレーブ・アドレスを送信し、NACKを受信した
             3=データ・バイトを送信し、NACKを受信した
             4=その他のエラー
             5=データ受信エラー
             6=デバイスのIDチェックエラー

ans = hdc.Read( )
 湿度・温度を読込む処理です。
 読み込まれた湿度(%)はHumi変数に、温度値(℃)はTemp変数に其々格納されます。
 尚、Humi/Temp変数はfloat変数で宣言されています。
 また、この処理は約15ms程時間が掛かります。
  ans       :戻り値、0=正常終了 それ以外 hdc.Init( )のans値を参照

  15msの処理が待てない場合は、
   コンフィギュレーションレジスタの設定"MODE"を温度・湿度の読込みは一度に取込むとして
   "DRDYn"ピンのデータ変換終了信号を割込みで利用すれば良いでしょう。

《HDC1000とAM2302の合体スケッチ》

Arduino IDE に下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
---------------------------------------------------------------------
#include <Wire.h>
#include "DHT.h"
#include "HDC.h"

#define DHTPIN           8         // AM2302接続ピン
#define DHTTYPE          DHT22     // DHT 22  (AM2302)

#define HDC1000_ADRS     0x40      // HDC1000のI2Cアドレス

HDC hdc(HDC1000_ID, HDC1000_ADRS) ;
DHT dht(DHTPIN, DHTTYPE) ;

void setup()
{
     int ans ;

     // シリアルモニターの設定
     Serial.begin(9600) ;
     // I2Cの初期化
     Wire.begin() ;                // マスターとする
     delay(3000) ;                 // 3Sしたら開始
     // HDC1000の初期化
     ans = hdc.Init() ;
     if (ans != 0) {
          Serial.print("HDC Initialization abnormal ans=") ;
          Serial.println(ans) ;
     } else Serial.println("HDC Initialization normal !!") ;
     // AM2302の初期化
     dht.begin() ;
}
void loop()
{
     float h, t ;
     int ans ;

     // HDC1000から湿度と温度を読み取る
     ans = hdc.Read() ;
     if (ans == 0) {
          Serial.print("HDC1000: ") ;
          Serial.print(Humi) ;
          Serial.print("%  ") ;
          Serial.print(Temp) ;
          Serial.println("'C") ;
     } else {
          Serial.print("Failed to read from HDC ans=") ;
          Serial.println(ans) ;
     }
     // AM2302から湿度と温度を読み取る
     h = dht.readHumidity() ;
     t = dht.readTemperature() ;
     if (isnan(t) || isnan(h)) {
          Serial.println("Failed to read from DHT");
     } else {
          Serial.print("AM2302 : "); 
          Serial.print(h);
          Serial.print("% ");
          Serial.print(t);
          Serial.println("'C");
     }

     delay(1000) ;                      // 1秒後に繰り返す
}
---------------------------------------------------------------------
結果の表示
 上記スケッチのシリアル表示画面の表示内容です。

 温度は大して変わらない様です。
 湿度はHDC1000の方が4%程高いようですね。

 もちろんこれは家の中での結果です、
 因みにこの時の気象台発表数値は、
 湿度42%で温度21.4℃でした。
 まあ、何方が正確かは不明ですがね。

 尚、データ長はHDC1000が14bitで、
 AM2302が16bitとなっています。


《その他》

AM2302センサーはデータの読出しに約300ms程かかるので、それが嫌な人はHDC1000は約15ms
なのでこちらの方が良いでしょう、更に安いしぃ。



記事一部追記(*1) 2020/01/30


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.