省電力モードに改良して再運用だぜっ!!
ツイート2019年6月29日(土)
「芝生×IoT」
先週6/23(日)夕方から運用を開始したセンサー部ですが、
25日(火)15時半以降からAmbientへのデータが登録されなくなった。
そう、電池がなくなって停止してしまったのだ・・・。
土曜夜からテスト運転させていたので、約3日程度しか持たない代物になったよ・・・(汗)
マンガン乾電池がいけないのかと思い、急遽アルカリ乾電池に変更して再運用させておいた。
そしたら・・・、
なんと・・・、
本日までしっかり動いているではないかっ!!!
やはりアルカリ乾電池ってスゲェ!選択するのはマンガン乾電池じゃなかったって事だね・・・(苦笑)
本日時点でアルカリ乾電池2本の電圧を計ったら2.7V残っていた。新品で約3V強だったので4日で0.3Vしか使用していないことになる。
やっぱりアルカリ乾電池ってスゲェ!
一応、電力の使い過ぎなのかと思って、省電力動作の方法を色々調べてみた。
そしたら、やばい情報を発見してしまった。
「土壌湿度センサーに電流流しっぱなしにすると、センサー部の劣化が早まる」って!?
やばい!?
直ぐに我が家の物を確認すると、こんな状態になっていた。
一部金メッキがはがれている・・・(涙)
これではまずいので省電力版に改良します。書込み用ブレッドボードに乗せ換えてスケッチを改良。
どうしたかというと、
センサーへの電源はESP8266へ供給されている電源(3.3V)から取っていました。
これだとESP8266がsleep中でもセンサー部には常に3.3Vが流れ続けてしまっているので、無駄な電力を喰ってしまっている。
さらに、これが土壌湿度センサーの劣化を早める原因になっていた・・・(涙)
そこで、センサー部への電力供給を使用していないポート(IO13)から計測時のみ電力供給するように改良した。
計測前にIO13に電力供給し、処理終了時(DeepSleep突入直前)に電力供給を断つようにすることで、無駄な電力を使わないようにした。
左側がsleep中、右が計測中。
センサー部に電力供給される時間は2秒程度。電力供給タイミングとセンサーの計測タイミングがなかなか合わず、当初は計測値が取れず苦労した。
以外に時間が掛かっているが、計測できないよりは、確実に計測処理を完了させる方を選択した結果だ。ただ、細かく計算するのが面倒なので適当に設定しちゃった
計測後は約60分sleepする。これを繰り返すのでセンサー部に電力が供給される時間は24時間で約50秒前後程度のみとなった。
今までは24時間常に電力が供給されていたので、かなりの電力節約が出来たことだろう。
そして、もう一つ「電気二重層コンデンサー」なるものを2つ追加してみた。
Before(左)※センサーついてません、After(右)※センサーついてます
※左側のオレンジ色の長いジャンパ線を1番(3V3)から5番(IO13)に刺し替えた。そこに土壌湿度センサーの赤いコードを一緒に刺し、5番(IO13)からセンサーへの電力供給をする。
After(右)側の左側にあるシルバーの丸いものが「電気二重層コンデンサー」です。
いわゆる充電池ですが、非常に充電時間が早く大容量なのです。
容量は2個で2500μF(1000μF + 1500μF)。
・・・って言われても私も???
これによって、乾電池が残り少なくなってもコンデンサーから電力が供給され、
ギリギリまで乾電池を使いきれるらしい・・・。それにより持ちがよくなるらしい・・・。
残2.7Vからどの位の期間電池が持ってくれるか?
これもちゃんと報告いたします。
さぁ、これで暫定ですが最終版の完成としたい。
なぜ暫定か?
散水部との連携を残しているからね。連携処理は後半の作業に織り込む事としますね。
前半のセンサー部についてはこれで完了。何も問題が起きなければね
ちなみに、運用版のみだけで掛かった費用は3,500円程度。
開発ボードはちょっと割高ですが、余計な物が不要なので初めてでも取り掛かりやすいかな。
今回揃えたもの全部含めると1万円前後位ですので、一応お小遣いの範囲で完成できました。
って、まだ散水部が残ってるけど、買い足すものはESP8266(650円)と他に3,000円位かな~。たぶん
月を跨げば、お小遣いで細かく買い足せる範囲だよね。
アイデア次第で色々な物を作ることができるので意外に楽しいです。
ご興味があれば是非チャレンジしてみてください。
Arduinoのスケッチはオープンソースなので、今回の私のセンサー部で動かしているスケッチを公開しておきます。
※センスのないスケッチなのであしからず
闘え、ボンビーリーマン!
負けるな、ボンビーリーマン!
常緑のために!
スケッチ
※スペース、タブが削除されてしまい、見づらくなっておりごめんなさい。
同じ構成であれば、このままコピペで動くはずです。
※WiFi、Ambient、LINE NotifyのID、パスワードはご自身の物に変更必須です。
処理順序はsetup()、 loop()の順に処理されます。
回路図はないですが、以下写真を参考に配線を確認ください。
詳細を知りたい方は、ご遠慮なくコメント欄にてお問い合わせくださいね。
#include "Wire.h"
#include "ESP8266WiFi.h"
#include "BME280_MOD-1022.h"
#include "Ambient.h"
#include "WiFiClientSecure.h" //LINE Notify
extern "C" {
#include "user_interface.h"
}
//******************************************
//定数宣言
//WiFi Access Point
#define WLAN_SSID "自分のSSID"
#define WLAN_PASS "自分のPASS"
#define PIN_SEN 13 // IO13(5番ピン)をセンサー電源とし間欠起動する
//Ambient キー設定
unsigned int channelId = 自分のID;
const char* writeKey = "自分のkey";
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
Ambient ambient;
//LINE Notify
const char* lineApiToken = "自分のlineApiToken";
//*****************************************
float temperature = 0.0;
float humidity = 0.0;
float pressure = 0.0;
void printFormattedFloat(float val) {
char buffer[10];
dtostrf(val, 4, 2, buffer);
Serial.println(buffer);
}
//Wi-Fi接続処理関数
void setupWiFi() {
// Connect to WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
//WiFi start
WiFi.begin(WLAN_SSID, WLAN_PASS);
int wifiCounter = 0;
//WiFi接続完了までループ
while (WiFi.status() != WL_CONNECTED) {
delay(450);
Serial.print(".");
//20回失敗したらリセット→再試行
if(wifiCounter > 20) {
digitalWrite(PIN_SEN,LOW); // 電力停止
Serial.println("IO13 error end.");
Serial.println("Failed to connect WiFi. Reset now.");
delay(500);
ESP.deepSleep(2 * 1000 * 1000);
delay(1000);
}
delay(50);
wifiCounter++;
}
Serial.println("");
Serial.println("WiFi connected");
// 接続成功 IP address表示
Serial.println(WiFi.localIP());
Serial.println("=================================");
Serial.println("");
}
//LINE送信処理関数
void sendLineNotify(int Value) {
const char* host = "notify-api.line.me";
String message = "土壌湿度値: ";
message += Value;
if(Value <= 350){
message += " 芝生が危険!至急散水";
}
else {
message += " 芝生が水不足 注意して下さい";
}
WiFiClientSecure ClientSecure;
Serial.println("Line-Try");
//LineのAPIサーバに接続
if (!ClientSecure.connect(host, 443)) {
Serial.println("LINE Connection failed");
return;
}
Serial.println("LINE Connected");
//リクエストを送信
String query = String("message=") + String(message);
String request = String("") +
"POST /api/notify HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Authorization: Bearer " + lineApiToken + "\r\n" +
"Content-Length: " + String(query.length()) + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n\r\n" +
query + "\r\n";
ClientSecure.print(request);
//受信終了まで待つ
while (ClientSecure.connected()) {
String line = ClientSecure.readStringUntil('\n');
if (line == "\r") {
break;
}
}
String line = ClientSecure.readStringUntil('\n');
Serial.println(line);
}
//*****************************************
//初期処理
void setup() {
//シリアル出力起動
Serial.begin(115200);
delay(50);
//Wi-Fi接続処理
setupWiFi();
pinMode(PIN_SEN,OUTPUT); // センサ電源用ポートを出力に
digitalWrite(PIN_SEN,HIGH); // 電力供給開始
Serial.println("IO13 start.");
delay(1000);
// I2Cの通信を開始
// SDA: GPIO4
// SCL: GPIO5
Wire.begin(4, 5);
Serial.println("I2C start.");
// BME280を初期化
BME280.readCompensationParams();
// オーバーサンプリングの回数を設定
BME280.writeOversamplingTemperature(os1x);
BME280.writeOversamplingHumidity(os1x);
BME280.writeOversamplingPressure(os1x);
Serial.println("BME280 start.");
// チャネルIDとライトキーを指定してAmbientの初期化
ambient.begin(channelId, writeKey, &client);
Serial.println("Ambient start.");
}
//メイン処理
void loop() {
int sensorValue = 0;
// BME280を1度だけ測定を行うモードに設定し計測が終わるまで待機
BME280.writeMode(smForced);
while (BME280.isMeasuring()) {
delay(1);
}
//土壌湿度センサー値取得
sensorValue = analogRead(A0);
//LINE送信
if(sensorValue < 501){
sendLineNotify(sensorValue);
}
Serial.print("Moisture Sensor Value:");
Serial.println(sensorValue);
// BME280から測定値を読み取る
BME280.readMeasurements();
temperature = BME280.getTemperature();
humidity = BME280.getHumidity();
pressure = BME280.getPressure();
// 読み取った値をシリアルに出力
//温度
Serial.print("Temperature: ");
printFormattedFloat(temperature);
Serial.println(temperature);
Serial.println("");
//湿度
Serial.print("Humidity: ");
printFormattedFloat(humidity);
Serial.println(humidity);
Serial.println("");
//気圧
Serial.print("Pressure: ");
printFormattedFloat(pressure);
Serial.println(pressure);
Serial.println("");
Serial.println("");
// Ambientへのデータ作成
ambient.set(1, sensorValue);
ambient.set(2, temperature);
ambient.set(3, humidity);
ambient.set(4, pressure);
ambient.send();
delay(1000);
digitalWrite(PIN_SEN,LOW); // 電力停止
Serial.println("IO13 end.");
//本版稼働時は60分DeepSleep
ESP.deepSleep(3600 * 1000 * 1000);
//Test 5分
//ESP.deepSleep(300 * 1000 * 1000);
delay(1000);
}
「頑張れ、ボンビーリーマン!」っと思った方は
↓ポチっとお願いますb>
ツイート
↓初めてコメントを入力される際は、「コメント欄使用時のご留意事項」をご覧ください
関連ページ
- 芝生×IoT 修正記録
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT 暑さ対策
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT 新センサーテスト
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト 番外編
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト23
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト22
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト21
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト20
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト19
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト18
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト17
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト16
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト15
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト14
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト13
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト12
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト11
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト10
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト9
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト8(センサ部 再改良)
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト6(センサー稼働開始)
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト5
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト4
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト3
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト2
- ボンビーリーマンの芝生手入れ奮闘の記録
- 芝生×IoT プロジェクト1
- ボンビーリーマンの芝生手入れ奮闘の記録