ESP32 の ULP を正確な間隔で動作させる方法

組み込み
スポンサーリンク

ESP32 の ULP を定期的に実行する際の Tips を紹介します.

スポンサーリンク

課題

ULP は RTC_SLOW_CLK に基づいて動作しますが,デフォルトでは内部で生成された 150kHz をクロックソースとして使用しています.一方,この 150kHz は温度によって周期が大きく変動するという困った性質を持っています.

そのため,下記のようなコードで,SENSE_INTERVAL 秒毎に ULP プログラムを動かそうとしてもうまくいきません.

なぜなら,rtc_clk_slow_freq_get_hz の実装は次のように固定値になっているためです.

解決方法

ESP-IDF の components/soc/esp32/include/soc/rtc.h には次の関数が用意されているのでこれを使って解決することができます.

rtc_clk_cal
クロックの周期を測定する関数
rtc_time_us_to_slowclk
クロックの周期に基づいて,指定された時間をクロック数に換算する関数

これらを組み合わせると,SENSE_INTERVAL 秒毎に ULP プログラムを動かすための設定は次のようにかけます.

CLOCK_MEASURE はクロックの周期を算出するためにサンプリングするサイクル数です.大きいほど精度はあがりますが,その分時間がかかります.ESP-IDF のデフォルトが 1024 なのでここではそれに合わせています.

Deep Sleep に入る前に毎回上記を実行することで,秒オーダーでの誤差がほぼない状態で定期的に ULP を動かすことができます.

補足

ESP-IDF は起動時に一度だけ上記と同じ方法で RTC_SLOW_CLK の周期を取得しており,その値は esp_clk_slowclk_cal_get で得ることができます.ただし,前述のとおり内部クロックは温度依存性が大きいので,起動時に算出されたこの値は長期に動作させる用途には適さないと思われます.

コメント