Investigated ESP32 current consumption when operating BLE (Bluetooth LE).
先週は FPGA 週間でしたが、今週は久々に無線関連の評価をやってみます。具体的には ESP32 による Bluetooth LE(BLE)です。
以前、Nordic Semiconductor 社の nRF51 を評価したことがあります。こちらは、メーカー製の評価ボードにコイン電池が付いてくるぐらい、同社は nRF51 の低消費電力に自信がある訳です。一方で、最近流行りの Espressif ESP32 は、Wi-Fi が使える安価なマイコンということで有名ですが、実は BLE もサポートしており、以前から気になっていました。
ESP32 ではありませんが、同社の ESP8266 に関しては一度、無謀にもコイン電池での Wi-Fi 動作を評価したことがあります。その時は MicroPython 環境を使ったのですが、MicroPython ではパワーセーブのやり方が難しいと感じました。そのときの印象から、実は ESP32 にはあまり期待していなかったのですが、使い方によっては ESP32 でも十分にバッテリー動作の BLE 利用が出来そうなことが分かったので、簡単にまとめてみたいと思います。
BLE クライアントについて
今回は評価用のクライアントアプリとして、Android 用の BLE Scanner というものを利用しました。
今回はビーコン動作にて
まずは最初にビーコン動作の評価です。Arduino 環境に ESP32 対応ライブラリの 1.0.4版をインストールし、サンプルプログラムの BLE_iBeacon をコピーしてビルドしました。今回はコードをいじらず、そのまま利用します。また、評価には、Adafruit 社の HUZZAH32 – ESP32 Feather Board を利用しました。
サンプルプログラムの動作概要ですが、BLE の advertising を始めたあと 0.1秒でそれをオフにし、ESP32 を 10秒間の deel sleep モードに移行させます。deep sleep では CPU が完全に停止してしまうので動作を復旧することはできず、10秒が経過すると、プログラムがリスタートされ、Arduino の setup() からやり直しになります。
なにはともあれ、消費電流のプロファイルを見てみることにしましょう。本ボードでは外部から電源を取ることがあまり考慮されていませんが、VBUS 端子に実験用電源の 5.0V を入力することにしました。また、(私は電流プローブ(電流センサ?)を持っていないので)電流測定用の 0.1オーム抵抗をシリーズに繋ぎ、オシロで抵抗の電圧降下を測定することにしました。こんな結果です。
ノイズが多くて見づらいですね、すみません。ここから正確な電流を読み取るのは難しいので、読み取るのは時間情報だけとし、実際の消費電流はデータシート(3.2版)を参照することにしましょう。
まず最初に、オシロ波形上の一番電流が少ない部分は deep sleep 状態です。データシートから見ますと、消費電流は 0.1 〜 0.15 mA と想定されます。(今回は、RTC をオフにしていないので。)
次に、deep sleep から起きて 0.3秒程度後の電流に着目します。ここはおそらく、modem sleep 状態に該当するのだと思われます。Arduino 環境の ESP32 では通常 240 MHz モードで動いているそうですから、ここの電流が 30〜68 mA の部分と想定されます。(オシロ画面で言うと、チャネルを 5 mV スケールに設定しているので、一マス 50 mA に該当し、この想定は合っていそうです。)
続いて、さらに電流が増加する 0.6秒程度のところを見ましょう。ここはおそらく、Active (RF working) で、Receive BT/BLE というところに該当すると思われます。データシートによると 95 〜 100 mA ですね。オシロの画面でも、だいたい合っていそうに見えます。
最後が、実際に電波を送信していると思われる部分です。オシロ画面上で、再度 deep sleep に落ちる前にツンツンとヒゲが 3本立っている部分ですね。データシートによると、0 dBm の出力において 130 mA だそうです。これも概ね合っていそうに見えます。
それでは、このサンプルプログラム BLE_iBeacon で、1サイクルに要する消費電力量を見積もってみましょう。なお、今回は 5V の実験電源を使いましたが、最終的には 3V のバッテリ(CR2032)を使うものと想定します。
上記のオシロ画面を動作時間毎にまとめてみますと(読取りは目測です)、
動作モード | 電流(データシート平均値 [ミリA]) | 時間 [秒] |
---|---|---|
Modem-sleep | 50 | 0.46 |
Receive BT/BLE | 100 | 0.60 |
Transmit BT/BLE (0 dBm) | 130 | 0.04 |
Deep-sleep | 0.13 | 10.00 – 上記全部 |
といった感じになります。(今回のサンプルプログラムでは deep sleep が 10秒間なので、サイクルタイムは 10秒になりませんが、ここでは、サイクルタイムを 10秒に設定できたと仮定します。)
これを時間軸で平滑化すると、平均消費電流は 8.9 mA となります。
さて、コイン電池 CR2032 の容量ですが、こちらの資料によると概ね 230mAh ということです。ただし、その容量は 0.19mA 連続放電時の値なので、8.9mA 放電ではもう少し容量が少なくなる(半分程度)と仮定してみます。結論としては、CR2032 で 10秒間隔のビーコン(connection なしの advertising のみ)動作ですと、10時間(半日)程度は動作するのではないか、と思われます。
ただし一点注意が必要なのは、CR2032 で(仮にパルス的であっても)130mA の放電に耐えられるかどうか、ということがあります。これは前回の ESP8266 Wi-Fi 実験のときと同様に大容量のキャパシタを併用すれば良いのですが、装置が大型になってしまうという懸念が残ります。
こちらに、80mA までのパルス放電を実験したレポートがあります。また、Energizer 社のこちらのアプリケーションマニュアルを見ると、パルス放電であっても、だいたい 30 mA 程度くらいまでしか想定していないことが分かります。
一つの期待として(実験しないといけませんが)、ESP32 の動作クロックを 80 MHz に落とすことが考えられます。これで、消費電流を 10 〜 30mA 程度下げられるかも知れません。
もしこれが 10秒間隔でなく、必要なときだけ送信すれば良いとした場合、つまり外部トリガで起きれば良いとした場合、deep sleep モードでの消費電流を 0.13 mA と仮定して、(さらにこの場合は CR2032 の想定している使い方に近いと思われますので 230mAh の容量があるとしますと、)おおむね 2ヶ月以上は動作を続けられそうです。
しかし、前回の nRF51822 の結果と比較してみますと、確かにこちらは Arduino 環境でのプログラミングであり最適化ができている訳ではありあませんが、だいぶ負けているなあ、といった印象は拭えません。(nRF51822 のときの計算は今回と異なりますが、CR2025(2032 ではない)で数年は持ちそうという推算でした。)
次回への宿題
なお、別の注意点として、もし仮にビーコン(advertising)の間隔を deep sleep でなく外部トリガにした場合には、トリガがかかってから実際に advertising で送信されるまでの遅延(lag)が気になります。今回の deep sleep の場合は、オシロの波形から考えると 1秒程度を要しているように見えます。次回は、deep sleep による消費電流の最小化を諦め(犠牲にし)、かつ light sleep モードが活用できたとして、外部トリガからの遅延、またそのばらつきをどれくらいに抑えられるかどうか、評価してみたいと思います。
さらにもう一つの宿題
今回は計算しませんでしたが、ESP32 Arduino の BLE サンプルプログラムには、BLE_notify というものがあります。これは、ビーコン動作とは異なり、BLE クライアント(たとえばスマートフォン)とのコネクションが発生します。その場合は、ビーコン動作よりもずっと消費電流が増えることになります。
オシロの波形だけはキャプチャしたので下に示します。下記の波形で、上側がコネクション待ち状態であり、下側がコネクションが確立した状態です。なお、こちらの波形では時間スケールが違うので御注意ください。
コネクション確立時の消費電流は平均して、概ね 100 〜 150 mA と言ったところでしょうか。必要なときだけコネクションを確立するようにすれば、もう少し消費電流を落とせそうにも思われます。
今日はここまで。