「Arduinoの基礎 - 温湿度センサ」の版間の差分
細 (文字列「</source>」を「</syntaxhighlight>」に置換) |
|||
(同じ利用者による、間の3版が非表示) | |||
1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
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(非接続) | 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 == | ||
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> | |||
シリアルモニタを開くことにより、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[%]程度の誤差で測定できる。
ピンの割り当ては、下図の通りである。
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センサライブラリのインストールする。
- Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [ライブラリを管理]を選択する。
- [ライブラリの管理]画面が起動するので、検索項目から"Adafruit Unified Sensor"と入力する。
- ライブラリ一覧が表示されるので、Adafruit Unified Sensorを選択して、リスト右側にある[Install]ボタンを押下する。
- 次に、Adafruit DHTセンサライブラリのGithubにアクセスして、zipファイルをダウンロードする。
- Arduino IDEのメニューバー[スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール]を選択する。
- ダウンロードしたzipファイルを選択して、Adafruit DHTセンサライブラリをインストールする。
まず、DHT-11から温度と湿度を取得する。
さらに、温度と湿度からヒートインデックス(体感温度)が取得できるので、それも併せて取得する。
以下の例では、シリアルポートに値を出力している。
シリアルモニタを開くことにより、3秒ごとに結果が出力される。
LCDに出力する場合は、Arduinoを用いてLCDに文字を表示を参照すること。
#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センサモジュール (I2C接続) の回路図を以下に示す。
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ライブラリをインストールする。
- Arduino IDEを起動して、[スケッチ] - [インクルードライブラリ] - [ライブラリの管理]を選択する。
- 検索ボックスから、"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
- SDOピンがVDDIO (HIGH) に接続されている場合
- モジュールの種類による違い
- 青い基板のBME280モジュール
- 多くの場合は、0x77
- 黒い基板のBME280モジュール
- 多くの場合は、0x76
- 青い基板のBME280モジュール
- メーカーによる違い
- Boschの純正品
- 0x76
- 他社製
- 0x77に設定されていることがある
- Boschの純正品
アドレスが不明の場合は、以下に示すような対応を行う。
- まず、0x76で試す。
- 認識されない場合は、0x77を試す。
- どちらも認識されない場合は、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秒待機
}