RTCを使ってESP32をDeep SleepからWake upさせる
はじめに
1ヶ月ほど前、ESP32のDeep SleepからのWake upを調査していた。
ESP32にはESP8266同様、タイマーを設定してwake upする方法もある。この場合、ESP8266では、GPIO16ピンとRSTピンを接続する必要があるが、ESP32の場合にはそのような接続の必要はなくなっている。
また、ESP8266ではタイマーの精度が悪く、5分後のwake upを設定しても、実際には4分40〜50秒くらいでwake upしてくるが、ESP32では数秒早くwake upする程度に精度が良くなっていることが確認できた。
さらに、自宅にDS3231を搭載したRTCモジュールがあったので、これを使って外部割り込みで正確にESP32をDeep Sleepからwake upできないか、と思い調査をした。
ESP32のDeep Sleep
下記のサイトにESP32のDeep Sleepについて、まとめられているのでこちらを参考にして欲しい。
ESP32は外部割り込みによりDeep Sleepを解除して、Wake upさせることができる。今回はこの外部割り込みによりwake upさせる。
DS3231のAlarm
設定した時間になると、DS3231はAlarmを発生させ、このAlarmを外部割り込みとして、Deep SleepしているESP32をwake upさせる。
DS3231のAlarmの実装については、下記を参考にし、同じライブラリーを使用して実装することにした。
また、DS3231にはAlarm1とAlarm2というアラームがあるが、Alarm1は秒単位、Alarm2は分単位のAlarm設定が可能だ。
接続
下記のように、ESP32とRTCモジュールを接続している。
DS3231でAlarmが発生すると、SQWがHigh→Lowに変化し、GPIO33ピンへ外部割り込みとなり、この変化をトリガーにESP32のDeep Sleepが解除されwake upする。
ソースコード
下記にソースコードを示す。詳細については説明しないが、ここではAlarm2を使い、×時5分、10分、15分・・・と分指定でDS3231にAlarmを発生させ、ESP32をwake upさせるコードとなっている。
#include <Wire.h>
#include <RtcDS3231.h>
#define __DEBUG__
#ifdef __DEBUG__
#define DPrint(a) Serial.print(a)
#define DPrintln(a) Serial.println(a)
#define DPrintf(a, ...) Serial.printf(a, __VA_ARGS__)
#else
#define DPrint(a)
#define DPrintln(a)
#define DPrintf(a, ...)
#endif
//
// DS3231設定
//
RtcDS3231<TwoWire> Rtc(Wire);
#define INTERRUPT_PIN GPIO_NUM_33
void setup() {
#ifdef __DEBUG__
Serial.begin(9600);
#endif
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
// RTC時刻取得
Rtc.Begin();
RtcDateTime now = Rtc.GetDateTime();
DPrintf("\n%02d-%02d-%02d %02d:%02d:%02d\n",
now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second());
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmTwo);
DS3231AlarmTwo alarm2(0, 0, (((now.Minute() + 5) / 5) * 5 % 60), DS3231AlarmTwoControl_MinutesMatch);
Rtc.SetAlarmTwo(alarm2);
Rtc.LatchAlarmsTriggeredFlags();
DPrintln("Initialized");
deepSleep();
}
void loop() {
}
// Deep Sleep
void deepSleep()
{
esp_sleep_enable_ext0_wakeup(INTERRUPT_PIN, LOW);
esp_deep_sleep_start();
delay(1000);
}
実行結果
下記にシリアル出力を示す。5分毎にRTCのAlarmを割り込みとして、ESP32がwake upしていることが分かる。
さいごに
どこかに同じようなことをやっていそうで、でも見つけられなかったのでnoteにしてみた。中身はたいしたことないけど、こんなことでも思った通り動くと楽しい。
Wake upの時間の精度が気にならないシステムであれば、タイマーでwake upさせれば簡単だが、精度が必要とされるなら、こういう使い方もできる。
P.S.
microUSBケーブルは、データ通信に対応しているのか確認してから購入すべき。
ESP32を接続しても、Macbookがシリアルポートを認識しないので、しばらく悩んでしまった。運用中は良いけど、書き込み、デバッグはデータ通信対応でないと。。。