Grove Beginner KitでのArduino入門 その9 温度および湿度センサー(DHT11)

概要

前回はI2Cでの画面制御を行いました。今回はシリアル接続の温度と湿度計を使ってみたいと思います。

DHT11とは?

シリアル接続の温度と湿度センサーで、比較的定番の商品になります。

単品のセンサーだと上記になります。温度センサーと湿度センサーは非常に数が多く、どれを使っていいのか悩むと思います。DHT11は値段も安く、比較的使いやすいのですが独自プロトコルでの接続になります。

信号線は1本しか使いませんので、GPIOが少ないマイコンなどでの利用しやすいです。ただし、一般的にはI2C接続のセンサーを使うことが多いように感じます。I2Cの場合には複数台を同時に接続することが可能なので、何個のセンサーを接続しても追加のGPIOが必要ありません。

センサー自体はこの青いものになります。Grove端子をみるとGND、VCC、NC、SIGと書いてあります。VCCは電源で、NCは未接続(Non-Connection)、SIGが信号線になります。上の表示をみるとD3端子に接続されていますね。

ライブラリの追加

この手のセンサーを使う場合にはまずは利用できるライブラリがあるかを確認します。ライブラリマネージャよりセンサーの名前であるDHT11を入力して検索します。

たくさん出てくると思いますが、基本的にSeeed社のGrove接続のセンサーであればGroveと名前がついているライブラリがあるはずです。今回はこれを使いたいと思います。おそらく他のライブラリを利用しても使えると思いますが、使いにくいライブラリもたくさんあるので気をつけてください。

スケッチ例

ライブラリを入れたら、スケッチ例をまずは見てみましょう。

上記のようにスケッチ例の中に「DHTtester」があると思います。

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 3     // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

/*Notice: The DHT10 is different from other DHT* sensor ,it uses i2c interface rather than one wire*/
          /*So it doesn't require a pin.*/

//#define DHTTYPE DHT10

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

#if defined(ARDUINO_ARCH_AVR)
#define SERIAL  Serial

#elif defined(ARDUINO_ARCH_SAMD) ||  defined(ARDUINO_ARCH_SAM)
#define SERIAL  SerialUSB
#else
#define SERIAL  Serial
#endif

void setup() 
{

    SERIAL.begin(115200); 
    SERIAL.println("DHTxx test!");
    Wire.begin();

    /*if using WIO link,must pull up the power pin.*/
    // pinMode(PIN_GROVE_POWER, OUTPUT);
    // digitalWrite(PIN_GROVE_POWER, 1);

    dht.begin();
}

void loop() 
{
    float temp_hum_val[2] = {0};
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    
    
    if(!dht.readTempAndHumidity(temp_hum_val)){
        SERIAL.print("Humidity: "); 
        SERIAL.print(temp_hum_val[0]);
        SERIAL.print(" %\t");
        SERIAL.print("Temperature: "); 
        SERIAL.print(temp_hum_val[1]);
        SERIAL.println(" *C");
    }
    else{
       SERIAL.println("Failed to get temprature and humidity value.");
    }

   delay(1500);
}

上記がそのスケッチを書き換えたものです。

#define DHTPIN 3     // what pin we're connected to

まずは接続先を設定します。今回はD3に接続しているので初期値の2から3に書き換えます。

#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)

また、この手のライブラリは複数のセンサーに対応していることが多く、こちらもデフォルトのDHT22から、今回接続したDHT11に変更します。こちらはDHT11の先頭にある//のコメントを消して有効化し、DHT22の先頭に//を追記してコメント化します。

DHTxx test!
Humidity: 48.00 %	Temperature: 22.00 *C
Humidity: 46.00 %	Temperature: 21.00 *C
Humidity: 46.00 %	Temperature: 21.00 *C
Humidity: 46.00 %	Temperature: 21.00 *C
Humidity: 47.00 %	Temperature: 22.00 *C

この状態で動かして、シリアルモニタを表示すると上記のような表示がでると思います。なんとなく正しそうな数値がでています。

ちなみに、この手のセンサーは結構ずれます。時計売り場などにいって、温度と湿度センサー付きの時計を見ればわかりやすいのですが、同じ商品でも全然違う値を表示しているものが多いです。なので相対的な変化を観察するのは良いのですが、絶対的な温度はあまり信用できないと思ってください。

スケッチのブラッシュアップ

#include "DHT.h"

#define DHTPIN 3
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {

  Serial.begin(115200);
  Serial.println("DHT11 test!");

  dht.begin();
}

void loop() {
  float temp_hum_val[2] = {0};

  if (!dht.readTempAndHumidity(temp_hum_val)) {
    Serial.print("Humidity: ");
    Serial.print(temp_hum_val[0]);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(temp_hum_val[1]);
    Serial.println(" *C");
  } else {
    Serial.println("Failed to get temprature and humidity value.");
  }

  delay(1500);
}

この手のスケッチ例は余計なコードが含まれていることがあるので、本当に最低限のコードにブラッシュアップしてから利用するほうがよいと思います。上記が絞り込んだスケッチになります。

DHT dht(DHTPIN, DHTTYPE);

上記で宣言をしていて、使っているPINとセンサーの種類を与えていますね。

dht.begin();

上記でセンサーの初期化。

  float temp_hum_val[2] = {0};

  if (!dht.readTempAndHumidity(temp_hum_val)) {
    Serial.print("Humidity: ");
    Serial.print(temp_hum_val[0]);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(temp_hum_val[1]);
    Serial.println(" *C");
  } else {
    Serial.println("Failed to get temprature and humidity value.");
  }

あとは、データ用の変数を確保してから、readTempAndHumidity関数を呼び出すだけですね。単純なので使いやすいライブラリだと思います。ただ、結果を見た限り小数点以下の数値が出てこないので、DHT11はざっくりの数値しか取得できないのかもしれません。

その他の温度センサー

主にI2Cのセンサー紹介ですが、個人的にはSHT30あたりがおすすめです。M5Stack ENV2ユニットなども最近はSHT30を搭載しています。

ちなみにSeeed社のGrove温度センサーにもいろいろな種類があります。

上記が検索結果ですが、たくさんですぎてよくわからないと思います。

公式スケッチ例

#include "DHT.h"
#include <Arduino.h>
#include <U8x8lib.h>

#define DHTPIN 3     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  Serial.begin(115200);
  Serial.println("DHTxx test!");
  dht.begin();
  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFlipMode(1);
}

void loop(void) {
  float temp = dht.readTemperature();
  float humi = dht.readHumidity();

  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.setCursor(0, 33);
  u8x8.print("Temp:");
  u8x8.print(temp);
  u8x8.print("C");
  u8x8.setCursor(0, 50);
  u8x8.print("Humidity:");
  u8x8.print(humi);
  u8x8.print("%");
  u8x8.refreshDisplay();
  delay(200);
}

キットのスケッチ例を見てみます。こちらはOLEDに表示していますね。

  float temp = dht.readTemperature();
  float humi = dht.readHumidity();

こっちのデータ取得方法の方がシンプルで良さそうですね。

まとめ

DHT11はシンプルで使いやすいセンサーです。とはいえ、キットにはよく入っていますが、実際にはもう少し高いI2Cセンサーを使う場合が多いみたいです。

続編

コメント