前回は液晶ディスプレイの省エネ設計にトライしました。
今回は温度計と湿度計を追加して、部屋の温度と湿度をモニタリングします。
温度計は以前、組み込んだことがあります。
【Python】Arduino で温度センサーから室温を取得して画面に表示する(前編)
【Python】Arduino で温度センサーから室温を取得して画面に表示する(後編)
ただ、独立した湿度計が難解でした。
資料も少なく自分にはちょっと敷居が高かったので、
今回は少し難易度を下げてみます。
難易度低めでポピュラーな温湿度センサーがあったので、これを使ってみようと思います。
温度計がセットなので、前回の温度計はお蔵入りにして新しく設計します。
材料
- 温湿度センサ モジュール DHT11
- 10kΩ 抵抗1本
材料はこれだけ。前回使用した Arduino 回路に追加します。
複雑な設計はモジュールに組み込み済みなので、作業は楽ですね。
回路作成
今回参考にさせてもらったページ
DHT11 を用いた温度と湿度の計測 - Arduino - 基礎からの IoT 入門
https://iot.keicode.com/arduino/temperature-dht11.php
![Screenshot_20200208[1].png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F362854%2F5cecdfe1-04e4-e155-75f7-a9be2781de82.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=04b8bfecbf76f7647e8e32bd9b8b7eb7)
上図の DHT11(水色のパーツ)は表裏逆になってます。
左から [GND] [NC] [DATA] [VDD] になるのでご注意ください。
出力は参考ページと同じデジタル 8pin にしました。
オレンジ、イエローの配線は 5V、GND はブラックです。
回路図はシンプルにできたんですが、リアル回路はちょっと混み合ってきました。
この後、気圧計も追加する予定なんですが、どうなることやら。
Arduino プログラムコード
#include <DHT.h>
// Initializing DHT11 sensor
const int PIN_DHT = 8;
DHT dht(PIN_DHT, DHT11);
void setup() {
//start serial connection
Serial.begin(9600);
//configure pin A3 as an input and enable the internal resistor
pinMode(A3, INPUT);
// start DHT11 sensor
dht.begin();
}
void loop() {
// Whether to display in Fahrenheit
bool isFahrenheit = false;
// Get humidity and temperature
float percentHumidity = dht.readHumidity();
float temperature = dht.readTemperature(isFahrenheit);
// Do nothing if not available
if (isnan(percentHumidity) || isnan(temperature)) {
return;
}
// Get heat index
float heatIndex = dht.computeHeatIndex(
temperature,
percentHumidity,
isFahrenheit
);
//read the photocell value into a variable
int photocell = analogRead(A3);
//print out the sensor value in csv format
String s = "";
s += String(temperature, 1) + ",";
s += String(percentHumidity, 1) + ",";
s += String(heatIndex, 1) + ",";
s += String(photocell);
Serial.println(s);
//delay 2000 ms
delay(2000);
}
追加したコードはほとんどが DHT11 ライブラリの操作です。
温度は摂氏で出したいので bool isFahrenheit = false;
としています。
あと、処理が込み入ってきたので2秒間隔のループとしました。
念のためです。
デジタル 8pin から読み込み、前回の照度センサーの値も含め CSV 形式で出力します。
DHT ライブラリの追加
DHT ライブラリは Arduino IDE のライブラリマネージャーから追加できます。
メニューから「ツール → ライブラリを管理」です。
DHT sensor library by Adafruit
スクリーンショットでは Ver.1.3.8 をインストールしました。
Adafruit Unified Sensor by Adafruit
共通ライブラリです。この時点では Ver.1.1.2 をインストールしています。
データベースとユーザーとテーブルを作成
今回からセンサー情報をデータベースに書き込みます。
シリアル接続は複数同時に行うことができないため、
(何か方法はあるのでしょうが、費用がかからない方法として)
データベースに書き込むプログラムを動かし続けて、他のプログラムがデータベースを参照することで情報を共有します。
$ mysql -u root -praspberry
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.1.38-MariaDB-0+deb9u1 Raspbian 9.0
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE sensor;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> CREATE USER 'sensorpi'@'localhost' IDENTIFIED BY 'raspberry';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON sensor.* TO 'sensorpi'@'localhost';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> USE mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]> SELECT user, password, plugin FROM user;
+------------+-------------------------------------------+--------+
| user | password | plugin |
+------------+-------------------------------------------+--------+
| root | ***************************************** | |
| phpmyadmin | ***************************************** | |
| fxpi | ***************************************** | |
| sensorpi | ***************************************** | |
+------------+-------------------------------------------+--------+
4 rows in set (0.01 sec)
MariaDB [mysql]> QUIT;
Bye
pi@raspberrypi:~ $ mysql -u sensorpi -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 34
Server version: 10.1.38-MariaDB-0+deb9u1 Raspbian 9.0
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> USE sensor;
Database changed
MariaDB [sensor]> CREATE TABLE tbl_serval (time DATETIME,
-> max_temperature FLOAT, avg_temperature FLOAT, min_temperature FLOAT,
-> max_humidity FLOAT, avg_humidity FLOAT, min_humidity FLOAT,
-> max_heatIndex FLOAT, avg_heatIndex FLOAT, min_heatIndex FLOAT,
-> max_pressure INT, avg_pressure INT, min_pressure INT,
-> max_photocell INT, avg_photocell INT, min_photocell INT);
Query OK, 0 rows affected (0.05 sec)
項目 | 設定値 |
---|---|
データベース | sensor |
ユーザー | sensorpi |
テーブル | tbl_serval |
tbl_serval の構造はこんな感じ。
NULL は全カラム許容してますが、そのうち見直します。
serval は SERial VALue の略です。
列名 | 型 | NULL | 説明 |
---|---|---|---|
time | DATETIME | 許容 | 記録時刻 |
max_temperature | FLOAT | 許容 | 温度(最大) |
avg_temperature | FLOAT | 許容 | 温度(平均) |
min_temperature | FLOAT | 許容 | 温度(最小) |
max_humidity | FLOAT | 許容 | 湿度(最大) |
avg_humidity | FLOAT | 許容 | 湿度(平均) |
min_humidity | FLOAT | 許容 | 湿度(最小) |
max_heatIndex | FLOAT | 許容 | 体感温度(最大) |
avg_heatIndex | FLOAT | 許容 | 体感温度(平均) |
min_heatIndex | FLOAT | 許容 | 体感温度(最小) |
max_pressure | INT | 許容 | 気圧(最大) |
avg_pressure | INT | 許容 | 気圧(平均) |
min_pressure | INT | 許容 | 気圧(最小) |
max_photocell | INT | 許容 | 照度(最大) |
avg_photocell | INT | 許容 | 照度(平均) |
min_photocell | INT | 許容 | 照度(最小) |
Python プログラムコード
あちこち修正したので、概要だけ。
変更点については、ご興味あれば GitHub(mySensor) & GitHub(DesktopClock) を覗いてみてください。
- 2秒ごとにセンサー情報(CSV 形式)を受信して分割
- 1分間で集計して最大・平均・最小値を算出
- データベースに書き込む
- 置き時計プログラム(DesktopClock)側をシリアル接続から DB 接続に変更
- 1分ごとに DB から最新の値を取得して画面に表示する
![Screenshot_20200208[4].png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F362854%2F67e885b8-250d-20be-b226-f26a3fd0ff65.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=12ac0427d64da77d8c8ab1a4395fa967)
小ネタ
照度が 50 以下のときに、バックライトを消灯する仕組みにしていたのですが
今回の変更のあと、部屋を暗くしてもすぐに消えず、しばらく経ってから消灯するなど、やたら反応が遅くなりました。
Python プログラムを再起動すると直りますが、ちょっとするとまた再発するという感じです。
イロイロ調べた結果、受信バッファが原因だったようです。
# 受信バッファをフラッシュする
self.ser.flushInput()
これをしないと、シリアル接続と同期が取れなくなって
時間経過とともに遅延の幅が大きくなるらしいのです。
イマイチ、ピンとこない感じですが遅延は無くなったのでそういうことなのでしょう。