ArduinoでDHT11、DHT22、SHTC3の温湿度データを読み取る

この記事では、NodeMcu開発ボードを使用してDHT11、DHT22、SHTC3の3つの温湿度センサーのデータを読み取り、シリアルポートに送信する方法を説明します。各センサーについて、サードパーティライブラリを使用する場合と使用しない場合の例をそれぞれ掲載しています。

ESP8266開発環境構築ガイド:https://blog.zeruns.com/archives/526.html

文中で使用しているセンサーの購入先は、記事の最後に記載しています。

DHT11

DHT11は、校正済みのデジタル信号出力を備えた温湿度センサーです。湿度精度は±5%RH、温度精度は±2℃、測定範囲は湿度20~90%RH、温度0~50℃です。精度はそれほど高くありませんが、価格が非常に安価です。 DHT11はシングルバス通信を使用します。動作電圧は3.3~5Vです。

DHTライブラリの使用

DHT sensor library(別途インストールが必要。インストール方法は上のESP8266開発環境構築ガイドを参照)を使用して、DHT11のデータを直接読み取ります。

#include ```<DHT.h>        // DHTライブラリをインポート

DHT dht(D1, DHT11);      // データピンに接続されたIOピンとセンサーの種類を設定

void setup(){ // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
  dht.begin();       
}
//https://blog.zeruns.com
void loop() {
  delay(1000);                  // 1000ミリ秒遅延
  float RH = dht.readHumidity();   // 湿度データを読み取る
  float T = dht.readTemperature(); // 温度データを読み取る
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

ライブラリを使用しない

DHT11のデータシートを読み、独自にプログラムを記述してデータを読み取る。

DHT11データシート:http://go.zeruns.com/G

#define data D1   // DHT11のDataピン(2番ピン)をNodeMcu開発ボードのD1ピンに接続

unsigned char i;  // 符号なし8ビット整数型変数
float RH,T;       // 単精度浮動小数点数(32ビット)
byte RH_H,RH_L,T_H,T_L,sum,check;  // バイト変数(2進数)

void setup() {    // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
}

void loop() {     // ループ関数。初期化関数終了後、繰り返し実行される
  delay(1000);    // 1000ミリ秒遅延
  DHT11();        // 温湿度データを取得
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void DHT11()
{
  RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  pinMode(data,OUTPUT);   // IOピンを出力モードに設定
  digitalWrite(data,1);   // IOピンに高電平を出力
  delay(10);              // 10ミリ秒遅延
  digitalWrite(data,0);   // IOピンに低電平を出力
  delay(25);              // 25ミリ秒遅延
  digitalWrite(data,1);   // IOピンに高電平を出力
  pinMode(data,INPUT);    // IOピンを入力モードに設定
  delayMicroseconds(30);  // 30マイクロ秒遅延
  if(!digitalRead(data))  // IOピンの入力が低電平かを判断
  {//https://blog.zeruns.com
    while(!digitalRead(data));  // 入力が高電平になるまでループ
    while(digitalRead(data));   // 入力が低電平になるまでループ
    for(i=0;i<8;i++)            // 8回ループ
    {   
      while(!digitalRead(data));// 入力が高電平になるまでループ   
      delayMicroseconds(28);    // 28マイクロ秒遅延
      if(digitalRead(data)){    // IOピンの入力が高電平かを判断
        bitWrite(RH_H, 7-i, 1); // 2進数変数RH_Hの7-iビット目(右から数えて)に1を書き込む
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){
        bitWrite(RH_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_H, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(check, 7-i, 1);
        while(digitalRead(data));
      }
    }
   }
  sum=RH_H + RH_L + T_H + T_L;
  byte sum_temp=0;
  // sumの下位8ビットをsum_tempに書き込む
  for(i=0;i<8;i++){
    bitWrite(sum_temp,i,bitRead(sum,i)); 
  }//https://blog.zeruns.com
  if(check==sum_temp){  // データ検証
    RH=RH_H+float(RH_L)/10;
    T=T_H+float(T_L)/10;
  }
}

実行結果

DHT22(AM2302)

DHT22(AM2302)は、校正済みデジタル出力を持つ温湿度センサーです。湿度精度は±2%RH、温度精度は±0.5℃、測定範囲は湿度0~100%RH、温度-40~80℃、分解能はいずれも0.1です。精度が高く、価格も手頃です。 DHT22はシングルバス通信を使用します。動作電圧は3.3~5Vです。

DHTライブラリを使用

DHT sensor libraryライブラリを使用して、DHT22のデータを直接読み取ります。

#include <DHT.h>        // DHTライブラリをインポート

DHT dht(D1, DHT22);      // データピンに接続されたIOピンとセンサーの種類を設定

void setup(){ // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
  dht.begin();       
}
//https://blog.zeruns.com
void loop() {
  delay(1000);                  // 1000ミリ秒遅延
  float RH = dht.readHumidity();   // 湿度データを読み取る
  float T = dht.readTemperature(); // 温度データを読み取る
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

ライブラリを使用しない

DHT22のデータシートを読み、独自にプログラムを記述してデータを読み取る。

DHT22データシート:http://go.zeruns.com/H

#define data D1   // DHT22のDataピン(2番ピン)をNodeMcu開発ボードのD1ピンに接続

unsigned char i;  // 符号なし8ビット整数型変数
float RH,T;       // 単精度浮動小数点数(32ビット)
byte RH_H,RH_L,T_H,T_L,sum,check;  // バイト変数(2進数)

void setup() {    // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
}

void loop() {     // ループ関数。初期化関数終了後、繰り返し実行される
  delay(1000);    // 1000ミリ秒遅延
  DHT11();        // 温湿度データを取得
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void DHT11()
{
  RH_H=0,RH_L=0,T_H=0,T_L=0,sum=0,check=0;
  pinMode(data,OUTPUT);   // IOピンを出力モードに設定
  digitalWrite(data,1);   // IOピンに高電平を出力
  delay(10);              // 10ミリ秒遅延
  digitalWrite(data,0);   // IOピンに低電平を出力
  delay(25);              // 25ミリ秒遅延
  digitalWrite(data,1);   // IOピンに高電平を出力
  pinMode(data,INPUT);    // IOピンを入力モードに設定
  delayMicroseconds(30);  // 30マイクロ秒遅延
  if(!digitalRead(data))  // IOピンの入力が低電平かを判断
  {//https://blog.zeruns.com
    while(!digitalRead(data));  // 入力が高電平になるまでループ
    while(digitalRead(data));   // 入力が低電平になるまでループ
    for(i=0;i<8;i++)            // 8回ループ
    {   
      while(!digitalRead(data));// 入力が高電平になるまでループ   
      delayMicroseconds(28);    // 28マイクロ秒遅延
      if(digitalRead(data)){    // IOピンの入力が高電平かを判断
        bitWrite(RH_H, 7-i, 1); // 2進数変数RH_Hの7-iビット目(右から数えて)に1を書き込む
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){
        bitWrite(RH_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_H, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(T_L, 7-i, 1);
        while(digitalRead(data));
      }
    }
    for(i=0;i<8;i++)
    {
      while(!digitalRead(data));
      delayMicroseconds(28);
      if(digitalRead(data)){  
        bitWrite(check, 7-i, 1);
        while(digitalRead(data));
      }
    }
   }
  sum=RH_H + RH_L + T_H + T_L;
  byte sum_temp=0;
  // sumの下位8ビットをsum_tempに書き込む
  for(i=0;i<8;i++){
    bitWrite(sum_temp,i,bitRead(sum,i)); 
  }//https://blog.zeruns.com
  if(check==sum_temp){
    if(bitRead(RH_H,7)==1){ // 温度がマイナスかを判断
      T=-(float(T_H<<8)+float(T_L))/10;
    }else{
      T=(float(T_H<<8)+float(T_L))/10;
    }
    RH=(float(RH_H<<8)+float(RH_L))/10;
  }  
}

実行結果

SHTC3

SHTC3は、校正済みデジタル出力を持つ温湿度センサーです。湿度精度は±2%RH、温度精度は±0.2℃、測定範囲は湿度0~100%RH、温度-40~125℃、分解能はいずれも0.01です。精度が高く、価格も比較的安価ですが、資料が限られています。 SHTC3はI2C(IIC)通信を使用します。動作電圧は1.62~3.6Vです。

SHTC3データシート:http://go.zeruns.com/I

Wire(I2C)ライブラリを使用

Wireライブラリを使用してSHTC3と通信し、データを読み取ります。

/* https://blog.zeruns.com
 * 接続方法
 * SHTC3    ボード
 * SCL      SCL(NodeMcuボードはD1)
 * SDA      SDA(NodeMcuボードはD2)
 */
#include <Wire.h>

#define SHTC3_ADDRESS 0x70  // SHTC3のI2Cアドレスを0x70に定義
float T, RH;

void setup() {    // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
  Wire.begin();   // I2Cマスターとして初期化
}

void loop() {     // ループ関数。初期化関数終了後、繰り返し実行される
  delay(1000);    // 1000ミリ秒遅延
  SHTC3();        // 温湿度データを取得
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void SHTC3(){   // 温湿度データを取得
  Wire.beginTransmission(SHTC3_ADDRESS); // アドレス0x70でI2Cスレーブに通信を開始
  Wire.write(byte(0xE0));       // 書き込みコマンドを送信
  Wire.endTransmission();       // スレーブへの通信を終了
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0x35));       // ウェイクアップコマンドの上位バイトを送信
  Wire.write(byte(0x17));       // ウェイクアップコマンドの下位バイトを送信
  Wire.endTransmission();
  delayMicroseconds(300);       // 300マイクロ秒遅延
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0xE0));
  Wire.endTransmission();
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0x7C));       // 測定コマンドの上位バイトを送信
  Wire.write(byte(0xA2));       // 測定コマンドの下位バイトを送信
  Wire.endTransmission();
  Wire.beginTransmission(SHTC3_ADDRESS);
  Wire.write(byte(0xE1));       // 読み取りコマンドを送信
  Wire.endTransmission();
  Wire.requestFrom(SHTC3_ADDRESS, 6);     // スレーブからデータを要求
  uint16_t T_temp, RH_temp, T_CRC, RH_CRC;
  if (2 <= Wire.available()) {
    T_temp = Wire.read();     // 温度上位バイトを受信
    T_temp = T_temp << 8;     // 8ビット左シフト
    T_temp |= Wire.read();    // 左シフトした温度上位バイトと受信した温度下位バイトをビットOR
    T_CRC = Wire.read();      // CRCチェックサムを受信
    if(SHTC3_CRC_CHECK(T_temp, T_CRC)){  // データ検証
      T = float(T_temp) * 175 / 65536 - 45;  // 温度を計算
    }
  }//https://blog.zeruns.com
  if (2 <= Wire.available()) {
    RH_temp = Wire.read();     // 湿度上位バイトを受信
    RH_temp = RH_temp << 8;     // 8ビット左シフト
    RH_temp |= Wire.read();    // 左シフトした湿度上位バイトと受信した湿度下位バイトをビットOR
    RH_CRC = Wire.read();
    if(SHTC3_CRC_CHECK(RH_temp, RH_CRC)){
      RH = float(RH_temp) * 100 / 65536;
    }
  }
}
//https://blog.zeruns.com
uint8_t SHTC3_CRC_CHECK(uint16_t DAT, uint8_t CRC_DAT) // SHTC3のCRC検証
{
    uint8_t i, t, temp;
    uint8_t CRC_BYTE;  
    CRC_BYTE = 0xFF;  
    temp = (DAT >> 8) & 0xFF;  
    for(t = 0; t < 2; t ++)
    {
        CRC_BYTE ^= temp;
        for(i = 0; i < 8; i ++)
        {
            if(CRC_BYTE & 0x80)
            {
                CRC_BYTE <<= 1;         
                CRC_BYTE ^= 0x31;  
            }else{
                CRC_BYTE <<= 1;  
            }
        }  
        if(t == 0)
        {
            temp = DAT & 0xFF; 
        }
    }//https://blog.zeruns.com  
    if(CRC_BYTE == CRC_DAT)
    {
        temp = 1;  
    }else{
        temp = 0;  
    }   
    return temp;
}

### SHTC3ライブラリの使用

まず `SparkFun SHTC3` ライブラリをインストールしてください。

```c
/* https://blog.zeruns.com
 * 接続方法
 * SHTC3    ボード
 * SCL      SCL(NodeMcuボードはD1)
 * SDA      SDA(NodeMcuボードはD2)
 */

#include <SparkFun_SHTC3.h>

SHTC3 mySHTC3;

void setup(){ // 初期化関数。プログラム開始時に一度だけ実行される
  Serial.begin(115200);   // シリアル通信のボーレートを設定
  while(Serial == false){};   // シリアル接続の開始を待機
  Wire.begin();           // Wire(I2C)ライブラリを初期化
  unsigned char i=0;
  errorDecoder(mySHTC3.begin()); // センサを起動するには「begin()」を呼び出す必要があります。デフォルト設定ではWire(Arduinoの標準I2Cポート)を使用します。
}
//https://blog.zeruns.com
void loop() {
  float RH, T;
  delay(1000);                  // 1000ミリ秒遅延
  SHTC3_Status_TypeDef result = mySHTC3.update();
  if(mySHTC3.lastStatus == SHTC3_Status_Nominal)   // SHTC3の状態が正常か確認
  {
    RH = mySHTC3.toPercent();   // 湿度データを読み取り                
    T = mySHTC3.toDegC();       // 温度データを読み取り             
  }else{
    Serial.print("Update failed, error: ");
    errorDecoder(mySHTC3.lastStatus); // エラー原因を出力
    Serial.println();
  }
  Serial.print("Humidity:");  // シリアルに "Humidity:" を出力
  Serial.print(RH);           // 湿度データを出力
  Serial.print("%");
  Serial.print("  Temperature:");
  Serial.print(T);            // 温度データを出力
  Serial.println("C"); 
  Serial.println("https://blog.zeruns.com");
}

void errorDecoder(SHTC3_Status_TypeDef message) // errorDecoder関数は「SHTC3_Status_TypeDef」の結果を人間が読みやすい形で出力します
{
  switch(message)
  {
    case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
    case SHTC3_Status_Error : Serial.print("Error"); break;
    case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
    default : Serial.print("Unknown return code"); break;
  }
}

実行結果

センサの購入

DHT11: $Lk3h1Mx8UTO$ をコピーして、モバイル淘宝で即座に注文

DHT22: $kr2T1MxkUKY$ をコピーして、モバイル淘宝で即座に注文

SHTC3: $UD4D1Mx6N3R$ をコピーして、モバイル淘宝で即座に注文

おすすめ記事:

  • コスパの高い安価なVPS/クラウドサーバーのおすすめ:https://blog.zeruns.com/archives/383.html
  • ネットワークトンネリングサーバーをWebパネル付きで構築:https://blog.zeruns.com/archives/397.html
  • Cloudreveを使用した自宅ストレージの構築:https://blog.zeruns.com/archives/515.html
  • 個人ブログの構築方法:https://blog.zeruns.com/archives/218.html
  • 学生向け割引特典一覧:https://blog.zeruns.com/archives/321.html
  • 収益化できる小さなゲームを紹介:https://blog.zeruns.com/archives/472.html
「いいね!」 1