前回の投稿でM5Stackでセンサーライトを作ってみた。
今回はをこれを省電力化してみようとの試み。
きっかけは前回作成したセンサーライトもどきを玄関に設置してみたのだが、コンセントが近くに無く、SONYのモバイルバッテリー(CP-F10L)を繋いで動かしていた。
このバッテリー、買ってから3、4年経っているので劣化しているとはいえ、10,000mAhの大容量なのでそこそこ持つものと思っていた。(2週間くらいもってくれたらなー、と期待してた)
が、蓋を開けてみれば3日と持たないではないか!
これはきっと消費電力が大きいのだろうと思い、レッツ省電力化。
まずはネットから先人の知恵を拝借するのが常であろうが、面倒くさいので、自分で調べもせず同僚に相談。
そしたら「クロック数を下げてみたら?」とのこと。
なるほどと思い下げてみた。
// 消費電力を下げるためクロック数を下げる
setCpuFrequencyMhz(10);
これで良し、と思いきやなんと、数分すると動かなくなった。
調べてみるとどうやら消費電力が少なすぎるとディープスリープに入ってしまうもよう。
https://github.com/m5stack/M5Stack/issues/34
しかたないので定期的にクロック数を上げてディープスリープに入らないように改造。改造したのが以下。
点灯していない間は30秒間隔でクロック数を上げている。
# include <M5Stack.h>
# include "timer.h"
# define WAKE_INTERVAL_MSEC 30000
# define PIR_PIN 2
bool isLedOn = false;
Timer sleepTimer;
void setup() {
M5.begin();
// 消費電力を下げるためクロック数を下げる
setCpuFrequencyMhz(10);
pinMode(PIR_PIN, INPUT);// set pir sensor pin as input
// 画面を白くすることにより照明の代わりにする
M5.Lcd.fillScreen(WHITE);
// スリープ状態にしておく
sleep();
}
void loop() {
int value = digitalRead(2);// read the pin(0: not detectd 1: detected)
if (value == 0)
{
if (isLedOn == true)
{
isLedOn = false;
// スリープ状態にしておく
sleep();
}
else
{
// スリープ状態でも定時間に一回起動する(32秒でのスタンバイ対策)
if (sleepTimer.GetElapsed() >= WAKE_INTERVAL_MSEC)
{
// クロックを上げてスタンバイ状態になってしまうのを回避する
M5.Lcd.wakeup();
setCpuFrequencyMhz(240);
delay(1000);
// クロック数を元にもどしてスリープ
setCpuFrequencyMhz(10);
sleep();
}
}
}
else
{
if (isLedOn == false)
{
isLedOn = true;
// スリープ状態を解除して点灯状態にする
wakeup();
}
}
delay(500);
}
void sleep()
{
sleepTimer.Start();
M5.Lcd.sleep();
M5.update();
}
void wakeup()
{
M5.Lcd.wakeup();
M5.Lcd.setBrightness(255);
M5.Lcd.fillScreen(WHITE);
M5.update();
}
※timer.hおよびTimerクラスは自作したもの。ただのストップウォッチ。
これでヨシ!かと思いきや1~2時間くらいでやはり動かなくなってしまう。
なぜ?と思ったが、どうやらモバイルバッテリーからの給電がストップしてたもよう。
消費電力が少ないと給電がストップしてしまうのだろうか?
省電力化しようとしてるのに省電力化したら止まるという、、、ままならない。
良い解決策も思いつかないのでとりあえず不貞寝。