NeoPixel(WS2812B)の制御
Arduino UnoでNeoPixel(WS2812B)の制御をライブラリ無しで行ってみました。
まずは手持ちのリング形状16個LEDのタイプを制御してみました。
動いている様子
スケッチ(2018/05/30 修正)
制御を行うためのプロトコル自体は非常に簡単です。
1ポートからLOW or HIGHを指定したタイミングで出力するだけです。
リセット(RET)コード送信後、1つのLED(ピクセル)毎に24ビット分の0 or 1の送信、
複数のLEDの場合、24ビットxLED数分のデータを送信します。
リセット(RET)コードは、Treset(50μ秒)間 LOWを出力、
1ビット 0 を送信(0 code)は、T0H間HIGHを出力後、T0L間LOWを出力、
1ビット 1 を送信(1 code)は、T1H間HIGHを出力後、T1L間LOWを出力、
します。
だだし、このタイミングがシビアです。
作成したスケッチでは、
T0H、T1L : 0.375μ秒 (6クロック分)
T0L、T1H : 0.625μ秒 (10クロック分)
としました。
値としては、「Data transfer time」の表の有効範囲から少々ずれていますが、
問題無いようです。
Arduino Unoはシステムクロックが16MHzで動作しています。
1クロックは 1/16000000 = 0.0625μ秒 となります。
わずか、6~10クロックというシビアなタイミングで信号を出力する必要があります。
今回は6~10クロックの待ち時間の調整はインラインアセンブラ命令でNOPを入れて
調整しました。
*NeoOutReg |= NeoBitOut; // HIGHの出力
が6クロック
*NeoOutReg &= NeoBitMask; // LOWの出力
が3クロック
要していることを考慮しています。
時間待ち中は割り込みを禁止しています。
割り込みが入ると動作に外乱が入り、データが化けます。
また、デジタル出力をdigitalWire()で行うと処理が間に合いません。
そこで、出力レジスタに直接、値を書き込んでいます。
まあ、これだとシリアル通信等、他に何も出来ません。
そこで、次の対策としてSPIを使って何とかしようと思います。
関連記事
NeoPixel(WS2812B)の制御 その4(2020.01.09) ・・・ 16x16マトリックスの制御
NeoPixel(WS2812B)の制御 その3(2018.05.30) ・・・ 8x8マトリックスの制御
NeoPixel(WS2812B)の制御 その2(2018.05.22) ・・・ SPIを使った制御
NeoPixel(WS2812B)の制御(2018.05.20) ・・・ GPIOを使った制御 (この記事です)
参考にしたサイト
・uratan - WS2812B の駆動タイミングの限界調査
・PICマイコンの小部屋 - 秋月でWS2812B買ってしまったので動かないかも知れないけれど作ってみた
« ゲームボーイ(旧タイプ)のパーツ その2 | トップページ | NeoPixel(WS2812B)の制御 その2 »
「arduino」カテゴリの記事
- Arduino IDE+Arduino STM32環境で指定と異なるgccが使われてしまう(2025.01.23)
- Zorin OSでArduino Uno互換機(CH340)が認識しない(2025.01.19)
- Arduino IDE 2.3.4でArduino STM32を利用する(2025.01.12)
- Arduino用 SKK日本語変換ライブラリの開発 その1(2024.12.28)
- NeoPixel(WS2812B)の制御 その5(2024.09.15)
「表示器制御関連」カテゴリの記事
- NeoPixel(WS2812B)の制御 その5(2024.09.15)
- Arduino用 美咲フォントライブラリを更新しました(2024.03.21)
- Raspberry Pi Pico(MicroPython)でLEDドットマトリックスを使ってみる(2024.03.14)
- Raspberry Pi Pico MicroPython用のマルチフォントライブラリ(2023.02.09)
- MicroPython(Raspberry Pi pico)で8x8ドットNeoPixcel文字表示(2023.02.08)
« ゲームボーイ(旧タイプ)のパーツ その2 | トップページ | NeoPixel(WS2812B)の制御 その2 »
コメント