Skip to main content

XIAO ESP32S3 Sense スリープモード

ここでは、これらの低消費電力スリープモードの使用を実演するためのいくつかの簡単な例を紹介します。すべてのESP32ボードは多機能であり、この文脈で使用している開発ボードはXIAO ESP32S3 Senseです。

ハードウェア概要

Seeed Studio XIAO ESP32S3 Sense

Deep-Sleep

概要

Deep-Sleepモードでは、ESP32はCPU、RAMの大部分、およびAPB_CLKでクロックされるすべてのデジタル周辺機器の電源を切ります。電源が供給されたままの部品は以下のみです:

  • RTCコントローラー
  • ULPコプロセッサー
  • RTC FASTメモリ
  • RTC SLOWメモリ

ウェイクアップ方法

  • **タイマーウェイクアップ:**ESP32はタイマーを設定することで、指定された時間後に自動的にウェイクアップできます。

  • **タッチパッド割り込みウェイクアップ:**タッチパッドの動作によってデバイスをウェイクアップでき、ユーザーインタラクションが必要なアプリケーションに適しています。

  • **外部ウェイクアップ:**ESP32は外部信号(ボタン押下など)によってウェイクアップでき、低消費電力アプリケーションに最適です。

  • **ULPコプロセッサーアクティビティウェイクアップ:**ULPコプロセッサーは独立して動作し、特定の条件を監視してメインCPUをウェイクアップして電力を節約できます。

  • **GPIOウェイクアップ:**GPIOピンの状態変化(HighまたはLow)によってデバイスをウェイクアップでき、様々なセンサーや周辺機器に柔軟性を提供します。

以下に、XIAO ESP32 S3 SenseでDeepSleepモードを使用する3つの簡単な例を示します。

コード実装


#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 5

RTC_DATA_ATTR int bootCount = 0;

void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;

wakeup_reason = esp_sleep_get_wakeup_cause();

switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}

void setup() {
Serial.begin(115200);
delay(1000);


++bootCount;
Serial.println("Boot number: " + String(bootCount));


print_wakeup_reason();


esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

Serial.println("Going to sleep now");
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
}

void loop() {

}

詳細な注記

#define uS_TO_S_FACTOR 1000000ULL 
  • マイクロ秒を秒に変換するマクロを定義します。1000000ULLはマイクロ秒を秒に変換するために使用される係数です。
#define TIME_TO_SLEEP  5     
  • ESP32がスリープする時間を設定するマクロを定義します。この場合は5秒です。
RTC_DATA_ATTR int bootCount = 0;
  • 整数変数 bootCountRTC_DATA_ATTR 属性で宣言します。これにより、ディープスリープ中でもその値を保持できます。
void print_wakeup_reason() {
  • ESP32が起動した理由を出力するprint_wakeup_reason()という名前の関数を定義します。
esp_sleep_wakeup_cause_t wakeup_reason;
  • ウェイクアップイベントの原因を格納するために、esp_sleep_wakeup_cause_t 型の変数 wakeup_reason を宣言します。
wakeup_reason = esp_sleep_get_wakeup_cause();
  • 関数 esp_sleep_get_wakeup_cause() を呼び出してウェイクアップの理由を取得し、wakeup_reason 変数に代入します。
  switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
  • ESP_SLEEP_WAKEUP_EXT0 : このウェイクアップ理由は、RTC(リアルタイムクロック)I/O用に設定されたGPIOピンで検出された外部信号により、ESP32がウェイクアップしたことを示します。これは通常、ボタンやセンサーがトリガーされたときのスリープからのウェイクアップに使用されます。
  • ESP_SLEEP_WAKEUP_EXT1 : これは、RTCコントローラーによって管理されるGPIOピンの外部信号によってウェイクアップが引き起こされたことを示します。EXT0とは異なり、EXT1は複数のピンを処理でき、指定されたピンのいずれかが状態を変更したとき(例:ローまたはハイになる)にウェイクアップできます。
  • ESP_SLEEP_WAKEUP_TIMER : このウェイクアップ理由は、ESP32が事前定義されたタイマー期間後にウェイクアップしたことを意味します。これは、ユーザーの操作を必要とせずに定期的なタスクを実行する必要があるアプリケーションに有用です。
  • ESP_SLEEP_WAKEUP_TOUCHPAD : これは、タッチパッドイベントによりESP32がウェイクアップしたことを示します。ウェイクアップ用に設定されたタッチパッドがタッチを検出すると、デバイスをスリープモードから復帰させることができます。
  • ESP_SLEEP_WAKEUP_ULP : このウェイクアップ理由は、ULP(超低消費電力)プログラムによってウェイクアップがトリガーされたことを意味します。ULPはメインCPUがディープスリープ中でも動作でき、特定の条件が満たされたときにESP32をウェイクアップできるため、最小限のバッテリー消費で低消費電力動作が可能になります。
++bootCount;
  • デバイスが再起動するたびに起動回数をインクリメントして出力します。
print_wakeup_reason();
  • ESP32のウェイクアップ理由を出力します。
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

Serial.println("Going to sleep now");
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
  • esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);指定した時間後にESP32をウェイクアップするタイマーを有効にします。
  • Serial.flush();スリープに入る前にすべてのシリアルデータが送信されることを確認します。
  • esp_deep_sleep_start();ESP32をディープスリープモードに移行させます。
tip

ディープスリープモードに入った後にプログラムを再書き込みするには、ブートボタンを押し続けながらリセットボタンを押してESP32を再起動してください。

結果表示

ライトスリープ

概要

ライトスリープモードは、ESP32のもう一つの低消費電力モードで、デバイスが素早い応答時間を維持しながらエネルギーを節約することを可能にします。このモードでは、CPUコアは停止しますが、RAMと一部の周辺機器は電源が供給されたままで、特定のイベントに応答してデバイスが素早く起動できます。

ライトスリープは、低消費電力が必要でありながらWiFiやBluetoothへの接続を維持する必要があるアプリケーションに最適です。無線通信モジュールをアクティブな状態に保つことができるためです。

ウェイクアップ方法

  • タイマーウェイクアップ: デバイスは指定された時間後に起動でき、定期的なタスクの実行が可能になります。
  • 外部割り込みウェイクアップ: ESP32は、ボタンの押下やその他のハードウェア割り込みなどの外部信号によって起動できます。
  • ネットワークアクティビティウェイクアップ: デバイスは受信ネットワークパケットに応答して起動でき、常にアクティブ状態でなくても効率的な通信が可能になります。
  • GPIOウェイクアップ: 特定のGPIOピンを設定して、状態変化や信号などのイベントが発生したときにライトスリープからデバイスを起動させることができます。

コード実装

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

const int sleepTime = 10000;
const int ledPin = LED_BUILTIN;

void ledTask(void *pvParameters) {
digitalWrite(ledPin, HIGH);
Serial.println("LED is ON");
vTaskDelay(pdMS_TO_TICKS(1000));
digitalWrite(ledPin, LOW);
Serial.println("LED is OFF");

vTaskDelete(NULL);
}

void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
Serial.println("Setup complete. Going to sleep...");
}

void loop() {
esp_sleep_enable_timer_wakeup(sleepTime * 1000);
Serial.println("Going to sleep now...");
esp_light_sleep_start();

xTaskCreate(ledTask, "LED Task", 2048, NULL, 1, NULL);

delay(1000);
}

詳細な注記

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
  • FreeRTOSライブラリをインクルード
const int sleepTime = 10000; 
const int ledPin = LED_BUILTIN;
  • スリープ時間を10秒に設定
  • 内蔵LEDピンを使用
void ledTask(void *pvParameters): 
  • LEDの状態を制御するFreeRTOSタスクを定義します。
digitalWrite(ledPin, HIGH); 
Serial.println("LED is ON");
vTaskDelay(pdMS_TO_TICKS(1000));
digitalWrite(ledPin, LOW);
Serial.println("LED is OFF");
vTaskDelete(NULL);
  • vTaskDelay(pdMS_TO_TICKS(1000));Keep the LED on for 1 second
  • vTaskDelete(NULL);Delete the current task
esp_sleep_enable_timer_wakeup(sleepTime * 1000);
Serial.println("Going to sleep now...");
esp_light_sleep_start();
xTaskCreate(ledTask, "LED Task", 2048, NULL, 1, NULL);
delay(1000);
  • esp_sleep_enable_timer_wakeup(sleepTime * 1000);ウェイクアップ用のタイマーを設定
  • esp_light_sleep_start(); ライトスリープモードに入る
  • xTaskCreate(ledTask, "LED Task", 2048, NULL, 1, NULL);LED制御タスクを作成

Results Show

Modem-Sleep

Introduction

Modem Sleepモードは、ESP32のもう一つの重要な低消費電力モードで、Deep Sleepモードとは異なります。Modem Sleepモードは主にESP32のワイヤレス通信モジュールに最適化されています。

このモードでは、ESP32のWiFi/Bluetoothモジュールがスリープ状態に入り、CPUコアはアクティブなままです。これにより、ESP32は一定レベルのワイヤレス接続を維持しながら、消費電力を大幅に削減できます。

Wake-up Methods

  • Timer Wake-up

  • External Interrupt Wake-up

  • Task Wake-up

  • Network Activity Wake-up

Code Realization

#include "WiFi.h"

void setup() {
Serial.begin(115200);
Serial.println("Connecting to WiFi...");

WiFi.begin("****", "****");

while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
Serial.println("Connected to WiFi!");

WiFi.setSleep(true);
Serial.println("Modem-Sleep enabled.");
}

void loop() {

Serial.println("Running...");

delay(5000);

WiFi.setSleep(false);
Serial.println("Modem-Sleep disabled. WiFi is active.");

if (WiFi.status() == WL_CONNECTED) {
Serial.println("Still connected to WiFi.");
} else {
Serial.println("WiFi disconnected.");
}

delay(5000);
WiFi.setSleep(true);
Serial.println("Modem-Sleep enabled.");
}

詳細な注記

#include "WiFi.h"
  • WiFi機能を有効にするためにWiFiライブラリをインクルードします。
Serial.println("Connecting to WiFi...");
  • WiFiへの接続が開始されることを示すメッセージを出力します。
WiFi.begin("****", "****");
  • 指定されたWiFiネットワークへの接続を開始します。
    while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
Serial.println("Connected to WiFi!");
  • Loop until successfully connected to WiFi.
WiFi.setSleep(true);
  • モデムスリープモードを有効にして電力を節約します。
WiFi.setSleep(false);
  • モデムスリープモードを無効にしてWiFiをアクティブにします。
if (WiFi.status() == WL_CONNECTED) {
  • WiFiの状態を確認します。
WiFi.setSleep(true);
  • モデムスリープモードを再度有効にします。

結果表示

スリープ機能アプリケーション

上記のシンプルな例を踏まえて、さらに一歩進んで、これらのスリープ機能をESP32 S3 Senseセンサーで使用してみましょう。

ソフトウェア準備

この記事を始める前に、XIAO ESP32S3 Senseのすべてのハードウェア機能をまだ活用していない場合は、いくつかのソフトウェアインストール準備を完了していることを確認してください。

ここでは3つの機能の紹介があり、以下のリンクを通じてより詳しい情報を見つけることができます:

  • マイクロフォンの使用:XIAO ESP32S3 Senseのマイクロフォンを使用して周囲の音レベルを捉え、音声を録音する方法を学びます。

  • MicroSD:データストレージにMicroSDカードを使用する方法を理解し、プロジェクトでファイルを保存および取得できることを確認します。

  • カメラの使用:XIAO ESP32S3 Senseのカメラモジュールを使用して写真を撮影し、動画を録画する方法をマスターします。

コード実装

#include "esp_camera.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"

#define CAMERA_MODEL_XIAO_ESP32S3

#include "camera_pins.h"

unsigned long lastCaptureTime = 0;
int imageCount = 1;
bool camera_sign = false;
bool sd_sign = false;


void photo_save(const char * fileName) {
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Failed to get camera frame buffer");
return;
}
writeFile(SD, fileName, fb->buf, fb->len);

esp_camera_fb_return(fb);

Serial.println("Photo saved to file");
}

void writeFile(fs::FS &fs, const char * path, uint8_t * data, size_t len){
Serial.printf("Writing file: %s\r\n", path);

File file = fs.open(path, FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing");
return;
}
if (file.write(data, len) == len) {
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}

void setup() {
Serial.begin(115200);
while (!Serial);

camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.frame_size = FRAMESIZE_UXGA;
config.pixel_format = PIXFORMAT_JPEG;
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 12;
config.fb_count = 1;

esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}

camera_sign = true;

if (!SD.begin(21)) {
Serial.println("Card Mount Failed");
return;
}

uint8_t cardType = SD.cardType();

if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}

Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}

sd_sign = true;

Serial.println("Photos will begin shortly, please be ready.");
}

void loop() {
if (camera_sign && sd_sign) {
unsigned long now = millis();

if ((now - lastCaptureTime) >= 60000) {
char filename[32];
sprintf(filename, "/image%d.jpg", imageCount);
photo_save(filename);
Serial.printf("Saved picture: %s\r\n", filename);
Serial.println("Entering deep sleep for 10 seconds...");

esp_sleep_enable_timer_wakeup(10000000);
esp_deep_sleep_start();

}
}
}

詳細な説明

このコードは、ESP32カメラモジュールに基づく画像キャプチャシステムを実装しており、60秒ごとに自動的に写真を撮影してSDカードに保存することができます。void setup()関数では、カメラとSDカードを初期化してデバイスの状態を確認し、void loop()関数では、カメラが写真を撮影できるかどうかをチェックし、条件が満たされた場合はphoto_save()関数を呼び出して画像を保存し、保存後は省電力のために10秒間のディープスリープ状態に入ります。

tip

これらのコードは直接使用することはできません。カメラに関するヘッダーファイルを追加する必要があります。上記のXIAO ESP32 S3に関する例を確認してください。

まとめ

なぜDeep Sleepモードを使用するのか

機能を損なうことなく電力節約を最大化し、デバイスのバッテリー寿命を延ばすためです。 適用シナリオ:リモートセンサーノード、ウェアラブルデバイス、その他の低電力IoTデバイスなど、バッテリー寿命が重要なアプリケーション。ウェイクアップ時間は比較的遅いですが、このトレードオフは価値があります。

なぜModem Sleepモードを使用するのか

ネットワーク接続を維持しながら、無線通信モジュールの電力消費を最適化するためです。 適用シナリオ:ネットワーク接続を維持する必要があるが、低電力も必要とするアプリケーション、例えば間欠的に動作するIoTデバイス。Modem Sleepは、高速なウェイクアップ応答を提供しながら、無線モジュールの電力消費を大幅に削減できます。

総括

これら3つのスリープモードは、開発者に異なる電力/性能のトレードオフオプションを提供し、アプリケーションの具体的な要件に基づいて柔軟に選択できます。バッテリー寿命要件があるデバイスには、Deep Sleepモードが良い選択です。ネットワーク接続を維持する必要があるIoTデバイスには、Modem Sleepモードが最適な選択です。

技術サポートと製品ディスカッション

私たちの製品をお選びいただき、ありがとうございます!私たちの製品での体験ができるだけスムーズになるよう、さまざまなサポートを提供しています。異なる好みやニーズに対応するため、複数のコミュニケーションチャンネルを提供しています。

Loading Comments...