🚀 究極の電池長持ち術:ESP32 Deep Sleepと複合ウェイクアップで実現する数年駆動IoTデバイス

【DIY】ホームセーフティ実践

はじめに:なぜIoTデバイスにDeep Sleepが欠かせないのか

IoTデバイスを電池で長期間運用する際、最大の敵は電力消費です。ESP32のような強力なマイクロコントローラも、Wi-FiやCPUをフル稼働させると、わずか数時間で電池が尽きてしまいます。

ここで鍵となるのが、ESP32が持つ Deep Sleep(ディープスリープ) 機能です。これは、システムをほとんど停止させ、消費電流を劇的に下げる究極の省電力モードです。

この記事では、Deep Sleepの基本的な仕組みから、私たちが以前構築したワイヤレスドアセンサー(続・改良版!ESP32 ESP-NOW ワイヤレスドアセンサーガイド)を例に、複数の復帰条件(タイマーと外部割り込み)を組み合わせる、より実用的な複合ウェイクアップの実装方法を徹底解説します。


1. Deep Sleepの基礎知識と消費電力の劇的削減

🔋 Active Modeとの消費電流比較

Deep Sleepの最大の魅力は、その驚異的な低消費電力です。

モード消費電流の目安実行中の機能特徴
Active Mode80mA ∼ 200mACPU、Wi-Fi、Bluetoothなど全機能処理速度が速いが、電池消費が激しい。
Deep Sleep Mode5μA ∼ 20μARTC(リアルタイムクロック)とRTCメモリのみ超低消費電力。CPU、メインメモリ、無線機能は停止。

Deep Sleep中は、消費電流が数千分の1以下になるため、センサーのデータを測定・送信する数秒間だけActive Modeで動作し、残りの時間はDeep Sleepで待機するという間欠動作パターンが、電池駆動IoTデバイスの基本設計となります。

📌 Deep Sleepの真のコスト

Deep Sleep中の消費電流は、ESP32本体の 5μA 前後に加え、 電源回路の自己消費電流(静止電流 Iq​) が加算されます。

  • 理想的な設計:静止(自己)消費電流(IQ​)が 1 マイクロアンペア (μA) 以下の昇降圧 ICを選定すれば、合計待機電流を10 マイクロアンペア (μA) 以下に抑え、数年単位の長寿命が実現します。
  • 汎用ICの場合:静止(自己)消費電流(IQ​)が 30 マイクロアンペア (μA) 以下の昇降圧 ICを使用すると、合計待機電流は 35μA 程度となり、電池寿命は約2年程度に短縮されます。

Deep Sleepの恩恵を最大限に受けるには、電源ICの選定が最も重要であることを忘れてはいけません。


2. Deep Sleepからの復帰方法:複合ウェイクアップが実用的

IoTデバイスは、定期的なレポート突発的なイベント検知の両方が求められます。これを両立させるには、複数のウェイクアップ機能を組み合わせる複合ウェイクアップが必要です。

💻 複合ウェイクアップの構成要素

私たちが構築したドアセンサー子機を例に、以下の3つの条件でESP32を起動させます。

  1. タイマー・ウェイクアップ (Timer Wakeup): 定期的な電池残量レポートや、機器の生存確認に利用。(例: 1時間ごと)
  2. 外部割り込みウェイクアップ 1 (EXT1): ドアが開閉した際の緊急性の高いイベント検知に利用。(例: 磁気センサー)
  3. 外部割り込みウェイクアップ 2 (EXT1): ユーザーによる手動データ送信やリセットに利用。(例: タクトスイッチ)

📝 複合ウェイクアップのプログラム実装(子機側)

ここでは、特に重要なDeep Sleep関連の関数とその設定について解説します。

C++

// --- 定数設定 ---
#define DOOR_SENSOR_PIN 27   // 外部割り込み 1 (EXT1)
#define MANUAL_BUTTON_PIN 13 // 外部割り込み 2 (EXT1)
#define ONE_HOUR_US 3600000000ULL // 1時間 (3600秒)

// ... 中略:メッセージ構造体、Wi-Fi/ESP-NOW設定 ...

void setup() {
    Serial.begin(115200);
    
    // 1. 起動時にウェイクアップの原因を確認
    esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
    
    // 復帰理由に応じて動作を分岐
    if (wakeup_reason == ESP_SLEEP_WAKEUP_TIMER) {
        // 定期レポート処理(電池残量チェックなど)
        Serial.println("Wakeup by Timer. Scheduled report.");
        myData.reason = 1; 
    } else if (wakeup_reason == ESP_SLEEP_WAKEUP_EXT1) {
        // EXT1でウェイクアップした場合、どのピンがトリガーか確認
        uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();

        if (wakeup_pin_mask & (1ULL << DOOR_SENSOR_PIN)) {
            Serial.println(" -> Door sensor triggered!");
            myData.reason = 2; // ドア開閉イベント送信
        } else if (wakeup_pin_mask & (1ULL << MANUAL_BUTTON_PIN)) {
            Serial.println(" -> Manual button pressed!");
            myData.reason = 3; // 手動レポート送信
        }
    } else {
        // 初回起動処理(ADC初期化、ESP-NOW初期設定など)
        Serial.println("Initial boot or other wake up source.");
        myData.reason = 0; 
    }
    
    // ... ESP-NOWデータ送信処理 ...

    // 2. 次のスリープ設定
    Serial.println("Setting up Deep Sleep...");
    
    //  A. タイマー・ウェイクアップを設定 (1時間ごと) 
    esp_sleep_enable_timer_wakeup(ONE_HOUR_US);

    //  B. 複数の外部割り込み(EXT1)を設定 
    uint64_t wakeup_mask = 0;
    // 監視したいピンのビットマスクを作成し結合
    wakeup_mask |= (1ULL << DOOR_SENSOR_PIN);
    wakeup_mask |= (1ULL << MANUAL_BUTTON_PIN);

    // EXT1ウェイクアップをLOWレベルでトリガーするように設定
    // 複数のピンのいずれか一つがトリガーされると復帰 (ESP_EXT1_WAKEUP_ALL_LOW)
    esp_sleep_enable_ext1_wakeup(wakeup_mask, ESP_EXT1_WAKEUP_ALL_LOW);
    
    // 3. Deep Sleepへ移行
    Serial.println("Entering Deep Sleep now.");
    esp_deep_sleep_start();
}

void loop() {
    // Deep Sleepを使用するため、このループは実行されません
}

3. 実装のポイント:複合ウェイクアップを成功させる技術

3-1. 複数の外部割り込みは「EXT1」で

ESP32では、複数のGPIOピンの状態変化を監視して復帰させる機能として EXT1 ウェイクアップを使用します。

  • マスク生成: (1ULL << PIN_NUMBER) は、GPIOピンの番号に対応するビットフラグを生成する重要なC言語のテクニックです。
  • トリガーレベル: ESP_EXT1_WAKEUP_ALL_LOW は、マスクで指定されたいずれかのピンがLOW(通常はGNDに接続)になったときに復帰を意味します。ドアセンサーやボタンは、押されたときにGNDに接続される回路構成が一般的です。

3-2. 復帰原因の明確な特定

esp_sleep_get_wakeup_cause() 関数をsetup()の最初で実行することで、起動がタイマーによるものか、外部イベント(EXT1)によるものかを区別できます。さらにEXT1で起動した場合は、esp_sleep_get_ext1_wakeup_status() を使ってどのピンがトリガーだったかまで特定し、親機への送信データにその理由(myData.reason)を含めることで、親機側で適切な処理を実行できます。

3-3. RTCメモリの活用(データ保持)

Deep Sleepに入ると、メインのSRAMメモリの内容は消去され、変数の値はリセットされます。しかし、RTCメモリ(数KB)に保存されたデータはDeep Sleep中も保持されます。

  • 使用例: 再起動回数のカウント、前回の送信時刻、特定のセンサーのベースライン値など、スリープをまたいで保持したい一時的なデータの保存に利用します。
  • 宣言: RTC_DATA_ATTR キーワードを付けて変数を宣言します。C++RTC_DATA_ATTR int bootCount = 0;

4. まとめ:Deep Sleepこそ電池駆動IoTの生命線

Deep Sleepは、単に消費電力を抑えるだけでなく、間欠動作を通じて電池駆動IoTの設計思想そのものを決定づける機能です。

私たちが構築したワイヤレスドアセンサーのように、 「定期的な生存報告(タイマー)」「突発的な異常検知(EXT1)」 を複合的に組み合わせることで、機器の信頼性と実用性は飛躍的に向上します。

あなたのESP32プロジェクトでDeep Sleepと複合ウェイクアップを駆使し、電池交換から解放される快適なIoTライフを実現してください!

タイトルとURLをコピーしました