/* * an experiment of WS2812B, with LPC810 * by uratan! 2014.10.29 * revised 2016.11.16 */
始まりは
WS2812B
を 3.3V ロジックで駆動できた(?)こと、マンガ
ハルロックで
米粒AVR を知ったこと、
それから…
・ WS2812B の駆動タイミングの限界調査
・ WS2812B の消費電流調査
・ テストベンチ by LPC810
・ .....
・ VIH 問題にけりをつけたい… [2016.11.06]
WS2812B の駆動信号のタイミングは、データシートを読む限りは 「うまいシステム構成なのはわかるが 実際には どうするの???」な 仕様に見えます。
つまり UART を 2.5Mbps で使って…とか、SPI で SCK=20MHz をベースに…、とか 内蔵周辺回路を なんとか応用できないものか考えましたが、今ひとつ しっくり来ません。
(VDD が 3.5V〜 とか、5V で使って VIH = 0.7 x VDD = 3.5V な点も今ひとつ…だし)
1bit 1bit ソフトで駆動するしかないか…、というところで web で情報を探ったところ、こちらのページ 「 秋月でWS2812B買ってしまったので……」 が なかなかいい観点を突いている。
分からんことはモノに訊け! というわけで、私も 実際の chip を 調査してみました。(ただし n=1)
以下、背景・青がパルスの幅に関して、背景・赤が パルス間のインターバルに関しての取得波形です。 (TAB に並べて切り替えながら見ると比較しやすいかも)
波形がたくさんあるのでアレですが、要は以下の通りです。つまりデイジーチェーンの先頭を きちんと駆動できれば、 その後は間違いようがない (というか こちらの制御下にない) ということになります。
- 432nsec までのパルスは '0' として判別される。 (132nsec のパルスでも '0')
- 536nsec 以上のパルスは '1' として判別される。
- DOUT 出力は判別された論理に従って新規のパルスが出力される。
- その DOUT 出力においては、T0H=330nsec、T1H=660nsec である。
- インターバル 6.7usec 程度を境に Treset として判別され、 中継処理が中断される。
(しかしながら これは誤点灯になります)
(デイジーチェーンはハード構成が簡便ですが、 途中の chip が壊れると その後は道連れとも)
VDD=5V ですが DIN を 3.3V 駆動してまして、こちらも とりあえずは 問題とはならなそう…。(?)
(2段目以降は 5V に整形されるのは上と同じ)
そしてここで、整形された DOUT 出力が 333nsec/666nsec 相当なのですから、 初段の駆動も 333nsec/666nsec で全く十分なのではないのか… !?
次に、WS2812B の消費電流の調査結果を。
調査対象は adafruit の これ→ NeoPixel 1/4 60 Ring
輪っかにして 60個つなぎました。電流はテスターで測定。
個体によって 数mA 程度の差はありますが、 指定値に対するリニアリティは高そうです。
power consumption by 60x WS2812B condition parameter consumption current (VDD=5V) supplement G R B no-lighting GRB = 0x00_00_00 x60 53.0mA (4.85V) (range: 200mA) lighting
only 1 LEDG | R | B = 0x10 x1 53.3mA 53.4mA 53.3mA G | R | B = 0x20 x1 54.2mA 54.3mA 54.3mA G | R | B = 0x30 x1 55.2mA 55.4mA 55.3mA G | R | B = 0x40 x1 56.2mA 56.4mA 56.4mA G | R | B = 0x60 x1 58.3mA 58.6mA 58.4mA G | R | B = 0x80 x1 60.3mA 60.7mA 60.5mA G | R | B = 0xC0 x1 64.3mA 65.0mA 64.7mA G | R | B = 0xFF x1 68.3mA 69.1mA 68.8mA GRB = 0x40_40_40 x1 62.8mA GRB = 0x80_80_80 x1 74.7mA GRB = 0xC0_C0_C0 x1 86.4mA GRB = 0xFF_FF_FF x1 97.6mA (4.67V) lighting 0 LED GRB = 0x00_00_00 x60 0.05A (5.03V) (range: 10A) 1 LED GRB = 0xFF_FF_FF x1 0.10A 2 LEDs GRB = 0xFF_FF_FF x2 0.15A 3 LEDs GRB = 0xFF_FF_FF x3 0.20A 4 LEDs GRB = 0xFF_FF_FF x4 0.25A 6 LEDs GRB = 0xFF_FF_FF x6 0.35A 8 LEDs GRB = 0xFF_FF_FF x8 0.44A 10 LEDs GRB = 0xFF_FF_FF x10 0.53A 20 LEDs GRB = 0xFF_FF_FF x20 0.95A (4.71V)
しかし 5V 駆動だと 1 LED あたり最大で 約50mA だから、60個だと… 3A !?
(いや実際、0x40〜0xff までは要らないです、 もう照明のレベル…)
以上 WS2812B の評価に使用した環境は、8pin DIP マイコンの LPC810 を 使って構築しました。
circuit diagram: ws2812B-14.png ... 余計なものは野望のためのもの
firmware program: wsmon-021.zip (00README.txt) ... uart ベースで会話的に使います
上のタイミング調査より WS2812B の駆動は SPI を SCK=3MHz で使い、 以下のようにパルスを発生しています。 (SCK は使用しません)LPC810 の SPI 回路はフレーム長を 1〜16bit まで可変できるので 15bit/frame として使用し、この 15bit で上図のごとく 計 5bit 分の NZR データを生成します。
-->| |<-- 3MHz/333nsec --+ +--+ +--+ +--+ +--+ +--+ +--+ (SCK:) | | | | | | | | | | | | | +--+ +--+ +--+ +--+ +--+ +--+ +-- +-----+ +-----------+ +-- MOSI: | | '0' | | | -+ +-----------+ '1' +-----+
ですので 1 chip あたり 24bit の輝度データは 5bit ずつ 5回に分けて転送します。
パルス間の時間はマージンが大きいので、25bit 目を 0 とすることで 1 chip あたり きっかり 5回にあわせます。これ波形を見るときに 切れ目がわかっていい感じです。こんな感じ↓
駆動波形の生成にハードウェア (SPI) を使用することのメリットは以下の通りです。
- CPU の速度設定等によらず一定の駆動波形が得られる。
(CPU clock やコンパイラの影響を受けないようにできます)- CPU の負荷を ある程度減らせる。
(通常データの追加は 5usec 間隔で良く、FIFO のない LPC810 でも ダブル)
(バッファになっているので データのセットは 最大 10usec まで許容されます)
(パルス間が空いてもいいなら さらに +6.7usec)
- CPU の占有度を ある程度減らせる。
(波形生成処理を最優先・割り込み禁止で行う必要がなくなります。
(24bit×60個で 1.5msec 以上かかるし!)
(また 追加タイミング取得に割り込みも使用でき自由度が上がります)
以上、あくまで実験的なアプローチであり、いかなる条件においても 動作を保証する、というものではありません。↓↓↓
※ 今日気がついたこと [2014.11.1]
3.3V の LPC1830 / LPC810 でも駆動できるじゃん! と意気揚々だったのですが、ホントにギリギリだったみたいです。 5V 3A のアダプターを用意して別系の装置で駆動してみたらダメでした。
要因の逆類推としては、以下のような状況の模様…
と言うわけでそれでは、 わざと駆動信号配線を長くするというインチキをしてます。
- 容量 3A の電源がその容量のために各種の抵抗分を考慮してか 出力電圧が 5.2V ほどと高めで、 VIH もそれに伴って上がった。 (ベンチでは 約 5.0V)
- ベンチ基板を通して LED に電源供給する「電源→回路→LED」の形から、 「電源→LED→回路」の形に変えたため、電圧降下順や配線抵抗などが いっそう不利な条件になった。
- DIN への駆動信号の配線が短くなり、リンギングが少々小さくなって、 リンギングで VIH を越えるというモードがなくなった。 (一度越えれば 後はヒステリシスで…なのかな)
次はちゃんとレベルコンバータ入れようね…
これが それ
奥歯に挟まった小骨のようなコレ、再検証してみました。(2年ぶりか)
リンギングをどう変化させて実験すべきか悩みましたが、 上記現象のとおり まずは線路の長短を変え、 さらにダンピング抵抗を挿入して その大小を可変しデータを取りました。 またオシロのプローブを付けることでの回路への影響をかんがみ、 波形観測あり・なしでの点灯・制御の様子も確認しました。
まずは点灯・制御の様子を。 (問題の 5V 3A のアダプター(出力 5.2V)を電源に使っています)
(GLUE81X / LPC810+=2 が気になる人は こちらへ)
「○ OK」がちゃんと制御・駆動され点灯する、です。 これは (おそらく) リンギングが大きいということになります。 リンギングが抑えられていれば VIH を越えられなくて点灯・駆動できていない すなわち「× NG」となります。
以上、線路が長い もしくは オシロのプローブをクリップすることで、 リンギングが大きくなりやすい(であろう)傾向が見えます。
線路・短 線路・長 ダンピング抵抗 オシロなし オシロあり オシロなし オシロあり (1) none × NG ○ OK ○ OK ○ OK (2) 10Ω × NG ○ OK ○ OK ○ OK (3) 100Ω × NG × NG × NG ○ OK (4) 330Ω × NG × NG × NG × NG
次に波形の比較を。これ もちろん「オシロあり」の場合に限ります。
先の考察、「線路が長い」と「リンギングが大きくなりやすい」 のは間違っていないように思われます。
ringing on DIN signal damping resister driven by a short wire driven by a long wire (1) none ○ OK
○ OK
(2) 10Ω ○ OK
○ OK
(3) 100Ω × NG
○ OK
(4) 330Ω × NG
× NG
ここで気になるのは、立ち上がりのリンギングで VIH を越えるのはいいとして、 立下り時のマイナス電圧へのリンギングも対称的に変化します。 これが絶対定格を越えると まずいはまずい ので、 やはり人にお勧めするわけにはいかんですね…。(Y田先生は正しかった)
- * - * - * -
続いて WS2812B を LPC810 (3.3V) で駆動する手法の考察を。
実は 当時 アプローチとして色々試して、個人的に 「単純 open-drain + pull-up ではダメだ」と結論付けていたのです。 (pin 直接はやってなくて、Tr 外付けだったかもしれない…)
(黎明期 右も左もわかっていない頃の判断は 要因が全部見えてなくて 誤っていることが多いですね (^_^;;)
ところが 「 ボクのLPC810工作ノート 」では、普通に それで 駆動できる/駆動した と書いてあって、 これもちょっと気になっていたのです…。 (初版、ちゃんと買いました、LED は WS2812B そのものではなくて お仲間(?)の PL9823-F5 ですが)
(GLUE81X / LPC810+=2 が気になる人は こちらへ)
以下、波形・回路絵をご覧ください。(リンギングでかいですね…)
手法 波形・回路 (1) 標準の push-pull 駆動 (2) push-pull 駆動に 5V への pull-up-R 付けても影響はない (3) open-drain 駆動に pull-up 10kΩ × NG (4) open-drain 駆動に pull-up 10kΩ+3.3kΩ 並列 (5) level-converter (TC7SET32FU)
(6) WS2812B そのものを level-converter として使う
(本 WS2812B の電源は、VIH を下げるために少々低めのものを使います)
(7) 3.3V push-pull 出力と 5V 間を抵抗分圧したらどうだろう (8) ↑ 悪くなさそう
VIL が心配な人は assist も付けられます
(misc signal tricks by LPC810)
上記 今回の実験の中で、ターゲットの WS2812B を正常に駆動できなかったのは (3) だけです。(短いパルスが VIH に届いていませんので)
まぁ (1), (2) もインチキですが…
open-drain + pull-up-R では 線路の容量や相手の入力回路(プルアップ抵抗等 もしあれば)もパラメータとして影響が大きいので、 必ずしも波形が再現するとは限らないでしょう。
でも 400kbps の I2C ですら 2.2kΩとか使うんだからさぁ…
open-drain + pull-up-R では、 まずは (駆動時間内に) VIH を越えることが必要で、 この際 駆動パルス幅に対して 受け取り側のパルス幅は目減りしますので、 そういった部分のマッチングも要チェックですかね。
で、どれを採用するか…と言われると………、level-converter-IC としか 答えようがない、のだが…。
まだ若干 喉に引っかかっている感じがありますが、とりあえず ここまで。
- * - * -
p.s.
LPC810 を しゃぶりつくす基板、 作りました。 (今回ツボに はまって我ながらビックリ (^_^;;;)
[2016.11.16]
ring には 470Ωが、AE-WS2812B には 100Ωが、
入力保護(?)的に直列に挿入されていることに 今更 気付いてしまった……。