ESP8266をバッテリー駆動で長期間動かす時に欠かせないのがdeep sleepです。n秒deepSleepした時にESP8266が実際に何秒眠るのかを調べました。

実験

n秒deepSleepし、deepSleep直前からdeepSleep復帰までの実際の経過時間(実経過時間)をRealTimeClock(RTC)モジュールで測定し、指示した時間と実経過時間を比較しました。RTCモジュールは秋月電子の「RX-8025NB使用I2C接続リアルタイムクロック(RTC)モジュール」を使いました。月差13秒という十分な精度を持ったクロックモジュールです。実験はdeepSleepに指示する時間を10秒から450秒まで10秒ずつ変化させ、指示時間と実際の時間と差分との関係を調べました。

結果

80MHzで動作するESP8266で測定した結果です。

deepsleep20161217_01

差分は(実経過時間 – deepSleepに指示した時間)なので、値がマイナスということは例えば300秒指定してdeepSleepしても実際には294秒で起きてくるということです。つまりESP8266はdeepSleepの際、実際の時間よりも2%ちょっと速く時間をカウントすることになります。

個体差

手元にあった三つのESP8266で実験しましたが、ご覧の通りほぼ同じ結果が得られました。

deepsleep20161217_02deepsleep20161217_03

補正式

deepSleep直前の実時刻をtbeforeとします。n秒deepSleepして、復帰直後の実時刻tafterは

tafter = tbefore + n * 0.977

で計算できます。

1日に1回程度、SNTPなどで外部から実時刻を取得し、あとはdeepSleepで周期的にセンサーを測定するようなアプリケーションでは、この補正式を使うことで、RTCモジュールを使わなくても比較的正確にdeepSleep後の実時刻を得られるようになります。

背景

ESP8266で長期間バッテリー駆動するIoTセンサー端末を作ることを考えます。例えば5分ごとに温度、湿度を測定し、クラウドに送信するような端末です。測定と測定の間は消費電力を低く抑えるためにdeepSleepさせます。

単純に作ると、n秒deepSleepし、deepSleepから復帰したらセンサー値を測定し、Wi-Fiに接続してデーターをクラウドに送信するというプログラムになります。しかし、ESP8266はWi-Fiアクセスポイントに接続する際に大きな電力を消費することが分かっているので、更に消費電力を下げるためには、毎回データーをクラウドに送信せず、何回かに1回まとめてデーターを送信する方法が有利になります。

IoTクラウドサービス「Ambient」は、通常一組のデーター(例えば{“d1”: 21.3, “d2”: 52.1}といったデーター)を送るとサーバー側で受信時刻を記録しますが、何回か分のデーターをまとめて送信するbulk_send()という機能があり、このときは次のようにデーターとその生成時刻を組みにして送ることが出来ます。

    {
        “writeKey” : “ライトキー”,
        “data” : [
            {“created” : 数値, “time” : 1, “d1” : “値”, “d2” : “値”, ...},
            {“created” : 数値, “time” : 1, “d1” : “値”, “d2” : “値”, ...},
            ...
            {“created” : 数値, “time” : 1, “d1” : “値”, “d2” : “値”, ...}
        ]
    }

ESP8266はdeepSleepから覚めるときにリセットがかかるため、deepSleepに入る前の情報を忘れてしまいます。唯一deepSleepの間もデーターを保持できるのはRTCメモリーで、ユーザーが使えるエリアが512バイトあります。このRTCメモリーに何回か分のデーターを保持し、まとめて送ればいいのですが、生成時刻はどうすればいいでしょう?

deepSleepから立ち上がったら毎回SNTPでネットから取得するのでは、毎回Wi-Fiに接続することになり消費電力が下げられません。そこで、2016年8月に作った「環境モニター」ではRealTimeClock(RTC)モジュールを使い、1日に1回SNTPで現在時刻を取得したらRTCモジュールにセットし、あとはセンサーを読むタイミングでRTCモジュールから現在時刻を読んでデーターの生成時刻にしていました。

今回の実験で、deepSleepする直前の時刻とdeepSleep時間をRTCメモリーに書いておき、deepSleep復帰後にRTCメモリーのデーターから計算で現在時刻を得られるようになったので、RTCモジュールを使わなくてすむようになりました。

次はこの結果を利用してRTCモジュールを使わない環境モニター3号機を作ります。