「Arduinoの基礎 - 温湿度センサ」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
(文字列「</source>」を「</syntaxhighlight>」に置換)
 
(同じ利用者による、間の3版が非表示)
1行目: 1行目:
== 概要 ==
== 概要 ==
ここでは、温湿度センサとしてDHT-11を使用して、Arduinoから使用する方法を記載する。<br>
<br>
DHT-11はサーミスタと異なり、温度と湿度のキャリブレーション済みの状態で出荷されているセンサ(デジタル信号)である。<br>
DHT-11はサーミスタと異なり、温度と湿度のキャリブレーション済みの状態で出荷されているセンサ(デジタル信号)である。<br>
一般的な利用において、温度は1[℃]程度の誤差、湿度は4[%]程度の誤差で測定できる。<br>
一般的な利用において、温度は1[℃]程度の誤差、湿度は4[%]程度の誤差で測定できる。<br>
8行目: 6行目:
[[ファイル:Arduino DHT11 1.png|フレームなし|中央]]
[[ファイル:Arduino DHT11 1.png|フレームなし|中央]]
<br>
<br>
4本のピンは左から順に、VDD、DATA、NC(非接続)、GNDである。VDDへの供給電圧は、3.3[V]〜5.5[V]の範囲である。<br>
4本のピンは左から順に、VDD、DATA、NC(非接続)、GNDである。<br>
VDDへの供給電圧は、3.3[V]〜5.5[V]の範囲である。<br>
<br>
データシートを確認すると、VDDとGNDの間にパワーフィルタリングとして0.1[μF]のセラミックコンデンサを設置することができる。<br>
データシートを確認すると、VDDとGNDの間にパワーフィルタリングとして0.1[μF]のセラミックコンデンサを設置することができる。<br>
<br>
<br>
19行目: 19行目:
<br><br>
<br><br>


== サンプルコード ==
== DHT-11 / DHT-21 ==
Adafruitが作成しているDHT用ライブラリを使用して、DHT-11から温度と湿度を取得する。<br>
DHT-11 / DHT-21を使用するには、Adafruit DHTセンサライブラリをインストールする必要がある。<br>
<br>
Adafruit DHTセンサライブラリのインストールする。<br>
# Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [ライブラリを管理]を選択する。
# [ライブラリの管理]画面が起動するので、検索項目から"Adafruit Unified Sensor"と入力する。
# ライブラリ一覧が表示されるので、Adafruit Unified Sensorを選択して、リスト右側にある[Install]ボタンを押下する。
# 次に、[https://github.com/adafruit/DHT-sensor-library/releases Adafruit DHTセンサライブラリのGithub]にアクセスして、zipファイルをダウンロードする。
# Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール]を選択する。
# ダウンロードしたzipファイルを選択して、Adafruit DHTセンサライブラリをインストールする。
<br>
まず、DHT-11から温度と湿度を取得する。<br>
さらに、温度と湿度からヒートインデックス(体感温度)が取得できるので、それも併せて取得する。<br>
さらに、温度と湿度からヒートインデックス(体感温度)が取得できるので、それも併せて取得する。<br>
<br>
<br>
以下のサンプルコードでは、シリアルポートに値を出力している。<br>
以下の例では、シリアルポートに値を出力している。<br>
これでシリアルモニタを開けば、3秒おきに結果が出力されることがわかる。<br>
シリアルモニタを開くことにより、3秒ごとに結果が出力される。<br>
<br>
<br>
LCDに出力する場合は、Arduinoを用いてLCDに文字を表示を参照すること。<br>
LCDに出力する場合は、Arduinoを用いてLCDに文字を表示を参照すること。<br>
68行目: 78行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>
== BME280 ==
==== BME280とは ====
BME280センサモジュールは、気圧、温度、湿度を読み取ることができる。<br>
気圧は高度によって変化するため、高度も推定することもできる。<br>
<br>
BME280センサモジュールには、I2C通信またはSPI通信を使用してArduinoへデータを送信する。<br>
<br>
[[ファイル:BME280 1.png|フレームなし|中央]]
<center>図. BME280センサモジュール I2C接続 (4ピン)</center><br>
<br>
[[ファイル:BME280 2.png|フレームなし|中央]]
<center>図. BME280センサモジュール SPI接続 (6ピン)</center><br>
<br>
BME280センサモジュール (I2C接続) の回路図を以下に示す。<br>
[[ファイル:BME280 3.png|フレームなし|中央]]
<br>
I2C通信を使用する場合は、BME280センサモジュールとArduino UNOのI2Cピンを下表のように接続する。<br>
<center>
{| class="wikitable" | style="background-color:#fefefe;"
! style="background-color:#66CCFF;" | BME280
! style="background-color:#66CCFF;" | Arduino UNO R3 / R4
|-
| SCK (SCLピン) || A5
|-
| SDI (SDAピン) || A4
|}
</center>
<br>
SPI通信を使用する場合は、BME280センサモジュールとArduino UNOのI2Cピンを下表のように接続する。<br>
<center>
{| class="wikitable" | style="background-color:#fefefe;"
! style="background-color:#66CCFF;" | BME280
! style="background-color:#66CCFF;" | Arduino UNO R3 / R4
|-
| SCK (SPIクロックピン) || Pin 13
|-
| SDO (MISO) || Pin 12
|-
| SDI (MOSI) || Pin 11
|-
| CS (Chip Select) || Pin 10
|}
</center>
<br>
==== BME280ライブラリのインストール ====
Adafruit BME280ライブラリをインストールする。<br>
# Arduino IDEを起動して、[スケッチ] - [インクルードライブラリ] - [ライブラリの管理]を選択する。
# 検索ボックスから、<u>"adafruit bme280"</u>を検索して、ライブラリをインストールする。
<br>
==== I2C接続の使用例 ====
以下の例では、Arduino UNOにBME280をI2C接続して温度、湿度、大気圧を受信して、シリアルモニタに出力している。<br>
<br>
<u>※注意</u><br>
<u>SPI通信を行う場合は、SDOをHighにして、アドレスを0x77で取得する必要がある。</u><br>
<br>
<syntaxhighlight lang="c++">
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// BME280センサのインスタンスを生成
Adafruit_BME280 bme;
// BME280のI2Cアドレス (0x76または0x77)
#define BME280_ADDRESS 0x76
void setup()
{
  // シリアル通信の初期化 (通信速度 : 9600[bps])
  Serial.begin(9600);
  // I2C通信の初期化
  Wire.begin();
  // BME280センサの初期化
  if (!bme.begin(BME280_ADDRESS)) {
    Serial.println("BME280センサが見つかりません。配線を確認してください。");
    while (1);  // エラーの場合は無限ループ
  }
  Serial.println("BME280センサの初期化が完了");
  Serial.println("測定を開始...");
  // ヘッダの出力
  Serial.println("温度(℃), 湿度(%), 気圧(hPa)");
}
void loop()
{
  // 各センサ値の読み取り
  float temperature = bme.readTemperature();    // 温度 (℃)
  float humidity = bme.readHumidity();          // 湿度 (%)
  float pressure = bme.readPressure() / 100.0F; // 気圧 (hPa)
  // 測定値の出力
  Serial.print(temperature, 1);  // 小数点以下1桁まで表示
  Serial.print(", ");
  Serial.print(humidity, 1);
  Serial.print(", ");
  Serial.println(pressure, 1);
  // 1秒間待機
  delay(1000);
}
</syntaxhighlight>
<br>
==== SPI接続の使用例 ====
以下の例では、Arduino UNOにBME280をSPI接続して温度、湿度、大気圧を受信して、シリアルモニタに出力している。<br>
<br>
<u>※注意 1</u><br>
<u>電源は3.3Vを使用する必要がある。(5[V]は使用不可)</u><br>
<br>
ピン定義<br>
* CSピン : Pin 10
* SCK : Pin 13
* MISO : Pin 12
* MOSI : Pin 11
<br>
<u>※注意 2</u><br>
<u>BME280モジュールがSPI通信に対応していることを確認する。</u><br>
<u>配線は必ずSPIの仕様に従うこと。</u><br>
<br>
<syntaxhighlight lang="c++">
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// BME280のCSピン設定
#define BME_CS_PIN 10  // Arduino UNO R3 / R4のデフォルトCSピン
                        // CS (SS) ピンは、Pin 10はデフォルトのSSピンであるが、任意のデジタルピンをCSピンとして使用できる
                        // 例えば、複数のSPIデバイスを使用する場合は、異なるデジタルピンをCSとして割り当てることが可能である
// SPIの設定
#define BME_SCK 13  // SCKピン
#define BME_MISO 12  // MISOピン
#define BME_MOSI 11  // MOSIピン
// BME280センサのインスタンスを生成 (SPIモード)
Adafruit_BME280 bme(BME_CS_PIN);  // CSピンを指定
void setup()
{
  // シリアル通信の初期化 (通信速度 : 9600[bps])
  Serial.begin(9600);
  // CSピンを出力モードに設定
  pinMode(BME_CS_PIN, OUTPUT);
  // SPI通信の初期化
  SPI.begin();
  // BME280センサの初期化 (SPIモード)
  if (!bme.begin()) {
    Serial.println("BME280センサーが見つかりません。配線を確認してください。");
    Serial.println("・CS → Pin 10");
    Serial.println("・SCK → Pin 13");
    Serial.println("・MISO → Pin 12");
    Serial.println("・MOSI → Pin 11");
    Serial.println("・VCC → 3.3V");
    Serial.println("・GND → GND");
    while (1);  // エラーの場合は無限ループ
  }
  Serial.println("BME280センサの初期化が完了");
  Serial.println("測定を開始...\n");
  // ヘッダの出力
  Serial.println("温度(℃), 湿度(%), 気圧(hPa)");
}
void loop()
{
  // 各センサ値の読み取り
  float temperature = bme.readTemperature();    // 温度 (℃)
  float humidity = bme.readHumidity();          // 湿度 (%)
  float pressure = bme.readPressure() / 100.0F; // 気圧 (hPa)
  // 測定値の出力
  Serial.print(temperature, 1);  // 小数点以下1桁まで表示
  Serial.print(", ");
  Serial.print(humidity, 1);
  Serial.print(", ");
  Serial.println(pressure, 1);
  // 1秒間待機
  delay(1000);
}
</syntaxhighlight>
<br>
==== BME280のI2Cアドレス (0x76 または 0x77) の見分け方 ====
* SDOピン (アドレス選択ピン) の状態による変化
** SDOピンがVDDIO (HIGH) に接続されている場合
**: 0x77
** SDOピンがGND (LOW) に接続されている場合
**: 0x76
** SDOピンが浮いている (未接続) 場合
**: 内部プルアップにより0x77
<br>
* モジュールの種類による違い
** 青い基板のBME280モジュール
**: 多くの場合は、0x77
** 黒い基板のBME280モジュール
**: 多くの場合は、0x76
<br>
* メーカーによる違い
** Boschの純正品
**: 0x76
** 他社製
**: 0x77に設定されていることがある
<br>
アドレスが不明の場合は、以下に示すような対応を行う。<br>
# まず、0x76で試す。
# 認識されない場合は、0x77を試す。
# どちらも認識されない場合は、I2Cアドレススキャナプログラムを使用してアドレスを確認する。
<br>
<syntaxhighlight lang="c++">
// I2Cアドレススキャナプログラムの例
// 接続されているBME280のI2Cアドレスを確認することができる
#include <Wire.h>
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("I2Cアドレススキャナ");
  Serial.println("デバイスを検索中...");
}
void loop()
{
  byte error, address;
  int nDevices = 0;
  for(address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2Cデバイスが見つかりました アドレス 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address, HEX);
      nDevices++;
    }
  }
  if (nDevices == 0) {
    Serial.println("I2Cデバイスが見つかりませんでした。");
  }
  delay(5000);  // 5秒待機
}
</syntaxhighlight>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Arduino]]
[[カテゴリ:Arduino]]

2024年12月22日 (日) 08:24時点における最新版

概要

DHT-11はサーミスタと異なり、温度と湿度のキャリブレーション済みの状態で出荷されているセンサ(デジタル信号)である。
一般的な利用において、温度は1[℃]程度の誤差、湿度は4[%]程度の誤差で測定できる。

ピンの割り当ては、下図の通りである。

Arduino DHT11 1.png


4本のピンは左から順に、VDD、DATA、NC(非接続)、GNDである。
VDDへの供給電圧は、3.3[V]〜5.5[V]の範囲である。

データシートを確認すると、VDDとGNDの間にパワーフィルタリングとして0.1[μF]のセラミックコンデンサを設置することができる。

データはシングル・バス・データフォーマットで少々面倒であるが、ArduinoではDHT用のライブラリが多数あるので、それらを使用する。
データのサンプリング間隔は最短で1[s]なので、ソフトウェア側でデータを取得する時に、delayする必要がある。

2番ピンであるDATAピンはプルアップして使用する。プルアップ抵抗は、ワイヤが20[m]以下の場合は、5[kΩ]程度が推奨される。
一般的には、4.7[kΩ]〜10[kΩ]程度がよく使用されている。
なお、Arduinoの内部プルアップ抵抗は20[kΩ]なので、DHT-11では使用できない。


DHT-11 / DHT-21

DHT-11 / DHT-21を使用するには、Adafruit DHTセンサライブラリをインストールする必要がある。

Adafruit DHTセンサライブラリのインストールする。

  1. Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [ライブラリを管理]を選択する。
  2. [ライブラリの管理]画面が起動するので、検索項目から"Adafruit Unified Sensor"と入力する。
  3. ライブラリ一覧が表示されるので、Adafruit Unified Sensorを選択して、リスト右側にある[Install]ボタンを押下する。
  4. 次に、Adafruit DHTセンサライブラリのGithubにアクセスして、zipファイルをダウンロードする。
  5. Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール]を選択する。
  6. ダウンロードしたzipファイルを選択して、Adafruit DHTセンサライブラリをインストールする。


まず、DHT-11から温度と湿度を取得する。
さらに、温度と湿度からヒートインデックス(体感温度)が取得できるので、それも併せて取得する。

以下の例では、シリアルポートに値を出力している。
シリアルモニタを開くことにより、3秒ごとに結果が出力される。

LCDに出力する場合は、Arduinoを用いてLCDに文字を表示を参照すること。

Arduino-DHT11 2.png
 #include <DHT.h>
 
 const int PIN_DHT = 8;
 DHT dht( PIN_DHT, DHT11 );
 
 void setup()
 {
    Serial.begin(9600);
    Serial.println("DHT11");
    dht.begin();
 }
 
 void loop()
 {
    delay(3000);
 
    bool isFahrenheit = true;
    float percentHumidity = dht.readHumidity();
    float temperature = dht.readTemperature( isFahrenheit );
 
    if (isnan(percentHumidity) || isnan(temperature))
    {
       Serial.println("ERROR");
       return;
    }
 
    float heatIndex = dht.computeHeatIndex(temperature, percentHumidity, isFahrenheit);
 
    String s = "Temp: ";
    s += String(temperature, 1);
    s += "[F] Humidity: ";
    s += String(percentHumidity, 1);
    s += "[%] HI: ";
    s += String(heatIndex, 1);
 
    Serial.println(s);
 }



BME280

BME280とは

BME280センサモジュールは、気圧、温度、湿度を読み取ることができる。
気圧は高度によって変化するため、高度も推定することもできる。

BME280センサモジュールには、I2C通信またはSPI通信を使用してArduinoへデータを送信する。

BME280 1.png
図. BME280センサモジュール I2C接続 (4ピン)



BME280 2.png
図. BME280センサモジュール SPI接続 (6ピン)



BME280センサモジュール (I2C接続) の回路図を以下に示す。

BME280 3.png


I2C通信を使用する場合は、BME280センサモジュールとArduino UNOのI2Cピンを下表のように接続する。

BME280 Arduino UNO R3 / R4
SCK (SCLピン) A5
SDI (SDAピン) A4


SPI通信を使用する場合は、BME280センサモジュールとArduino UNOのI2Cピンを下表のように接続する。

BME280 Arduino UNO R3 / R4
SCK (SPIクロックピン) Pin 13
SDO (MISO) Pin 12
SDI (MOSI) Pin 11
CS (Chip Select) Pin 10


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

Adafruit BME280ライブラリをインストールする。

  1. Arduino IDEを起動して、[スケッチ] - [インクルードライブラリ] - [ライブラリの管理]を選択する。
  2. 検索ボックスから、"adafruit bme280"を検索して、ライブラリをインストールする。


I2C接続の使用例

以下の例では、Arduino UNOにBME280をI2C接続して温度、湿度、大気圧を受信して、シリアルモニタに出力している。

※注意
SPI通信を行う場合は、SDOをHighにして、アドレスを0x77で取得する必要がある。

 #include <Wire.h>
 #include <Adafruit_Sensor.h>
 #include <Adafruit_BME280.h>
 
 // BME280センサのインスタンスを生成
 Adafruit_BME280 bme;
 
 // BME280のI2Cアドレス (0x76または0x77)
 #define BME280_ADDRESS 0x76
 
 void setup()
 {
   // シリアル通信の初期化 (通信速度 : 9600[bps])
   Serial.begin(9600);
 
   // I2C通信の初期化
   Wire.begin();
 
   // BME280センサの初期化
   if (!bme.begin(BME280_ADDRESS)) {
     Serial.println("BME280センサが見つかりません。配線を確認してください。");
     while (1);  // エラーの場合は無限ループ
   }
 
   Serial.println("BME280センサの初期化が完了");
   Serial.println("測定を開始...");
 
   // ヘッダの出力
   Serial.println("温度(℃), 湿度(%), 気圧(hPa)");
 }
 
 void loop()
 {
   // 各センサ値の読み取り
   float temperature = bme.readTemperature();    // 温度 (℃)
   float humidity = bme.readHumidity();          // 湿度 (%)
   float pressure = bme.readPressure() / 100.0F; // 気圧 (hPa)
 
   // 測定値の出力
   Serial.print(temperature, 1);  // 小数点以下1桁まで表示
   Serial.print(", ");
   Serial.print(humidity, 1);
   Serial.print(", ");
   Serial.println(pressure, 1);
 
   // 1秒間待機
   delay(1000);
 }


SPI接続の使用例

以下の例では、Arduino UNOにBME280をSPI接続して温度、湿度、大気圧を受信して、シリアルモニタに出力している。

※注意 1
電源は3.3Vを使用する必要がある。(5[V]は使用不可)

ピン定義

  • CSピン : Pin 10
  • SCK : Pin 13
  • MISO : Pin 12
  • MOSI : Pin 11


※注意 2
BME280モジュールがSPI通信に対応していることを確認する。
配線は必ずSPIの仕様に従うこと。

 #include <SPI.h>
 #include <Adafruit_Sensor.h>
 #include <Adafruit_BME280.h>
 
 // BME280のCSピン設定
 #define BME_CS_PIN 10  // Arduino UNO R3 / R4のデフォルトCSピン
                        // CS (SS) ピンは、Pin 10はデフォルトのSSピンであるが、任意のデジタルピンをCSピンとして使用できる
                        // 例えば、複数のSPIデバイスを使用する場合は、異なるデジタルピンをCSとして割り当てることが可能である
 
 // SPIの設定
 #define BME_SCK 13   // SCKピン
 #define BME_MISO 12  // MISOピン
 #define BME_MOSI 11  // MOSIピン
 
 // BME280センサのインスタンスを生成 (SPIモード)
 Adafruit_BME280 bme(BME_CS_PIN);  // CSピンを指定
 
 void setup()
 {
   // シリアル通信の初期化 (通信速度 : 9600[bps])
   Serial.begin(9600);
 
   // CSピンを出力モードに設定
   pinMode(BME_CS_PIN, OUTPUT);
 
   // SPI通信の初期化
   SPI.begin();
 
   // BME280センサの初期化 (SPIモード)
   if (!bme.begin()) {
     Serial.println("BME280センサーが見つかりません。配線を確認してください。");
     Serial.println("・CS → Pin 10");
     Serial.println("・SCK → Pin 13");
     Serial.println("・MISO → Pin 12");
     Serial.println("・MOSI → Pin 11");
     Serial.println("・VCC → 3.3V");
     Serial.println("・GND → GND");
     while (1);  // エラーの場合は無限ループ
   }
 
   Serial.println("BME280センサの初期化が完了");
   Serial.println("測定を開始...\n");
 
   // ヘッダの出力
   Serial.println("温度(℃), 湿度(%), 気圧(hPa)");
 }

 void loop()
 {
   // 各センサ値の読み取り
   float temperature = bme.readTemperature();    // 温度 (℃)
   float humidity = bme.readHumidity();          // 湿度 (%)
   float pressure = bme.readPressure() / 100.0F; // 気圧 (hPa)
 
   // 測定値の出力
   Serial.print(temperature, 1);  // 小数点以下1桁まで表示
   Serial.print(", ");
   Serial.print(humidity, 1);
   Serial.print(", ");
   Serial.println(pressure, 1);
 
   // 1秒間待機
   delay(1000);
 }


BME280のI2Cアドレス (0x76 または 0x77) の見分け方

  • SDOピン (アドレス選択ピン) の状態による変化
    • SDOピンがVDDIO (HIGH) に接続されている場合
      0x77
    • SDOピンがGND (LOW) に接続されている場合
      0x76
    • SDOピンが浮いている (未接続) 場合
      内部プルアップにより0x77


  • モジュールの種類による違い
    • 青い基板のBME280モジュール
      多くの場合は、0x77
    • 黒い基板のBME280モジュール
      多くの場合は、0x76


  • メーカーによる違い
    • Boschの純正品
      0x76
    • 他社製
      0x77に設定されていることがある


アドレスが不明の場合は、以下に示すような対応を行う。

  1. まず、0x76で試す。
  2. 認識されない場合は、0x77を試す。
  3. どちらも認識されない場合は、I2Cアドレススキャナプログラムを使用してアドレスを確認する。


 // I2Cアドレススキャナプログラムの例
 // 接続されているBME280のI2Cアドレスを確認することができる
 
 #include <Wire.h>
 
 void setup()
 {
   Wire.begin();
   Serial.begin(9600);
   Serial.println("I2Cアドレススキャナ");
   Serial.println("デバイスを検索中...");
 }
 
 void loop()
 {
   byte error, address;
   int nDevices = 0;
 
   for(address = 1; address < 127; address++) {
     Wire.beginTransmission(address);
     error = Wire.endTransmission();
 
     if (error == 0) {
       Serial.print("I2Cデバイスが見つかりました アドレス 0x");
       if (address < 16) {
         Serial.print("0");
       }
 
       Serial.println(address, HEX);
       nDevices++;
     }
   }
 
   if (nDevices == 0) {
     Serial.println("I2Cデバイスが見つかりませんでした。");
   }
 
   delay(5000);  // 5秒待機
 }