煽り気味のタイトルで始めてみましたが、今回はESP32の内蔵RTCの話をしようと思います。
ESP32にはRTCが内蔵されています。
RTC timer: Allows keeping the system time during any resets and sleep modes, only the power-up reset leads to resetting the RTC timer. The frequency deviation depends on an RTC Clock Source and affects accuracy only in sleep modes, in which case the time will be measured at 6.6667 us resolution.
公式のWikiにも書いてあるとおり、スリープ中も使えるクロックです。
deepsleepの復帰をタイマーで設定するAPIなんかはこのクロックを使っています。
ただ、このクロックは、標準では内蔵RCオシレーターを使うようになっており、
実測したところ30分でも数秒以上の誤差が出ることもありました。
何時何分のデータかタイムスタンプが重要なアプリケーションや、
正確な起動時間が求められるタイマーとしてはこのままでは使うことができません。
そこで、DS3231のようなI2C RTCを接続し、スリープの復帰をGPIO割り込みにして、
RTCのINTピンを使って起こすなんてことをよくしていると思います。
しかし、実はESP32内蔵のRTC、よくRTCに使われる32.786kHzのクロックを
外部から供給して、外付けRTC並の高精度な時刻保持ができるのです。
上記リンクを少し下へスクロールすると、 RTC Clock Sourceという項目があります。
そこには
・Internal 150kHz RC oscillator (default)
・External 32kHz crystal
・External 32kHz oscillator at 32K_XN pin
・Internal 8.5MHz oscillator, divided by 256 (~33kHz)
という利用できるクロックソースのリストがあります。
それぞれ、
標準で使用されるRCオシレーター、
外付け32k水晶
XNピンへのクロック入力
内蔵8.5MHzオシレーターの分周
となっていますが、標準のRCはご存知のようにかなり精度が悪いです。
また、8.5MHzから分周するのも、周波数安定度は高いものの、
周波数が近似値なので均一にかなりずれます。絶対時間での誤差ではRCのほうがマシでした。
そこで、32kHzの水晶を外部に接続する方法を試してみました。
https://t.co/9EJqUo62JN
— じてんしゃっぷ (@jitenshap) January 5, 2021
>Optimized 32.768 KHz crystal oscillator stability, the issue was reported by client that
there is a low probability that under ECO V1 hardware, the 32.768 KHz crystal oscillator
couldn’t start properly.
ひどい話ですね。これまで流通していたESP-WROOM-32では
うまくRTC用クロックソースの水晶を発振できませんでした。
そんな矢先、秋月でもチップバージョン3のWROOM-32Eが発売されていたので
本当にそちらでは動くのか試してみました。
水晶のドライブに必要な回路はデータシートの11-12ページに書いてあります。
GPIO32, 33に並列に抵抗を入れて、あとは水晶と負荷容量をつなぐだけです。
並列の抵抗は5M~10MΩとされていたので、手持ちのある5.1Mを使いました。
なお、ハードウェア的に接続するだけで自動的に水晶が使われるわけではなく、
ビルドオプションでクロックソースを別途設定する必要があります。
Component config->ESP32-specific
RTC clock sourceでEnterを押して
External 32kHz crystalを選択
Number of attempts to repeat 32k XTAL calibrationでEnterを押して、
適当に数値を増やす
(これをしないと、発振の開始が間に合わずRCに切り替わってしまいます。)
なお、この数値を莫大な数値にすると、
発振できない場合にブートローダー内でWDT Resetが掛かりブートループになります。
うまく発振できないと、ブートローダーでこのようにエラーが出て、RCに切り替わります。
プローブを当てて、発振できているのにこの表示になる場合は、
Number of attempts to repeat 32k XTAL calibrationの数値を増やすといいと思います。
うまく発振できると、App cpu upの周りでエラーが表示されなくなります。
このように、ESP-WROOM-32Eでは外付けの水晶を使ったRTCクロックソースを
使用することができました。
この状態で実際に仕事で使ってみていますが、半日時計合わせをしなくても
1秒以内の誤差になっているため、
外付けRTCなしでも絶対時刻が重要なアプリケーションで使用できています。
ちなみに、秋月で売っているESP-WROOM-32Eは、技適マークが刻印されておらず、
シールが添付されていますが、3月のロットからは技適マークが入るようになっています。
Changes of the marking on ESP32-WROVER-E and ESP32-WROVER-IE to add new certification
identification
実際にDigiKeyで3月に購入したものについては、技適マークが入っていました。