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の消費電力を測定しました。
結果はこちらをご覧ください。