ステークカジノ レベルアップボーナス <,ただ、ここからは電池屋さんの専門分野。使用環境や自己放電特性、

M5Stackでステークカジノ レベルアップボーナスモジュール(IFS-M01)の消費電力を測定する

2020.08.05

LPWAは、低消費電力だと言いながら、そこそこいいお値段のするステークカジノ レベルアップボーナス計を手に入れないと消費電力量を測ることができないと思われているかと思います。しかし、数千円レベルのステークカジノ レベルアップボーナス電圧計モジュールとM5Stackなどにより簡単に測れる方法があります。
ここでは、M5Stack Basicと電流電圧計モジュール(INA226PRC)を使って、ステークカジノ レベルアップボーナス無線モジュール(Innovation Farm社のIFS-M01)のステークカジノ レベルアップボーナスを計測する方法をご紹介します。

IFS-M01ベースの開発キットは、8月4日にステークカジノ レベルアップボーナスnovation Farm社からリリースされました。
詳細はこちら

用意するもの

身の回りにないかもしれませんが、下記を用意してください。

ステークカジノ レベルアップボーナスosensor ES Devkit

ステークカジノ レベルアップボーナスosensor ES Devkitは、ST社のサブGHz帯トランシーバS2-LPベースのステークカジノ レベルアップボーナスモジュールIFS-M01の開発キットです。
ボタンと接点x2を搭載したモデルですので、とりあえずステークカジノ レベルアップボーナスを試してみたいという方は乾電池だけ用意してもらえればボタンや接点入力をトリガにステークカジノ レベルアップボーナスメッセージを送信できます。また、エンジニア向けに、STのSDKでも開発できるようになっています。

電力計モジュール[ステークカジノ レベルアップボーナスA226PRC]

消費電流値の測定は、ストロベリーリナックスのステークカジノ レベルアップボーナスA226PRCというI2Cデジタル電流・電圧・電力計モジュールを使用します。
ステークカジノ レベルアップボーナスA226PRCの仕様は下記の通りです。

項目仕様
電源電圧 3~5V
インターフェース I2C
測定電圧範囲 0~36V
測定ステークカジノ レベルアップボーナス範囲 -3.2768~+3.2767A
分解能 ステークカジノ レベルアップボーナス:0.1mA, 電圧:1.25mV

81Wまでの測定が可能という事で、組み込みセンサ系には適しているのではないかと思います。(待機ステークカジノ レベルアップボーナスまでは無理ですが。。。)
下の写真のようにモジュール基板に加え、端子台x2、2種類のコネクタが付属していますので、ご自身の環境に合わせたコネクタを選択し、はんだ付けしてください。
また、I2Cのアドレスを設定するために、下右図のように、アドレスを0b1000000xとする場合は、Gのところを、はんだでグランドを落としておく必要があるようです。

img-20200805-technical-05.png

INA226PRCとステークカジノ レベルアップボーナスモジュール、M5Stackとの配線

今回は、ステークカジノ レベルアップボーナスモジュールの消費電流を計測したいので、3本のICクリップとショートカット用のリード線を使用し、下図のように配線します。

img-20200805-technical-06.png

ステークカジノ レベルアップボーナスA226モジュールの配線は、グランド電位が共通となるハイサイド接続と電源の電位が共通となるローサイド接続があるようですが、推奨されているハイサイド接続で組みました。
ちなみに、端子側は下の写真のようにしています。

img-20200805-technical-07.png

完成した配線は下の写真のようになります。(既にM5Stack上にステークカジノ レベルアップボーナス値グラフが表示されてしまっていますが、気にしないでください)

img-20200805-technical-08.jpeg

ステークカジノ レベルアップボーナス・電圧測定プログラム

M5Stackとステークカジノ レベルアップボーナスA226RPCとは、I2Cで通信し電流値、電圧値を計測していくことになりますので、Wireライブラリ(Wire.hをインクルード)を使えば可能です。しかも、ステークカジノ レベルアップボーナスA226から電流電圧値をミリ秒単位でサンプリングし、画面表示するプログラムは、Takehiko ShimojimaさんがGitHubにアップされているので、これを流用させていただくことにしました。
こちらです。
私は、SDカードを持っていなかったので、SDカードの書き込み部分をコメントアウトし、Serialで結果を送信するように変えています。サンプルスケッチは下記の通りになりますので、先ほどのGitHubリポジトリから、その他必要なファイルはダウンロードしお使いください。

ステークカジノ レベルアップボーナスA226PRC.ステークカジノ レベルアップボーナスo.c
#include  
#include  
#include "INA226PRC.h" 
#include "menu.h" 

INA226PRC ina226prc;

void beep(int freq, int duration, uint8_t volume);

#define TIMER0 0 
hw_timer_t * samplingTimer = NULL;

#define NSAMPLES 3000 // 4ms x 3000 = 12秒 
short ampbuf[NSAMPLES];
short voltbuf[NSAMPLES];

int sampling  = 4;  // サンプリング間隔(ミリ秒)
int startthreshold = 3;  // 記録を開始する電流値(ミリA)

Menu menu;

volatile int t0flag;

void IRAM_ATTR onTimer0() {
    t0flag = 1;
}

int selectitem(int *candi, int items, int val, char *tail) {
    int focused;

    for (int i = 0; i < items; i++) {
        if (candi[i] == val) {
            focused = i;
        }
    }
    M5.Lcd.fillScreen(BLACK);
    menu.setMenu("up", "OK", "down");
    bool first = true;
    while (true) {
        bool modified = false;
        M5.update();
        if (M5.BtnA.wasPressed()) {
            focused--;
            modified = true;
        }
        if (M5.BtnC.wasPressed()) {
            focused++;
            modified = true;
        }
        if (M5.BtnB.wasPressed()) {
            M5.Lcd.fillScreen(BLACK);
            return candi[focused];
        }
        if (first || modified) {
            first = false;
            beep(1000, 100, 2);
            for (int i = 0; i < items; i++) {
                M5.Lcd.setCursor(100, 40 + i * 20);
                int16_t textcolor = ((focused % items) == i) ? BLACK : WHITE;
                int16_t backcolor = ((focused % items) == i) ? WHITE : BLACK;
                M5.Lcd.setTextColor(textcolor, backcolor);
                M5.Lcd.printf(" %d ", candi[i]);
                M5.Lcd.setTextColor(WHITE, BLACK);
                M5.Lcd.print(tail);
            }
        }
    }
}

void config() {
    int focused = 2;
    const int nItems = 3;
    int thresholds[] = {2, 3, 5, 10, 20};
    int samplings[] = {2, 4, 10, 20, 50};
    bool first = true;
    while (true) {
        bool modified = false;
        M5.update();
        if (M5.BtnA.wasPressed()) {
            focused--;  // upボタン
            modified = true;
        }
        if (M5.BtnC.wasPressed()) {
            focused++;  // downボタン
            modified = true;
        }
        if (M5.BtnB.wasPressed()) {  // changeボタン
            modified = true;
            switch (focused % nItems) {
            case 0:
                startthreshold = selectitem(thresholds, sizeof(thresholds) / sizeof(int), startthreshold, "mA");
                break;
            case 1:
                sampling = selectitem(samplings, sizeof(samplings) / sizeof(int), sampling, "ms");
                break;
            case 2:
            default:
                return;
            }
        }
        if (first || modified) {  // loop中で文字を書くとスピーカーからノイズが出るようだ
            first = false;
            beep(1000, 100, 2);
            menu.setMenu("up", "GO", "down");
            M5.Lcd.setCursor(20, 40);
            M5.Lcd.print("Start threshold: ");
            if ((focused % nItems) == 0) M5.Lcd.setTextColor(BLACK, WHITE);
            M5.Lcd.printf(" %d ", startthreshold);
            if ((focused % nItems) == 0) M5.Lcd.setTextColor(WHITE, BLACK);
            M5.Lcd.print("mA");

            M5.Lcd.setCursor(20, 100);
            M5.Lcd.print("Sampling period: ");
            if ((focused % nItems) == 1) M5.Lcd.setTextColor(BLACK, WHITE);
            M5.Lcd.printf(" %d ", sampling);
            if ((focused % nItems) == 1) M5.Lcd.setTextColor(WHITE, BLACK);
            M5.Lcd.print("ms");

            M5.Lcd.setCursor(20, 160);
            if ((focused % nItems) == 2) M5.Lcd.setTextColor(BLACK, WHITE);
            M5.Lcd.print(" DONE ");
            if ((focused % nItems) == 2) M5.Lcd.setTextColor(WHITE, BLACK);
        }
    }
}

#define X0 10 
#define Y0 220 

void drawData(short maxamp) {
    M5.Lcd.fillRect(0, 0, 320, 220, BLACK);
    maxamp = ((maxamp / 100) + 1) * 100;
    for (int i = 0; i < 299; i++) {
        int y0 = map(ampbuf[i * 10], 0, maxamp, Y0, 0);
        int y1 = map(ampbuf[(i + 1) * 10], 0, maxamp, Y0, 0);
        M5.Lcd.drawLine(i + X0, y0, i + 1 + X0, y1, WHITE);
        Serial.printf("%d, %d, %d, %d\r\n", ampbuf[i * 10], ampbuf[(i + 1) * 10], y0, y1);
    }
    M5.Lcd.drawLine(X0, Y0, 310, Y0, WHITE);
    M5.Lcd.drawLine(X0, 0, X0, Y0, WHITE);
}

void setup() {
    Serial.begin(115200);
    M5.begin();
    Wire.begin();
    ina226prc.begin();

    Serial.print("Manufacture ID: ");
    Serial.println(ina226prc.readId(), HEX);

    M5.Lcd.setTextSize(2);
    config();

    M5.Lcd.fillScreen(BLACK);
    beep(1000, 100, 2);
    menu.setMenu("start", "", "");
    M5.Lcd.setCursor(20, 100);
    M5.Lcd.print("Press A button");
    M5.Lcd.setCursor(40, 120);
    M5.Lcd.print("to start sampling");

    while (true) {
        M5.update();
        if (M5.BtnA.wasPressed()) break;
    }

    M5.Lcd.fillScreen(BLACK);
    beep(2000, 100, 2);

    samplingTimer = timerBegin(TIMER0, 80, true);  // 1マイクロ秒のタイマーを初期設定する
    timerAttachInterrupt(samplingTimer, &onTimer0, true);  // 割り込み処理関数を設定する
    timerAlarmWrite(samplingTimer, sampling * 1000, true);  // samplingミリ秒のタイマー値を設定する

    timerAlarmEnable(samplingTimer);  // タイマーを起動する

    bool started = false;
    int indx = 0;
    short maxamp = 0;

    M5.Lcd.fillRect(50, 100, 200, 10, BLACK);
    while (true) {
        t0flag = 0;
        while (t0flag == 0) {  // タイマー割り込みを待つ
            delay(0);
        }
        short amp = ina226prc.readCurrentReg();
        short volt = ina226prc.readVoltageReg();

        if (!started) {
            // 電流値がしきい値(startthreshold)未満だったら、測定を始めない
            if (amp * 0.1 > -(float)startthreshold && amp * 0.1 < (float)startthreshold) {
                continue;
            }
            started = true;  // 電流値がしきい値を超えたら測定開始
        }
        ampbuf[indx] = amp;  // 電流値をメモリーに記録する
        voltbuf[indx] = volt;  // 電圧値をメモリーに記録する
        maxamp = max(amp, maxamp);
        M5.Lcd.setCursor(100, 100);
        M5.Lcd.print(indx * 100 / NSAMPLES); M5.Lcd.print(" %");
        if (++indx >= NSAMPLES) {  // データー数がサンプル数を超えたら、周期処理を終わる
            break;
        }
    }
    timerAlarmDisable(samplingTimer);  // タイマーを停止する

    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setTextステークカジノ レベルアップボーナスze(2);
    M5.Lcd.setCursor(20, 100);
    beep(2000, 400, 2);

    Serial.println("time, current(mA), volt(mV)");
    for (int i = 0; i < NSAMPLES; i++) {
      Serial.printf("%d, %.2f, %.2f\r\n", sampling * i, ampbuf[i] * 0.1, voltbuf[i] * 1.25);
    }

    menu.setMenu("view", "", "");
    M5.Lcd.setCursor(40, 160);
    M5.Lcd.print("Press A button");
    M5.Lcd.setCursor(40, 180);
    M5.Lcd.print("to view data");

    while (true) {
        M5.update();
        if (M5.BtnA.wasPressed()) {
            drawData(maxamp);
        }
    }
}

void loop()
{
}

ステークカジノ レベルアップボーナスを計算する

ステークカジノ レベルアップボーナスでデータ送信した時の消費電流の時間変化の結果が下図のようにでました。

img-20200805-technical-09.png

上の消費ステークカジノ レベルアップボーナスのグラフを見ると、3回のメッセージが送信されていることが見れます。メッセージ送信時の消費ステークカジノ レベルアップボーナスは約20mA(あれ、公称値より若干低めになったかな?)、Wi-Fiのデータ送信時消費ステークカジノ レベルアップボーナスが100~200mAと言われていることからもLPWAが低消費電力であるということが結果からわかると思います。

さらに、ステークカジノ レベルアップボーナスと電池について考察してみます。
通信1回(3メッセージ)あたりの消費ステークカジノ レベルアップボーナス量は、1メッセージの送信時間を2.08[s]とすると
20[mA] x 2.08[s] ÷ 3600[s/h] = 0.011556[mAh]
仮に、1時間に1回通信すると仮定すると、
0.11556[mAh] x 24[h/day] ÷ 1[h] = 0.277333[mAh/day]
が1日あたりの消費ステークカジノ レベルアップボーナスになります。
何もセンサーを載せない(例えばボタン通知だけの)デバイスを想定した場合、待機ステークカジノ レベルアップボーナスを1μAとすると
1[μA] x 3600[s/h] ÷ 3600[s/h] × 24[h/day] = 0.024[mAh/day]
となり、1日あたりの消費ステークカジノ レベルアップボーナス計は0.277333 + 0.024 ≒ 0.3[mAh/day]となります。
もし、2年間バッテリー運用したい場合、0.3[mAh/day] x 365[day] * 2[years] ≒ 220[mAh]の容量を持ったバッテリーを準備する必要があります。
ただ、ここからは電池屋さんの専門分野。使用環境や自己放電特性、セーフティーマージン等を加味し最適な電池を選択することになります。

いかがでしょうか?
改めて、LPWA(ステークカジノ レベルアップボーナス)が低消費電力であるということを感じ取ってもらえたと同時に、この組み合わせで、お手元にお持ちの端末やモジュールの消費電力を簡単に測れるようになると思います。
是非、お試しください。

著者情報

研究部責任者 日比学

京セラコミュニケーションシステム株式会社(KCCS)の経営企画部門で新規事業・研究開発に従事。
ステークカジノ レベルアップボーナスネットワークの更なる普及にむけて、IoT、LPWA(ステークカジノ レベルアップボーナス)関連の情報を発信しています。

【Twitter】https://twitter.com/ghibi

ステークカジノ レベルアップボーナス