組み込み開発を、実機で体系的に学びませんか?
クミタテでは、ESP32・電子回路・IoT開発を学べる オンライン教材を公開しています。無料会員向け教材も利用できます。
無料会員登録して教材を見る Googleアカウントなら簡単に登録できます
ESP32でエルチカ(LED点滅)ができるようになったので、次のステップとしてLEDのフェード機能を試してみました。 じわじわ明るくなったり暗くなったりする、あの演出です。
Arduino IDE の [ファイル] → [スケッチ例] → [ESP32] → [Analog Out] → [LEDC Fade] を開くと、フェード機能を使ったサンプルが確認できます。
この記事では、
をまとめて紹介します。
ESP32にはLEDC(LED Control)というPWM制御用のハードウェアモジュールがあります。 フェード機能もこのLEDCに含まれています。
LEDCのフェードは、
という仕組みで動作します。
私たちが設定するのは、
の3つだけ。 あとはLEDCが自動でフェード処理をしてくれます。
実際の波形を見ると、1周期の中でON時間(デューティ比)が徐々に変化しているのが分かります。
LEDCは高速・低速の2グループを持ち、それぞれに
が割り当てられています。 Arduinoのサンプルでは高速グループが使われます。
サンプルコードの流れを簡単に整理すると次の通りです。
これらを構造体にまとめて ledc_timer_config() に渡します。
これを ledc_channel_config() に渡して設定します。
ledcFadeWithInterrupt() を呼ぶとフェードがスタートし、 目標デューティ比に達すると割り込みが発生してフラグが立ちます。
ここからが本題です。
例えば、
になるはずですが、実際に測ると約5秒しかかかりません。
他の値でも同様で、
| フェードタイム設定 | 理論値(往復) | 実測値 |
|---|---|---|
| 1000ms | 2000ms | 約1600ms |
| 1500ms | 3000ms | 約1600ms(なぜか同じ) |
| 2000ms | 4000ms | 約3200ms |
どれも 約0.8秒短い という結果になりました。
フェード時間は次の式で決まります。
ここで問題なのが、
という点です。
例えば12bit分解能ならカウンター最大値は4096。 周波数5kHzなら1カウントあたり約0.2ms。
フェードタイム1000msを設定しても、 内部計算で最適なステップ間隔が1に丸められ、 結果として 1.6秒 になってしまう、というわけです。
結論として、
という仕様になっています。
ESP32のLEDCは強力ですが、内部仕様を理解しておかないと「なんで?」とハマるポイントもあります。 今回の検証が、同じように悩んでいる方の参考になれば幸いです。