#WioLTE の電力消費に疲れた方へ
#WioLTE の電力消費に疲れた方へ
#WioLTEを物理で攻めるver2
WioLTEの電力消費で消耗している方向けの最後の手段
どうもくろにゃんこたんです。
こちらの記事は2018年4月までQiitaに掲載していた記事のアーカイブとなります。
全部のスライド資料と解説はこちら
くろにゃんこたん.com
概要
WioLTEの課題として、小型の筐体の割にモバイルバッテリーを駆使するとどうしても一日以内程度でバッテリー切れを起こしてしまう事がありました。
今回は前提条件を絞ることにより、物理現象をトリガーに通信を一発だけしたいときに使える技として、
モバイルバッテリー自体の過充電防止機能を利用してSORACOM Beamを打つ方法を思いつきましたので、スライドにまとめました。
名付けてSCFシステム(自閉式水栓システム)。
温泉に行ったときに、シャワーとかレバーを押すと一定時間シャワーが出てから止まりますよね。
要はあれです。
WioLTEの消費電力を極力抑えることで、バッテリー側が充電終了とみなして、勝手に電源供給をOFFにしてくれる機能をフル活用しました。
これにより、ボタンを押すことさえ出来れば、複数回ノーメンテナンスでBeamを打てます。
前回までのスライド解説
下記個別のスライド解説です。
物理的に攻めるとは?
はい。前回のブレイクスルーです。
マグネットケーブルを利用して、バッテリー側と接続し、それによってBeamを一発打つ。
というものでした。
こんな感じにカチッとハマります。
考え方のブレイクスルーとしては、いろんなセンサーがGroveでくっつけられるWioLTEなのに、常にセンシングしているのではなくて、常に電源をOFFにして、通信にのみフォーカスしたところです。
ラテラル・シンキングでは「縮小」の部類ですね。
前提条件の1と2は良いとして、3と4は結構運用していて面倒でした。
取りに行ったら、マグネットケーブルを外して、紙を挟んで再セット。
この手順が結構億劫です。
だって一回通知をしたらその後取りに行くまでバッテリーは起動したまま。
取りに行く頃にはバッテリーは使い切っているので新しいバッテリーを持ってこないと使えないのです。。。
あとはマグネットケーブルの間に挟むものとしては結構指先が器用じゃないとうまくカチッとならないです。。
ただ上記の様にブレイクスルーとしてはモバイルバッテリーの残量をほぼ気にしなくて良くなったので、
通知を一回飛ばすということ自体は達成は出来たと思います。
バッテリーにもいろいろとありまして、、、
そうなんです。過充電防止機能なんてものがあって、モバイルバッテリー側のUSB端子に刺さったままだと、マグネットケーブルが結線しても、無視されるものもありました。。。
それに伴いIoTでも使えるモバイルバッテリーなんてものも売っています。
確かにこれなら良いのですが、ずっと流しっぱなしなので、結局1日で放電してしまうという本末転倒な事態なわけに。。。
(後につづく)
さてとここまで書いて、
もう少しこのあたりでバッテリーに差異が出ないよう、ピアノ線的なギミックで、ダンボールかアクリルケースでデモを作ろうとしたのですが、
温泉に入りながら考えていたら、( ゚д゚)ハッ!と気づきました。
もともとの課題のモバイルバッテリーの過充電防止機能というものがあるのですが、
実は過充電防止機能ってずっと使う分にはうざいけど、逆にBeam一発くらいなら行けるんじゃないか。と。
僕の持っているバッテリーには、電源ボタンが付いていました。
これを押すと、バッテリー残量確認と共に、バッテリー供給が開始される仕組みです。
割り箸でも、クッション式のボタンでも良いので、一度物理的にポチッと押されれば電源が一時的に入るのではと。
先日温度を一定時間図っている時に、このボタンを定期的に押さないと動いてくれなくなってしまうので、非常に面倒で、結局コンセント供給に変えた覚えがあります。
でもでも、ある一定以上の消費電力が無いと、充電済みとして勝手に電源供給をOFFって仕組み。
使えるかも。。。
要は下記のフローが出来れば良いんじゃね。と。
久々のGoto文。
この赤い文字の部分をずっと回し続ければあれじゃないですかね。
もしかしたらBeam1000発くらい打てませんかね(´ω`)
名付けて「自閉式水栓システム」
温泉のシャワーとかにあるやつです。
バネの緻密な動作によって、お湯が一定時間出るやつ。
この水栓機構はとても複雑なので、新しく作るのは大変です。
だったら、このまま活用してしまおうというノリでやってみました。
Kinesis data firehoseとか水っぽいもののノリもクラウドっぽくないですか?
ちなみにLTで発表したときには、この論文調タイトルが一番ウケました。
ちょっと長いですが、連続で2回送信に成功している動画はこちら。
ノーカット、ノー編集です。
本当にしているのか分かりやすくするため、メール送信もやってみました。
WioLTE側では下記のコードで動いています。
[cpp]
#include <WioLTEforArduino.h>
#include <stdio.h>
#define INTERVAL (6000)
WioLTE Wio;
bool send_flag = false;
void setup() {
delay(200);
SerialUSB.println("");
SerialUSB.println("— START —————————————————");
SerialUSB.println("### I/O Initialize.");
Wio.Init();
SerialUSB.println("### Power supply ON.");
Wio.PowerSupplyLTE(true);
delay(1000);
SerialUSB.println("### Turn on or reset.");
if (!Wio.TurnOnOrReset()) {
SerialUSB.println("### ERROR! ###");
return;
}
SerialUSB.println("### Connecting to \"soracom.io\".");
delay(1000);
if (!Wio.Activate("soracom.io", "sora", "sora")) {
SerialUSB.println("### ERROR! ###");
return;
}
}
void loop() {
char data[100];
if (send_flag == false) {
SerialUSB.println("### Open.");
int connectId = Wio.SocketOpen("beam.soracom.io", 23080, WIOLTE_TCP);
if (connectId < 0) {
SerialUSB.println("### ERROR! ###");
goto err;
}
SerialUSB.println("### Send.");
sprintf(data, "{\"uptime\":%lu}", millis() / 1000);
SerialUSB.print("Send:");
SerialUSB.print(data);
SerialUSB.println("");
if (!Wio.SocketSend(connectId, data)) {
SerialUSB.println("### ERROR! ###");
goto err;
}
SerialUSB.println("### Receive.");
int length;
do {
length = Wio.SocketReceive(connectId, data, sizeof (data));
if (length < 0) {
SerialUSB.println("### ERROR! ###");
goto err;
}
} while (length == 0);
SerialUSB.print("Receive:");
SerialUSB.print(data);
SerialUSB.println("");
SerialUSB.println("### Close.");
send_flag = true;
SerialUSB.println("### LTE Power supply OFF.");
Wio.Deactivate(); // Deactivate a PDP context. Added at v1.1.9
Wio.TurnOff(); // Shutdown the LTE module. Added at v1.1.6
Wio.PowerSupplyLTE(false); // Turn the power supply to LTE module off
}
err:
delay(INTERVAL);
}
[/cpp]
はい。超シンプル。
beamで起動時間を送るだけのサンプルコードを流用して作りました。
最小限のコードはこちら(IOを省きました。)
※v1.1.9のライブラリを使用しています。
[cpp]
#include <WioLTEforArduino.h>
#include <stdio.h>
#define INTERVAL (6000)
WioLTE Wio;
bool send_flag = false;
void setup() {
delay(200);
Wio.Init();
Wio.PowerSupplyLTE(true);
delay(1000);
if (!Wio.TurnOnOrReset()) {
return;
}
delay(1000);
if (!Wio.Activate("soracom.io", "sora", "sora")) {
return;
}
}
void loop() {
char data[100];
if (send_flag == false) {
int connectId = Wio.SocketOpen("beam.soracom.io", 23080, WIOLTE_TCP);
if (connectId < 0) {
goto err;
}
sprintf(data, "{\"uptime\":%lu}", millis() / 1000);
if (!Wio.SocketSend(connectId, data)) {
goto err;
}
int length;
do {
length = Wio.SocketReceive(connectId, data, sizeof (data));
if (length < 0) {
goto err;
}
} while (length == 0);
send_flag = true;
Wio.Deactivate(); // Deactivate a PDP context. Added at v1.1.9
Wio.TurnOff(); // Shutdown the LTE module. Added at v1.1.6
Wio.PowerSupplyLTE(false); // Turn the power supply to LTE module off
}
err:
[/cpp]
(各種待ち時間も1000にしてみましたが、案外行けました。状況による可能性はあります。)
肝は「Wio.PowerSupplyLTE(false);」でLTEを切ります。
そして、送ったフラグを判定して再度起動するまで2度と打ちません。
これで消費電力がかなり抑えられるので、バッテリー側は
「おやっ?充電終わったか。」と判断して勝手に切ってくれます。
重要なのはほかのセンサーやLEDを使わない(もしくは)センサーもOFFにするということですかね。
GPSとかずっと動いているとうまく動作してくれないかもしれません。
はいまとめです。
今回は駆動そのものをモバイルバッテリー側に担保させる形を取りました。
おかげで前回のマグネットケーブルよりもっとシンプルな構造をとることが出来ました。
※モバイルバッテリーの過充電防止機能は様々なので製品やロットによって再現しない可能性があります。
この点はご留意下さい。
あとは、モバイルバッテリーのボタンをどのようなトリガーで押すかは実装次第ですね。
単純にボタンの上に何か貼り付けてもいいですし、前回の様に割り箸でピンポイントで押すのもよし。
床に設置しておいて、誰か通った!センサーというのも出来ますね。
また、ボタンは短時間に何回押しても、寸断されること無く最後に押してから一定時間供給し続けるので、まさしく自閉式水栓です。
なんでこんなことに気づかなかったんだろうと思うレベルです。
確かにラズパイではOSを起動しないと行けないので、そもそも電源OFF運用というのは考えづらかったのですが、
WioLTEは起動→ループというシンプルなものなので、起動自体はそこまで億劫では無いのですよね。
一つのトリガーとして考えたら、こんなに手軽に通信が出来るデバイスは画期的だと思います。
バッテリーのマイコン制御によって、WioLTEボードではもはやこれ以上削ぎ落とすことは必要ないところまで行ったと思っています。
ここまで行ったら、あとは運用面の方をガンガン詰めていって、専用のボードを作ったほうが経営面でも良いかなと思います。
オチ
物理面でも・・・
こちらの世界にずぶずぶとなりました。
ありがとうございました!
ここまでお読み頂きありがとうございます。
何かありましたらTwitterやコメントからどうぞ!