M5StickCでできること 〜Wi-Fi接続時以外のCPU動作周波数を落とす

以前、M5StickCの消費電流値を調べました(記事は こちら)。
M5StickCの消費電流値は、通常動作時に80mA程度、ディープスリープ時に3mA程度という結果になりました。


一定期間毎に何らかのデータを採取してWebサーバに送信するIoTデバイスをつくる場合、一定時間毎に「通常動作」させ、その他の時間は「ディープスリープ」させるのが普通だと思います。これにより、大部分の時間は消費電流値を3mA程度に抑えることができます。
例えば「温度」など、一定時間毎にデータを採取すれば良いのであれば、この方法で問題ありません。

ただし、データをWebサーバに送信するのは一定時間毎で良いが、データの採取自体は常時行いたい場合(例えば、常時加速度データを測定し、その最大値と最小値を一定時間毎にWebサーバに送信する場合)は、ディープスリープさせることができません。

このように、常時M5StickCを動作させておきたい場合、低電力化のためにはCPUの動作周波数を落とすのが有効です。
一方、Wi-Fi通信を行いたい場合は、CPUの動作周波数は80MHz以上でなければならないという制約もあります。

そのため、

  • 通常はCPUの動作周波数を最低(10MHz)に落とし、データ採取を行う。
  • 一定時間毎にCPUの動作周波数を上げ、Wi-Fi接続を行い、データをWebサーバに送信する。
  • データ送信が完了したら、CPUの動作周波数を最低(10MHz)に落とす。

というような使い方ができないか?と考えました。
これであれば、その他のM5StickC低電力化ノウハウもあわせ、Wi-Fi接続している期間以外は30mA程度以下で動作させることができます。
ディープスリープには遠く及びませんが、それでも何も対策しない場合に比べると、バッテリーの持ちをよくすることができそうです。

早速、以下のスケッチをつくって試してみました。
M5StickC内蔵の加速度センサで、常時加速度データを採取し、ボタンを押すたびに採取データの最大値、最小値をAmbientに送信するものです。
通常は、CPUの動作周波数は10MHzで動作しています。
ボタンを押すと、動作周波数を240MHzに上げ、Wi-Fiに接続してAmbientにデータを送信、送信が完了したらWi-Fiを切断し、動作周波数を10MHzに戻します。

CPU動作周波数以外の低電力化ノウハウとして「LCD画面の輝度を下げる」「5V出力端子用DCDCをOFFにする」ことも行っています。

#include <M5StickC.h>
#include "Ambient.h"

WiFiClient client;
Ambient ambient;

const char*  ssid      = "XXXXXXXX";
const char*  password  = "XXXXXXXX";
unsigned int channelId = XXXXX;
const char*  writeKey  = "XXXXXXXX";
float        accX, accY, accZ;
float        maxX      = -99.9;
float        minX      = 99.9;

void setup() {
  M5.begin();
  M5.Axp.begin(false, false, false, false, true); // 5V出力端子用DCDCをOFFに
  setCpuFrequencyMhz(10);                         // 動作周波数を落とす
  M5.Axp.ScreenBreath(8);                         // LDCの輝度を下げる
  M5.Lcd.setRotation(3);
  M5.Imu.Init();
}

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  if(maxX < accX) {
    maxX = accX;
    M5.Lcd.setCursor(0, 0, 2);
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.printf("[X-MAX] %5.2f\n[X-MIN] %5.2f\n", maxX, minX);
  }
  if(minX > accX) {
    minX = accX;
    M5.Lcd.setCursor(0, 0, 2);
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.printf("[X-MAX] %5.2f\n[X-MIN] %5.2f\n", maxX, minX);
  }
  if(M5.BtnA.wasPressed()) sendData();
}

void sendData() {
  setCpuFrequencyMhz(240);
  M5.Lcd.setCursor(0, 0, 2);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.println("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    M5.Lcd.print(".");
  }
  M5.Lcd.println("WiFi CONNECTED");

  ambient.begin(channelId, writeKey, &client);
  ambient.set(1, maxX);
  ambient.set(2, minX);
  ambient.send();
  maxX = -99.9;
  minX = 99.9;
  M5.Lcd.println("DATA SEND");

  WiFi.disconnect(true);
  M5.Lcd.println("WiFi DISCONNECTED");
  setCpuFrequencyMhz(10);
}

以下のように、モバイルバッテリーとM5StickCの間にテスタをつなぎ、消費電流値を測定しました。

通常は概ね30mA程度、ボタンを押すと一瞬だけ100mA以上に増加し、また30mA程度に戻ることが確認できました。
また、データがAmbientに問題なく送信できていることも確認できました。

低電力化の効果は限定的ではありますが、必要な時以外はWi-Fi接続を切断し、消費電流値を低減させることが可能であることが確認できました。


なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。