温度センサを使ってみる (湿度も測る)(Arduino)

温度センサを使って、温度を計測し、
シリアルモニタに表示することをしてみましょう。

まず、温度センサですが、
アナログとデジタルのものがあります。

私が持っているもので、
今回使用するものを紹介します。

温度(湿度)センサモジュール
温度(湿度)センサモジュール

・アナログ温度センサ LM35DZ
 測定温度範囲:0~100℃
 動作電圧:4~30V
 ¥190-(¥50-)

・デジタル温度センサ 18B20
 〔プルアップ抵抗(4.7KΩ)〕
 測定温度範囲:-55℃~+125℃
 動作電圧:3.0~5.5V
 ¥320-(¥50-)
 基板タイプ:¥1,020-(¥240-)

・デジタル温度(湿度)センサ DHT11
 〔プルアップ抵抗(5kΩ~10KΩ)〕
 測定温度範囲:20~90%
 測定湿度範囲:0~50℃
 動作電圧:DC3.3V~5.5V
 ¥300-(¥90-)
 基板タイプ:¥850-(¥171-)

の3種類です。
それぞれの価格は、
国内の電子部品のサイトでの販売価格
()括弧内は海外の格安サイトの価格です。
基板タイプのものは、
センサが基板に取り付けられていて、
ブレッドボードなどでは扱いやすいと思います。
また、
センサ使用時の回路にプルアップ抵抗が必要な場合、
基板タイプのもにはこのプルアップ抵抗実装済みの
ものがあり、抵抗等の配線が不要となり便利です。
基板タイプのものには、ピンヘッダやピンソケットが
付いていないものもありますので、
はんだ付けが必要になることがあります。

プルアップ抵抗
プルアップ抵抗

プルアップ抵抗とは、
Arduinoの入力ピンとセンサの信号線とがいつも繋がっている必要があります。
センサの信号線は、情報のやりとり時には繋がっていますが、
やりとりしていないときは繋がっていない状態になる場合があります。
この繋がっていない状態のときに、
ノイズ等の発生で、Arduinoが誤認識を起こすことがあります。
※これがすべてではありません。これ以外にもいろいろあります。
これを防ぐために入れる抵抗のことを、
プルアップ抵抗(プルダウン抵抗)とよんでいます。
この抵抗が必要な場合の抵抗値などは、
その部品(センサ等)のデータシートに記載されています。
※あまり気にせず、必要と書いてあれば入れましょう。
 ・・・その方が回路が安定します。
・私の技量では、これ以上の説明は無理です。

アナログ温度センサ LM35DZ から使ってみます。
このセンサは、
1℃当たり10mVの電圧を返します。
0℃→0mV
20℃→200mV
50℃→500mV
ということになり、
これは、アナログピンで受け取れそうです。
アナログピンは、
入力電圧 0~5Vを、
0~1023の数値として表す回路でした。

回路は図の通りです。
   この回路図の作図には fritzing を利用させて頂いております。
   https://fritzing.org/home/

LM35DZ利用の回路図
LM35DZ利用の回路図

スケッチしてみます。

void setup() {
  // put your setup code here, to run once:
  Serial.begin( 9600 );     // シリアルポートを初期化(9600 bpsで通信)
}
void loop() {
  // put your main code here, to run repeatedly:
  // 変数宣言
  int val;    // センサからの値取得用
  float temp; // 温度に変換用
  // 温度値取得と変換
  val = analogRead( A0 ); // センサより値取得
  temp = ( 5.0 * val ) / 1024.0 * 100.0; // 温度に変換
  // シリアルポートへ送信
  Serial.print( temp );
  Serial.println( "℃" );
  delay(500);   //  500ms停止
}

これは、前回の電圧測定の時と同じようなスケッチですね。
マイコンボードに書き込んで実行してみます。

LM35DZ利用の実行結果
LM35DZ利用の実行結果

それらしい温度が表示されています。

続いてデジタルタイプのセンサを使用してみます。

デジタルセンサは、
ON(HIGH)、OFF(LOW)を繰り返すことで、
情報を伝達します。
考え方として、モールス信号のような感じでしょうか。
・・・詳細では違いますよ。
また、
要求→返答を繰り返す仕組みが基本です。
どのような要求を出せば、どのような返答を返してくるかは、
データシートに詳しく書かれています。

しかし、これらの要求をや返答を、
自分でプログラミングするのは大変です。

そこで、ライブラリの利用です。
このライブラリは、このやりとりに必要なプログラムを
ひとまとめにしたものです。
このライブラリは、センサ(部品等)毎にあり、
自分が利用したいもののライブラリを利用することになります。

このライブラリは、メーカーや有志の方によって作成された
もので、ダウンロードして使用することができます。
・・・ありがとうございます。<(_ _)>

ライブラリを利用すれば、
今までと同じく、そのライブラリ内の関数を使用するだけです。
このやりとりを一からプログラミングしたい方は別ですが、
そのセンサ等を簡単に利用したい場合は、
これを利用させて頂くのがよいと思います。

デジタル温度センサ 18B20から利用してみます。
このセンサは、
測定温度範囲:-55℃~+125℃
が取得可能です。

回路は図の通りです。
センサのみの回路の場合と基板利用の場合の回路です。
基板利用の場合、基板によってピンの配置が
違う場合もあります、必ず確認して下さい。
プルアップ抵抗は、4.7KΩです。

18B20利用の回路図
18B20利用の回路図
18B20利用(プルアップ抵抗別設置)
18B20利用(プルアップ抵抗別設置)

続いてスケッチをします。

まず、ライブラリのダウンロード(インストール)を行います。
・OneWireライブラリ
 1-Wireは、1本の信号線に複数のデバイスをつないぐことのできる
 仕組みを提供するライブラリ。
・DallasTemperatureライブラリ
 18B20センサを利用するためのライブラリ。
の2つが必要です。

ArduinoIDEにインストールする方法は、
1.メニュー「スケッチ」 → 「ライブラリをインクルード」
   → 「ライブラリを管理」 を選択します。

ライブラリのインストール1
ライブラリのインストール1

2.ライブラリマネージャ画面の
 検索欄に、”OneWire” と入力します。
 表示された一覧の中から、
 ”OneWire”を選択し、〔インストール〕ボタンを押します。

ライブラリのインストール2
ライブラリのインストール2

3.ライブラリマネージャ画面の
 検索欄に、”DallasTemperature” と入力します。
 表示された一覧の中から、
 ”DallasTemperature”を選択し、〔インストール〕ボタンを押します。

ライブラリのインストール3
ライブラリのインストール3

これで、ライブラリの準備は完了です。

スケッチでライブラリを利用するには、
プログラム(スケッチ)の先頭行で、
 // インクルード(ライブラリ利用)宣言
 #include <OneWire.h>
 #include <DallasTemperature.h>
と記述します。

続いて、オブジェクト生成を行います。
オブジェクト生成の記述は、
 OneWire オブジェクト名( 使用デジタルピン番号 )
 DallasTemperature オブジェクト名( OneWireで生成したオブジェクトのアドレス );
という記述で行います。
 OneWire oneWire( 9 ); // デジタルピン9番を割り当て
 DallasTemperature sensors( &oneWire ); // oneWireを引数として
※オブジェクト名はルールに合っていてば良いですが、
 サンプルスケッチが提供されている場合が多いので、
 ほとんどの場合そのまま使用されているのでは?
※オブジェクト名 oneWire の先頭に & を付けることで、
 アドレス指定したことになります。

センサは測定精度の設定が可能です。
関数は、
 オブジェクト名.setResolution( センサ精度 );
と使用します。
センサの精度設定は、
9bit(93.75ms)~12bit(750ms)です。
精度を高くすれば取得に要する時間も長くなります。
詳しくはデータシートで確認して下さい。

使用開始指示を発行します。
関数は、
 オブジェクト名.begin( );
を使用します。

温度情報の取得には、取得要求関数を発行します、
オブジェクト名.requestTemperatures();
続いて、センサからの情報を取得します。
オブジェクト名.getTempCByIndex( センサ番号 );
で、取得情報は、関数自身が保持していますので、
float temp = sensors.getTempCByIndex( 0 );
として、変数へ代入します。
センサ番号は、1センサのみ使用している場合は、
0番です。

では、スケッチです。

// インクルード(ライブラリ利用)宣言
#include OneWire.h
#include DallasTemperature.h
// オブジェクト生成と初期化
OneWire oneWire( 9 );
DallasTemperature sensors( &oneWire );
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);            // シリアルポート設定(9600bps)
  sensors.setResolution( 9 );   // センサ精度設定
  sensors.begin( );             // 使用開始
}
void loop() {
  // put your main code here, to run repeatedly:
  // 変数宣言
  float temp;   // 温度格納用 
  // 温度取得// 500ms停止
  sensors.requestTemperatures();        // センサーへ要求
  temp = sensors.getTempCByIndex( 0 );  // センサーからの温度取得
  // シリアルポートへ送信
  Serial.print( temp );
  Serial.println( "℃" );
  delay(500);   // 500ms停止
}

では、マイコンボードに書き込んで実行してみます。

18B20利用の実行結果
18B20利用の実行結果

OneWireタイプのデジタルセンサ等は、
1つの回線に複数のセンサを接続することが可能です。
図のようなものとなります。

1つの回線に複数のセンサを接続
1つの回線に複数のセンサを接続

この場合、どのセンサからの情報を取得するかを
設定する必要があります。
オブジェクト名.getTempCByIndex( センサ番号 );
で、センサ番号を指定すれば良いのですが、
どのセンサが何番なのかが分かりません。
これを識別するために、
センサにはシリアル番号が付けられています。
このシリアル番号を指定して情報を取得すれば、
適切なセンサから情報を取得することができます。
では、このシリアル番号を取得してみます。

スケッチしてみます。

// インクルード(ライブラリ利用)宣言
#include <OneWire.h>
#include <DallasTemperature.h>
// オブジェクト生成と初期化
OneWire oneWire( 9 );
DallasTemperature sensors( &oneWire );
// アドレス格納用
DeviceAddress temp_sn;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);                  // シリアルポート設定(9600bps)
  sensors.begin( );                   // 使用開始
  sensors.getAddress( temp_sn, 0 );  // 割り当て0番のセンサシリアルNo取得 
}
void loop() {
  // put your main code here, to run repeatedly:
  // 変数宣言
  int i;    // 反復カウント用
  // シリアルモニタに取得シリアルNoを16進数で表示
  for( i=0; i<8; i++ ){
    Serial.print( "0x" );
    Serial.print( temp_sn[i],HEX );
    Serial.print( " " );
  }
  Serial.println( );
  delay(5000);   // 5000ms停止
}

では、マイコンボードに書き込んで実行してみます。
0番センサのシリアル番号が16進数で表示されます。

シリアル番号の取得
シリアル番号の取得

今度は、このシリアル番号で、
センサを指定して指定センサからの情報を取得してみます。
スケッチしてみます。

// インクルード(ライブラリ利用)宣言
#include <OneWire.h>
#include <DallasTemperature.h>
// オブジェクト生成と初期化
OneWire oneWire( 9 );
DallasTemperature sensors( &oneWire );
// 使用センサ割り当て
DeviceAddress temp_sn0 = { 0x28,0xFE,0x7B,0x16,0xA8,0x1,0x3C,0x59 };
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);    // シリアルポート設定(9600bps)
  sensors.setResolution( 9 );   // センサー精度設定
  sensors.begin( );     // センサ使用開始       
}
void loop() {
  // put your main code here, to run repeatedly:
  // 変数宣言
  float temp;   // 温度格納用 
  sensors.requestTemperatures( );       // センサーへ要求
  temp = sensors.getTempC( temp_sn0 );  // センサーからの温度取得
  // シリアルポートへ送信
  Serial.print( temp );
  Serial.println( "℃" );
  delay(500);   // 500ms停止
}

では、マイコンボードに書き込んで実行してみます。
指定したセンサから温度情報を取得できているようです。

指定センサからの情報を取得
指定センサからの情報を取得

では、もう一つのデジタルセンサを使ってみます。

デジタル温湿度センサ DHT11です。
このセンサは、温度、湿度が取得できます。
測定温度範囲:20~90%
測定湿度範囲:0~50℃
が取得可能範囲です。

回路は図の通りです。
センサのみの回路の場合と基板利用の場合の回路です。
基板利用の場合、基板によってピンの配置が
違う場合もあります、必ず確認して下さい。
プルアップ抵抗は、5kΩ~10KΩです。

DHT11利用の回路図
DHT11利用の回路図
DHT11利用(プルアップ抵抗別設置)
DHT11利用(プルアップ抵抗別設置)

このセンサも専用のライブラリがあります。
 DHT-sensor-library
 Adafruit_Unified_Sensor
の2つです。
先ほどと同じ方法でインストールを行います。

DHT-sensor-libraryライブラリでは、
確認画面が表示されますので、
”Install all”を選択します。
”Install DHT-sensor-library only”を選択した場合は、
Adafruit_Unified_Sensorライブラリのインストールが必要です。

ライブラリのインストール4
ライブラリのインストール4
ライブラリのインストール5
ライブラリのインストール5
ライブラリのインストール6
ライブラリのインストール6

スケッチしてみます。

// インクルード(ライブラリ利用)宣言
#include <DHT.h>
// オブジェクト生成
DHT dht( 9, DHT11 );
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);    // シリアルポート設定(9600bps)
  dht.begin();          // センサー初期化
}
void loop() {
  // 変数宣言
  float temp; // 温度格納用  
  float humi; // 湿度格納用
  // センサータイミング調整
  delay(2000);
  // 温度取得
  temp = dht.readTemperature();
  // 湿度取得
  humi = dht.readHumidity();
  // 取得情報確認
  if ( isnan( humi ) || isnan( temp )) {
    // 取得に失敗
    Serial.println( "-- sensor read error --");
  } else {
    // シリアルポートへ送信
    Serial.print( "温度:" );
    Serial.print( temp );
    Serial.print( "℃  湿度:" );
    Serial.print( humi, 1 );
    Serial.println( "%" );
  }
}

ライブラリの使用宣言は、
 #include <ライブラリ名>
 #include <DHT.h>
オブジェクト生成は、
 DHT オブジェクト名( デジタルピン番号, センサ名 );
 DHT dht( 9, DHT11 );
センサの初期化(使用開始)は、
 オブジェクト名.begin();
 dht.begin(); // センサー初期化
となります。

注意が必要なのは、
取得タイミングで、
前回の取得要求より、1000ms程度の間隔が必要です。
 // センサータイミング調整
 delay(2000);

情報の取得は、
温度が、
 オブジェクト名.readTemperature();
 float temp = dht.readTemperature();
湿度が
 オブジェクト名.readHumidity();
 float humi = dht.readHumidity();
です。

では、マイコンボードに書き込み実行してみます。

DHT11利用の実行結果

インターネットなどでもよく似たプログラムが多いと思います。
これは、各ライブラリにサンプルプログラムが提供されている
ため、それを参考にスケッチするからでしょうね。

利用方法が分からない場合、このサンプルスケッチは
大変ありがたいものです。。。感謝<(_ _)>