風呂を上がった後の、浴室の湿度経過を測定したくなったので、作りました。浴室の温湿度を定期的に測定し、SDカードにCSVで保存します。
つくりかた
ハードウェア
- ESP32 Devkit-C
- 温湿度センサ DHT20
- マイクロSDカードスロットDIP化キット
- 適当なマイクロSDHCカード
- SDXCだと上手くいかない可能性があります
- ブレッドボード・ジャンパ
- ESP32の幅が広いので、片側だけに電源ラインのあるブレッドボードを使います
これらを以下のように配線します。
SDカードスロット | ESP32 |
---|---|
① DAT2 | – |
② CD/DAT3 | 5 (SS) |
③ CMD | 23 (MOSI) |
④ VDD | 3V3 |
⑤ CLK | 18 (SCK) |
⑥ VSS | GND |
⑦ DAT0 | 19 (MISO) |
⑧ DAT1 | – |
⑨ スイッチB | – |
⑩ スイッチA | – |
DHT20 | ESP32 |
---|---|
① VDD | 3V3 |
② SDA | 21 |
③ GND | GND |
④ SCL | 22 |
こんな感じになりました。電源はモバイルバッテリーから給電します。
ソフトウェア
setup() でNTPを使った時刻合わせを行い、loop() で10秒おきにセンサから温湿度を取得してSDカードに保存しています。CSVには、現在時刻, 温度, 湿度 の順に記録されます。
温湿度の取得は、Arduinoのライブラリマネージャーで「DHT20」と検索するとライブラリが見つかるので、サクッと実行できます。検索結果が2つ出てきますが、よりプロトコルに忠実らしい Rob Tillaart 版を使いました。
#include <SPI.h> #include <SD.h> #include <DHT20.h> #include <WiFi.h> #include "time.h" #include "esp_sntp.h" const char* ssid = WIFI_SSID; // your SSID const char* password = WIFI_PASS; // your password const char* ntpServer = "ntp.nict.jp"; const long gmtOffset_sec = 3600 * 9; // UTC+9 const int daylightOffset_sec = 0; // summer time bool readDone = false; bool ntpDone = false; DHT20 dht20 = DHT20(); void setup() { Serial.begin(115200); // connect to WiFi Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" CONNECTED"); // get time from ntp server configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // wait until RTC is updated while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET) { delay(1000); } // disconnect WiFi as it's no longer needed WiFi.disconnect(true); WiFi.mode(WIFI_OFF); Serial.println("WiFi DISCONNECTED"); // initialize SD card if (!SD.begin()) { Serial.println("Card Mount Failed"); return; } uint8_t cardType = SD.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD card attached"); return; } // begin DHT20 temperature and humidity sensor dht20.begin(21, 22); // ESP32 I2C default pin: SDA(21), SCL(22) } void loop() { // get current time struct tm timeinfo; getLocalTime(&timeinfo); // if second is 0, 10, 20, 30, 40 or 50 if (timeinfo.tm_sec % 10 == 0) { // check readDone flag in order not to read twice or more if (!readDone) { // set readDone flag readDone = true; // read temperature and humidity. It takes 50ms if (dht20.read() == DHT20_OK) { float humidity = dht20.getHumidity(); float temperature = dht20.getTemperature(); char timeString[20] = "2000/01/01 00:00:00"; snprintf(timeString, 20, "%04d/%02d/%02d %02d:%02d:%02d", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec ); // write time as yyyy/mm/dd hh:mm:ss format String dataString; dataString += String(timeString) + ","; dataString += String(temperature) + ","; dataString += String(humidity); // open the file (need '/' before file name) File dataFile = SD.open("/datalog.txt", FILE_APPEND); // if the file is available, write to it: if (dataFile) { dataFile.println(dataString); dataFile.close(); Serial.println(dataString); // if the file isn't open, pop up an error: } else { Serial.println("error opening datalog.txt"); } } } } else { readDone = false; } delay(10); }
結果
- 測定日:2022/12/17
- 測定場所:東京都内某所の自宅
- 測定時の天気:くもり。21時ごろから一時雨
- その他条件:浴室の換気扇は常時ON、浴室内にバスタオルを干している
朝7:30に風呂を上がって、10時頃に家を出て、20時すぎに帰宅した一日の記録です。ちなみに22~23時にかけて浴室に隣接している台所で煮物を作っていたので、湿度が上がっています。
湿度が時間の経過とともに綺麗に下がるかなと思っていたのですが、意外にそんなことはなく、温度のほうが綺麗に下がっています。
湿度を見てみると、7:30に風呂を上がってから2時間程度は順調に下がったのですが、横ばいになったあと11時過ぎから上昇に転じています。11時から15時にかけて、湿度が高い時間帯が出来ているのですが、この時間帯は家にいないはずです。なぜだ……。
全期間を通して、湿度がカビ発生目安である60%を下回ることはないらしく、ずっと換気し続ける必要がありそうです。
まぁ1回の記録ではなんともいえないので、しばらくデータを取ってみます。また、隣接する台所の湿度も同時に取ってみたいと思います。