M5Stackでできること 〜deep sleep中も変数の値を保持する

一定時間間隔でデータを採取するIoTデバイスなどを、低電力で動作させたい場合、deep sleepの活用が有効です。
deep sleepに入ると、その期間中は消費電力が抑えられ、復帰時にはスケッチのあたまから処理が行われます。

スケッチ内の変数の値も、deep sleepから復帰すると初期化されてしまいますが、復帰後も変数の値を保持する方法として「RTC_DATA_ATTR」があります。
RTC_DATA_ATTRを使うと、変数は「RTCスローメモリ」に書き込まれ、その場合はdeep sleep中もRTCスローメモリの電源がオンのままになります。これによりdeep sleepに入っても、変数の値が保持されるようです。

今回は、この「RTC_DATA_ATTR」を、簡単なスケッチで確認してみます。

まずは以下のスケッチです。

#include <M5Stack.h>

int cnt;

void setup() {
  M5.begin();
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setTextSize(4);
  M5.Lcd.fillScreen(WHITE);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print(cnt);
}

void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()) {
    cnt++;
    M5.Lcd.fillScreen(WHITE);
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.print(cnt);
  }
  if(M5.BtnC.wasPressed()) {
    esp_sleep_enable_timer_wakeup(10000000);
    esp_deep_sleep_start();
  }
}

M5Stackの電源を入れると「0」と表示されます。
ボタンAを押すと数字がカウントアップされます。
ボタンCを押すとdeep sleepに入ります。10秒たつと復帰し、その時は表示が「0」に戻ります。

次に、スケッチを以下のように変更します。
「int cnt;」の行頭に「RTC_DATA_ATTR」を付け加えただけです。

#include <M5Stack.h>

RTC_DATA_ATTR int cnt;

void setup() {
  M5.begin();
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setTextSize(4);
  M5.Lcd.fillScreen(WHITE);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print(cnt);
}

void loop() {
  M5.update();
  if(M5.BtnA.wasPressed()) {
    cnt++;
    M5.Lcd.fillScreen(WHITE);
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.print(cnt);
  }
  if(M5.BtnC.wasPressed()) {
    esp_sleep_enable_timer_wakeup(10000000);
    esp_deep_sleep_start();
  }
}

先ほどと同じように、M5Stackの電源を入れると「0」と表示され、ボタンAを押すたびに数字がカウントアップされます。
ボタンCを押すとdeep sleepに入ります。10秒たつと復帰しますが、その時もdeep sleep前の変数の値が保持されており、その値が表示されます。

ちなみに本体左横の電源ボタン(赤いボタン)を押してリセットさせると、変数の値は初期化され、「0」が表示されます。

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


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


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

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