IoTデバイスをバッテリーや太陽電池などで長期間動作させるためには、IoTデバイスを低消費電力化する必要があります。IoTデバイスの消費電力を把握するために、0.1mA単位でIoTデバイスの消費電流を測定する電流モニターを作りました。
IoTデバイスの低消費電力化
IoTデバイスは、制御するマイコンの処理によって消費電流が変化します。特にWi-FiやBluetoothなどの無線通信は、比較的大きな電流を消費しますし、いくつかのセンサーは大きな電流を消費するものがあります。従って、センサーのアクセスや通信のプログラミングによってIoTデバイスの消費電力は異なってきます。
IoTデバイスを低消費電力化するためには、ある瞬間の消費電流を知るだけでなく、ある区間の消費電流の積算値を知り、それを改善していく必要があります。例えばそのデバイスが5分周期でデーターを測定し、クラウドサービスに送信しているとしたら、5分間トータルの消費電流を把握し、改善する必要があります。そのため、電流モニターもある区間の総消費電流が測れるものを作ります。
電流計モジュール INA226PRC
電流値の測定にはストロベリー・リナックス社のINA226PRCというモジュールを使いました。
このモジュールは電源ラインの中に25mΩの抵抗(シャント抵抗)を入れ、その両端の電圧をINA226という電流センサーで測ることで、電源ラインを流れる電流を測定するものです。電流測定の分解能は0.1mA、電圧の分解能は1.25mVです。
INA226はI2Cでマイコンと通信します。M5Stackとは次のように接続しました。
回路図のISENSE+とGNDの間に測定対象のバッテリーや発電デバイスをつなぎ、ISENSE-とGNDの間に測定対象のマイコンなどをつなぎます。
実装にはM5Stackの信号線をブレッドボードで扱いやすくするための拡張基板「SideBB for M5Stack」を使いました。M5Stackの拡張モジュールで、ブレッドボードが使えるので、今回の測定器のようなものがコンパクトにまとめられて便利です。
電流モニターのソフトウェア
ある区間の総消費電流を測るために、周期的に電流を測定し、メモリーに記録します。測定周期は2ミリ秒(ms)、4ms、10ms、20ms、50msから選べるようにしました。メモリーには3,000件のデーターを記録するようにしたので、測定区間は6秒(2ms x 3,000件)から150秒(50ms x 3,000件)になります。
周期的な処理は次のようにESP32 Arduinoのタイマー機能を使って実現します。samplingミリ秒ごとにタイマー割り込み処理関数 onTimer0 が呼び出されるようにします。周期処理では、t0flag という変数を0にしてタイマー割り込みを待ち、割り込み処理関数で t0flag を1にすることで待ちを解除し、samplingミリ秒ごとに周期処理がおこなわれるようにします。
volatile int t0flag; // 割り込み待ち変数 void IRAM_ATTR onTimer0() { // 割り込み処理関数 t0flag = 1; } samplingTimer = timerBegin(TIMER0, 80, true); // 1マイクロ秒のタイマーを初期設定する timerAttachInterrupt(samplingTimer, &onTimer0, true); // 割り込み処理関数を設定する timerAlarmWrite(samplingTimer, sampling * 1000, true); // samplingミリ秒のタイマー値を設定する timerAlarmEnable(samplingTimer); // タイマーを起動する while (true) { // 周期処理 t0flag = 0; while (t0flag == 0) { // タイマー割り込みを待つ delay(0); } // 周期処理本体 } timerAlarmDisable(samplingTimer); // タイマーを停止する
周期処理本体では、電流センサーモジュールINA226PRCから電流値と電圧値を読み、メモリーに記録していきます。電流値のしきい値を決め、そのしきい値を超えたら測定対象のIoTデバイスが動き出したと判断して、記録を開始するようにしています。
bool started = false; // 測定開始フラグ int indx = 0; // 記録するデーターのインデックス while (true) { t0flag = 0; while (t0flag == 0) { // タイマー割り込みを待つ delay(0); } short amp = ina226prc.readCurrentReg(); // INA226PRCから電流値を読む short volt = ina226prc.readVoltageReg(); // INA226PRCから電圧値を読む if (!started) { // 電流値がしきい値(startthreshold)未満だったら、測定を始めない if (amp * 0.1 > -(float)startthreshold && amp * 0.1 < (float)startthreshold) { continue; } started = true; // 電流値がしきい値を超えたら測定開始 } ampbuf[indx] = amp; // 電流値をメモリーに記録する voltbuf[indx] = volt; // 電圧値をメモリーに記録する if (++indx >= NSAMPLES) { // データー数がサンプル数を超えたら、周期処理を終わる break; } }
測定周期と測定開始のしきい値は、M5StackのLCDとボタンで選択できるようにしました。記録したデーターはcsvファイルとしてSDカードに書き出し、LCDにも表示するようにしています。
プログラム全体は次のようになります。
INA226PRCのドライバなどを含むプログラム全体はGithubに公開しました。
この電流モニターを使って、ESP32を搭載したESPr Developer 32とM5Stackの消費電力を測定しました。
結果はこちらをご覧ください。