フルカラーLED-PL9823のデータ転送タイミングで調べた結果をもとにESP32用のクラスライブラリを作成してみた。
Githubに自作したESP32用?のライブラリをPlatformIO用ライブラリ形式で公開したので、そちらに追加しておいた。
追加しているクラスは次の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分しか制御できないようになっている。
コメント