しばらく運用したところ問題点が浮上したので改善する
消費電力
実際の運用での消費電力量確認のため秋月のニッケル水素電池パック3.6V830mAh(パナソニック製)で室内試行
消費電力を20mAh/日と見積もっていたので40日は厳しくてもひと月は持つかなと思っていたら10日で停止し予想外の結果となる
以下がバッテリー電圧の状態推移で外した時のバッテリーは瀕死だった(試行時のグラフ)
最初の段階で計測したUSBチェッカーの消費電力値を鵜呑みにしたのが失敗だったようで再度見積もってみる
既に回路は出来上がっているので実際に動作させ登録1回分の電流を計測した
左が動作時(70mA前後)で約13秒,右がディープスリープ時の電流(0.28mA)(ビデオ)
(動作時)
通信のあるなしで70mAを前後するようだが70mAとして考える
(ディープスリープ時)
電流は以下のとおりで装置仕様から裏付けられる
ESP8266 |
10μA |
Deep-Sleep時 |
BME280 |
0.1μA |
スリープ・モード |
DHT22 |
50μA |
待機中 |
NJM2884 |
200μA |
無負荷時無効電流 |
電圧測定 |
6~7μA |
分圧抵抗590KΩ(470+120),4~3.5V |
合計 |
0.268mA |
|
(計測データから)
1時間で 13秒 × 6回 = 78秒間動作,1日で 78秒 × 24時間 = 1872秒間 となり
70mA × 1872秒 ÷ 3600秒 = 36.4mAh
ディープスリープ時が(実際は1872s分削除だが無視して)
0.28mA × 24 = 6.72mAh
トータルで1日分が
36.4 + 6.72 = 43.12mAh
10日間で430mAhとなるがバッテリーは830mAhなので充電が不十分だったのかへたっていたのかもしれない
省電力化
三端子レギュレーターをNJM2884から消費電力30μAのNJU7223F33するとディープスリープ時の合計が0.098mAとなり約4.4mAh減るが使用したいバッテリー電圧の関係でNJM2884を選択したため変更はしない
そこでESP8266の動作時間を減らすことができれば電力消費を抑えることができるのでこちらを参考に改善してみた
対応したのは再コネクションの部分で明示的に再コネクションするより必要な情報を退避させておいて自動的に行った方が処理が早いらしい(接続は一定時間保持されているのでネゴのやり直しを行わない分が短縮されるのだろうと考える)
結果,動作時間が13秒から10秒の28.0mAhで合計34.72mAhとなる(ビデオ)
省電力観測モード
通常は1時間に6回(10分毎)の観測を実行する
観測数を減らせば省電力化できるのでバッテリー容量が少なくなってきたら観測数を減らして太陽電池でのバッテリー回復を増大させる仕組みを導入
具体的にはディープスリープ時間を操作すればよく3.5V未満なら30分,3.4V未満になると60分スリープとし,それぞれ1時間に2回と1回の観測にする
アメダスとの温度差
近くにあるアメダスと日別の最高気温と最低気温を比べてみるとプラス方向に差ができている
10/23 曇・雨
最高気温(℃) 20.1 (自宅)21.6 +1.5
最低気温(℃) 13.8 (自宅)15.3 +1.5
10/24 晴
最高気温(℃) 22.5 (自宅)26.6 +4.1
最低気温(℃) 13.6 (自宅)14.8 +1.2
10/25 晴
最高気温(℃) 20.6 (自宅)24.3 +3.7
最低気温(℃) 11.1 (自宅)12.8 +1.7
10/26 晴・曇・雨
最高気温(℃) 21.7 (自宅)25.7 +4.0
最低気温(℃) 10.5 (自宅)11.8 +1.3
10/27 晴(風あり)
最高気温(℃) 20.0 (自宅)23.1 +3.1
最低気温(℃) 14.8 (自宅)14.5 -0.3
しかも晴の日で最高気温差の幅が大きいので鎧戸箱の空気の流れが悪く熱が籠っているのではないかと想定
鉢皿の高さは39mmで鉢皿間を20mmのスペーサーで隙間を空けていたのを30mmのスペーサーにした
20mmの時から比べると大きく隙間が空いたように見える
太陽電池
太陽電池の出力が不足しているようで十分に太陽光が当たっている場合でもバッテリー電圧が上昇しない
搭載する前の実験では40mAの充電量があったため十分かと考えていたが再調整が必要
また太陽電池部分に雨水が溜まるようなので改善しなければならない
スケッチ
現状のESP8266のスケッチ
#include <ESP8266WiFi.h>
#include "DHT.h"
#include "BME280.h"
#define DHTTYPE DHT22 //DHT 22 (AM2302), AM2321
#define DHTPIN 14 //what digital pin we're connected to
#define BME280_ADDRESS 0x76
//DHT22インスタンス
DHT dht(DHTPIN, DHTTYPE);
//BME280インスタンス
BME280 bme280(BME280_ADDRESS //BME280 I2C ADDRESS
, 0b0001 //Temperature oversampling : x1
, 0b0001 //Humidity oversampling : x1
, 0b0001 //Pressure oversampling : x1
, 0b0000 //Mode : Sleep mode(0), Normal mode(3)
, 0b0101 //Stand-by time : 1000ms
, 0b0000 //filter : 0ff
);
//Senser
const int locid = 11; //場所ID
//WiFi
const char *ssid = "ssid";
const char *password = "password";
const char *host = "server_name";
const char *path = "regTenki.php";
const int httpPort = 80;
//Sleep
static int sleepTime = 600; //10分(標準)
void deepSleep() {
//第1引数の時間設定はμ秒なので600秒(10分)後に復帰する設定になる
//+7は(10分での)補正値
ESP.deepSleep((sleepTime + 7) * 1000 * 1000 , WAKE_RF_DEFAULT);
//deepsleepモード移行までのダミー命令
delay(1000);
}
void setup() {
//WiFi接続
if(WiFi.SSID() != ssid) {
//設定が記憶されていないなら接続し記憶させる
WiFi.persistent(true); //ssidとpasswordを保存させる設定
WiFi.mode(WIFI_STA); //STA(子機)モード
WiFi.setAutoConnect(true); //次回起動時に保存内容で接続
WiFi.begin(ssid, password); //初回接続
}
unsigned long timeout = millis();
while(WiFi.status() != WL_CONNECTED) {
if(millis() - timeout > 30000) deepSleep();
delay(500);
}
//DHT22の開始
dht.begin();
//BME280の開始
double dTemperature, dHumidity, dPressure;
bme280.begin();
//DHT22: 温度,湿度
float dhtTemp = dht.readTemperature();
float dhtHumi = dht.readHumidity();
//BME280: 気圧,温度,湿度
bme280.getData(dTemperature, dHumidity, dPressure );
//ADC: バッテリー電圧
float vbat = ((119.0 + 469.0) / 119.0) * system_adc_read() / 1024.0;
if(vbat < 3.4) {
sleepTime = 3600; //3.4V未満になったら60分(最大は71.5分)
} else if(vbat < 3.5) {
sleepTime = 1800; //3.5V未満で30分
} else {
sleepTime = 600; //通常は10分
}
//Requesting POST data
WiFiClient client;
String data = "LOC=" + String(locid) + "&PRES=" + String(dPressure)
+ "&TEMP=" + String(dhtTemp) + "&HUMI=" + String(dhtHumi)
+ "&BVOLT=" + String(vbat);
if(!client.connect(host, httpPort)) {
deepSleep();
}
//Send request to the server
client.println(String("POST ") + path + " HTTP/1.1");
client.println(String("Host: ") + host);
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: " + String(data.length()));
client.println();
client.print(data);
timeout = millis();
while(!client.available()) {
if(millis() - timeout > 5000) {
client.stop();
deepSleep();
}
}
//HTTPヘッダを含むデータの読み取り(1文字毎)
String body = "";
while(client.available()) {
body += client.readStringUntil('\r');
}
if(client.connected()) client.stop();
WiFi.persistent(false); //保存したssidとpasswordが消去させないようにする
//trueのままdisconnect()すると消去される
WiFi.disconnect();
deepSleep();
}
void loop() {}
#include "DHT.h" は,一般的に出回っているので検索で手に入る
#include "BME280.h" は,前に記載したとおりこちらからいただいたスケッチの入出力部(SPIからI2C)とコンストラクタを修正したもの(再配布可能か不明なので記載のみ)