ESP32-フルカラーLED PL9823(WS2812B)制御クラス

フルカラーLED-PL9823のデータ転送タイミングで調べた結果をもとにESP32用のクラスライブラリを作成してみた。

Githubに自作したESP32用?のライブラリをPlatformIO用ライブラリ形式で公開したので、そちらに追加しておいた。

https://github.com/take4blue/librarieseesp32/tree/master/lib/ColorLed

追加しているクラスは次の2つ。

  • ColorLedControl
  • Color2LedControl

ColorLedControl

コンストラクタで制御するLEDの数を設定しESP32のRMT機能を使ってデータを送信している。

他の人が作成しているクラスでは、テンプレートを使いLEDの数とピンの宣言をしているのが多いのだが、ここでは内部バッファなどの領域にはヒープを使うことにしたので、テンプレートを使用していない。
RMTを使っているのもあるが、通常のArduino環境のものには移植できないと思う。

特色としては転送タイミングをパラメータで設定できることと一応非同期でデータを送信可能なように内部バッファを複数持っていること。

転送タイミングの設定に関してはsetTransmissionTimeというメソッドを用意してあり、これでT0H、T0L、T1H、T1Lとリセット時間を設定できるようになっている。
T0H、T0L、T1H、T1Lは制御用チップによりタイミングが違うので、もしデフォルト(WS2812B)と異なるタイミングなのであれば、使用者が設定できるようになっている。

リセット時間に関しては、RMT用データ構築時間などにより、想定しているリセット時間より長くなってしまうことが分かった。
なので、実際のリセット時間については、ロジックアナライザ等で実測値を見て調整できるようにしてみた。


実際、3個ぐらいのLEDデータを送信した場合、送信ブロック間の間隔が100μ秒近くになったため、リセット時間を調整することで仕様書の50μ秒にまで近づけることができた。

Color2LedControl

こちらは初期段階のRMT評価用という位置づけ。

当初データの変換については、変換関数を登録しrmt_write_sampleで行おうと思っていた。
その方が変換後のデータバッファの領域を確保しなくてもいいかなと思ったから。

この機能、rmt_write_sampleを呼び出すと変換関数経由で実データをrmt_item32_t形式に変換するというものなのだが、rmt_item32_tデータはシステムで用意されているRMT共有バッファになるとのこと。

このバッファは、初期化時に領域サイズを指定可能で1ブロックでrmt_item32_t が64個分になり、最大8ブロック指定できるようになっている。

上のような書き方だったため、1ブロックしか確保していなくても、rmt_write_sampleで大量のデータを設定してもブロック内のデータと送信データの管理をしてくれるのかなと思っていた。
例えば、フルカラーLEDでは1LEDのRGBデータを24ビットでしているのだが、これを3LED分rmt_write_sampleで設定したら、変換関数内が2回呼ばれ、24*2ビット分のデータと24*1ビット分のデータがきちんと送られるのかと思っていた。

実際には3LED分のデータを設定した場合、24*2ビット分のデータしか送付できなかった。
つまり変換関数は1度しか呼び出されず、送信できなかった1個分のLED情報は無視された形になってしまったのだった。

そういった経緯もありヒープを使ったColorLedControlを別途作ることになったのだ。

Color2LedControlはRMT用共有バッファを1ブロック分しか使っていないので2LED分しか制御できないようになっている。

コメント

タイトルとURLをコピーしました