SPRESENCEとDHT11で作る 窓際専用温湿度計測器
初めに:
窓際の温度が室温と違うと色々不都合(結露・床焼け・冷暖房効きにくい原因等)、室温測定はすでにしているので、比較する為以下の仕様を考えました。
仕様:
測定場所とデータ保存するPCとは1M位の距離なので有線接続する
測定時刻も取得する
電源は太陽電池とリチウムポリマー電池の充電器経由で給電する
温度と湿度の測定をする
太陽電池の出力を5V最大にしたADCで取り込む
ハードウェア:
マイコンはGPS内蔵のSPRESENCEを使いました。
温度センサーはインターフェース電圧がSPRESENCEとちょっと違うけど
I2Cセンサーより単純そうなDHT11を使いました。
太陽電池の出力がADCの最大超えないようなイメージで40kΩと10kΩで分圧しました。
部品表:
SPRESENSEメイン基板 1枚
DHT11 温湿度センサー 1個
84.5x65mm 太陽電池パネル 1枚
ソーラリチウムポリマー電池充電基板 1枚
抵抗 太陽電池プラス側40kΩ
太陽電池マイナス側10kΩ
DHT11は本来プルアップ抵抗入れますが、SPRESENCEのIOが1.8Vなので
あえてプルアップせず10kΩの抵抗を直列に入れています。
回路図:
DHT11はSPRESENSEからに3.3V、データ線に10kΩ抵抗を直列にいれています。
※10kΩは入れても入れなくても動作しました。
ブルーの線はUART-USB変換やラズベリーパイなどのUART-RXDに接続します
ブラックの線はUART-USB変換やラズベリーパイなどのGNDに接続します
製作品
測定データ仕様
測定時刻とDHT11の温湿度、ソーラパネル出力を分圧してSPRESENSEのADCに入れた値の3つをCSV出力し、測定場所から2mの2芯シールド線でホストコンピュータに3分に一回シリアル転送します。
プログラム:
/*
* DHT11とリチウムポリマー電池用ソーラ充電器の太陽電池電圧を測定し
* シリアル接続でパソコンに送信する。
* 測定時刻は内蔵gnssが取得した時間を使う
* DHT11のライブラリはadafroutsのDHT11を使用した
* 参考文献 SPRESENCEのサンプルプログラムとネット情報いろいろ
*/
#include <DHT.h>
#define DHTPIN 22 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
#include <RTC.h>
#include <GNSS.h>
SpGnss Gnss;
50
#define MY_TIMEZONE_IN_SECONDS (9 * 60 * 60) // JST
void printClock(RtcTime &rtc)
{
float h = dht.readHumidity();
// Read temperature as Celsius (false)
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
int sensor1 = analogRead(A2);
String data = ""+String(rtc.year())+","+String(rtc.month())
+","+String(rtc.day())+","+String(rtc.hour())+":"+String(rtc.minute())
+","+String(t)+","+String(h)+","+String(sensor1);
Serial.println(data);
Serial2.println(data);
}
void updateClock()
{
static RtcTime old;
RtcTime now = RTC.getTime();
// Display only when the second is updated
if (now != old) {
printClock(now);
old = now;
}
}
void setup()
{
Serial.begin(1200);
sleep(5);
Serial2.begin(1200);
sleep(5);
while (!Serial);
Serial.println("Example for GPS clock");
//Initialize DHT11
dht.begin();
// Initialize RTC at first
RTC.begin();
int ret;
ret = Gnss.begin();
assert(ret == 0);
ret = Gnss.start();
assert(ret == 0);
// LowPower.clockMode(CLOCK_MODE_32MHz);
// delay(200);
}
void loop()
{
// Wait for GNSS data
if (Gnss.waitUpdate()) {
SpNavData NavData;
// Get the UTC time
Gnss.getNavData(&NavData);
SpGnssTime *time = &NavData.time;
// Check if the acquired UTC time is accurate
if (time->year >= 2000) {
RtcTime now = RTC.getTime();
// Convert SpGnssTime to RtcTime
RtcTime gps(time->year, time->month, time->day,
time->hour, time->minute, time->sec, time->usec * 1000);
#ifdef MY_TIMEZONE_IN_SECONDS
// Set the time difference
gps += MY_TIMEZONE_IN_SECONDS;
#endif
int diff = now - gps;
if (abs(diff) >= 1) {
RTC.setTime(gps);
}
}
}
updateClock();
delay(50000); //測定間隔設定
}
測定データ出力:
Arduino-IDEのシリアルコンソール画面です。使うときはパソコン側でシェルスクリプトつかい
データ取り込みます。
シェルスクリプト例
ラズベリーパイでデータ受信してMQTTパブリッシャーを使いデータ送信する場合の例です
#!/bin/bash
TTY="/dev/ttyACM0"
# -lは標準入力を読みます -mはメッセージを送ります -fはファイルを指定します
MOSQUITTO_COMMAND="/usr/bin/mosquitto_pub -h hostname.local -u user-name -P passwd -t sensor/dht11-110 -l"
while true; do
read -r line < "$TTY"
# echo "Received: $line" 動作確認用
echo "$line" |eval $MOSQUITTO_COMMAND
done
ご注意:
GPS電波受信困難な場所では時刻取得失敗します。
設置場所は窓際で天空が見える場所にする必要あります。
LowPower.hを入れるとdelay()の動作が変わってしまうようで、毎回setup()から動作してしまい
電波受信良くない場所でつかうと一向に時刻取得しないのでLowPower.hは使いませんでした。
投稿者の人気記事
-
Makato-kan
さんが
2022/09/24
に
編集
をしました。
(メッセージ: 初版)
-
Makato-kan
さんが
2022/09/24
に
編集
をしました。
-
Makato-kan
さんが
2024/02/19
に
編集
をしました。
(メッセージ: シェルスクリプトを追加しました。)
ログインしてコメントを投稿する