Makato-kan が 2022年09月24日09時48分01秒 に編集
初版
タイトルの変更
SPRESENCEとDHT11で作る 窓際専用温湿度計測器
タグの変更
spresense
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のシリアルコンソール画面です。使うときはパソコン側でシェルスクリプトつかい データ取り込みます。 ### ご注意: GPS電波受信困難な場所では時刻取得失敗します。 設置場所は窓際で天空が見える場所にする必要あります。 LowPower.hを入れるとdelay()の動作が変わってしまうようで、毎回setup()から動作してしまい 電波受信良くない場所でつかうと一向に時刻取得しないのでLowPower.hは使いませんでした。