見出し画像

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モジュールを接続している。

画像1

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していることが分かる。

スクリーンショット 2020-05-13 15.51.30

さいごに

どこかに同じようなことをやっていそうで、でも見つけられなかったのでnoteにしてみた。中身はたいしたことないけど、こんなことでも思った通り動くと楽しい。

Wake upの時間の精度が気にならないシステムであれば、タイマーでwake upさせれば簡単だが、精度が必要とされるなら、こういう使い方もできる。

P.S.

microUSBケーブルは、データ通信に対応しているのか確認してから購入すべき。

ESP32を接続しても、Macbookがシリアルポートを認識しないので、しばらく悩んでしまった。運用中は良いけど、書き込み、デバッグはデータ通信対応でないと。。。

よろしければ、サポートをお願いします。 より多くの方に役立つnoteを書けるよう頑張ります!!