フォト
2020年5月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
無料ブログはココログ

« ゲームボーイ(旧タイプ)のパーツ その2 | トップページ | NeoPixel(WS2812B)の制御 その2 »

2018年5月20日 (日)

NeoPixel(WS2812B)の制御

Arduino UnoでNeoPixel(WS2812B)の制御をライブラリ無しで行ってみました。
まずは手持ちのリング形状16個LEDのタイプを制御してみました。

Dscn7924

動いている様子



スケッチ
2018/05/30 修正)

 

制御を行うためのプロトコル自体は非常に簡単です。
1ポートからLOW or HIGHを指定したタイミングで出力するだけです。

リセット(RET)コード送信後、1つのLED(ピクセル)毎に24ビット分の0 or 1の送信、
複数のLEDの場合、24ビットxLED数分のデータを送信します。

02

リセット(RET)コードは、Treset(50μ秒)間 LOWを出力、
1ビット 0 を送信(0 code)は、T0H間HIGHを出力後、T0L間LOWを出力、
1ビット 1 を送信(1 code)は、T1H間HIGHを出力後、T1L間LOWを出力、
します。

だだし、このタイミングがシビアです。

03

作成したスケッチでは、

   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」カテゴリの記事

表示器制御関連」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: NeoPixel(WS2812B)の制御:

« ゲームボーイ(旧タイプ)のパーツ その2 | トップページ | NeoPixel(WS2812B)の制御 その2 »