※なにか気になる点がありましたらコメント欄からお伝えください。また、回路を製作する場合には電源を切るなど、注意を払って行うようお願いいたします。
(2021/10/11追記)
目次
1.はじめに
WS2812BというICチップ内蔵のフルカラーLEDのアレイがある(図1左)。これはRaspberry Pi Pico (以下Pico と記述:図1右)での制御も可能である。これらは筆者も愛用しており、Picoにて制御する際の専用のライブラリがあったら便利かと思い、製作してみた。あくまで自分用である。
※少し調べましたが、まずNeoPixelというものがあり、これはマイコン付RGB LEDを総称したadafruitの商品シリーズ名だそうです。その中にWS2812Bと呼ばれるものも含まれるとのことです。
したがって、以降、私の記事ではNeopixelと記述することとします。(2021/10/11追記)
2.回路
WS2812BとPicoについてのくわしいことははここでは詳しくは説明しない。検索などで調べてください。
全体構成図を以下に示す。(Pico 用の電源は省略。USBケーブルを接続すると給電される)
簡単に説明すると、WS2812Bには3本の接続する電線がある。1本はGND、1本は電源、残りの1本が制御用である。制御用の電線はPicoからの出力信号を受け取り、WS2812Bの何番目のLEDのRGBをそれぞれどれくらいの強さで光らせるかを受信する。
また、WS2812Bの電源に関して述べると、WS2812B1素子当たり、RGB3個のLEDが内蔵されていて、それぞれ定格は約12mA流して使う。WS2812Bが100個の素子で構成されているとすると、最大約3.6Aの電流が必要となる。電源ラインと直列に数百Ωの保護抵抗を入れるなど注意が必要である。(WS2812B内に保護抵抗が収められている場合もある。メーカーによって異なる模様)
3.ライブラリ
リスト1に自作のライブラリを載せる。(多くは以下の書籍を参考にした)
THE OFFICIAL RASPBERRY PI PICO GUIDE : Get started with MicroPython on Raspberry Pi Pico
www.raspberrypi.org
リスト1(ファイル名:Class_ws2812b.py)
import array, utime from machine import Pin import rp2 from rp2 import PIO, StateMachine, asm_pio # PIO State Machine to display ws2812 @asm_pio(sideset_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_LEFT, autopull=True,\ pull_thresh=24) def ws2812b(): T1 = 2 T2 = 5 T3 = 3 label("bitloop") out(x, 1) .side(0) [T3 - 1] jmp(not_x, "do_zero") .side(1) [T1 - 1] jmp("bitloop") .side(1) [T2 - 1] label("do_zero") nop() .side(0) [T2 - 1] class Class_ws2812b: def __init__(self): self.sm_no = 0 # state machine No(0-7) self.Pin_No = 16 # the Number of conected Pin(GPIO) def init_ws2812b(self, sm_no, freq, Pin_No): self.sm_no = sm_no self.freq = freq self.Pin_No = Pin_No # Create the StateMachine with the ws2812b program, outputting on Pin_No. sm = StateMachine(self.sm_no, ws2812b, self.freq, \ sideset_base=Pin(self.Pin_No)) return sm
説明(筆者はクラスやインスタンスに関してよく理解していない):
① 1~ 4行目:必要なライブラリを読み込む
② 6~18行目:この部分は筆者はちゃんと理解していない。PIO State MachineというPicoを高速で動かすためのものらしい。(ラズパイPico用のマシン語?)前述の書籍に書かれていた。
20~34行目:この記事のメインとなる部分である。以下順に見ていく
③20行目:クラスClass_ws2812b の宣言
④22~24行目:クラスの初期化(microPythonならではの記述である)
⑤26~34行目:WS2812Bの初期化。27~29行目で変数の受け渡しを行っている。
27行目 sm_no:state machine の番号。8個用意され、0-7の間で指定できる。
28行目 freq :動作させる周波数
29行目 Pin_No:信号を出力するピンの指定(GP○○の○○のこと)
32~33行目 :StateMachine という関数で、sm_no、freq、Pin_Noと動作させる関数(ここではws2812b()(上の9~18行目))を指定し、変数sm にインスタンスを与えている。
34行目 戻り値sm を返している
4.ライブラリを使ってプログラムを組む
4.1ライブラリの使用例
実際に3章で紹介したライブラリの使用例を示す(リスト2)。長々と書いているが、大事な部分は18行目ぐらいまでである。
リスト2
import array, utime from Sep_2021 import Class_ws2812b #Configure the number of WS2812B LEDs. NUM_LEDS = 16 # Get the Instance of StateMachine with the WS2812B ws = Class_ws2812b.Class_ws2812b() # StateMachine(0, ws2812, freq=8000000, sideset_base=Pin(16)) sm = ws.init_ws2812b(0, 8000000, 16) # start the StateMachine, it will wait for data on its FIFO. sm.active(1) # Display a pattern on the LEDs via an array of LED RGB values. ar = array.array("I", [0 for _ in range(NUM_LEDS)]) # すべてのLEDの r g b の値を、 # 指定されたr g b の値にセットする def ar_color_all(red, green, blue): for i in range(NUM_LEDS): ar[i] = (green<<16) + (red<<8) + blue sm.put(ar,8) utime.sleep(1) # すべてのLED の値をゼロにする def clear_all(): for i in range(NUM_LEDS): ar[i] = 0 sm.put(ar,8) if __name__ == '__main__': # Process arguments print('Press Ctrl-C to quit.') try: while True: # ar_color_all(red, green, blue) ar_color_all(100, 0, 0) # 赤 ar_color_all(50, 0, 50) # マゼンタ ar_color_all(50, 50, 0) # 黄色 ar_color_all(0, 100, 0) # 緑 ar_color_all(0, 50, 50) # 水色 ar_color_all(0, 0, 100) # 青 ar_color_all(20, 20, 20) # 白 except KeyboardInterrupt: #### clear WS2812B clear_all() print('program is finished')
解説
1行目 必要なライブラリを読み込む
2行目 3章で作ったライブラリを読み込んでいる。リスト1のファイル名はClass_ws2812b.pyで、Sep_2021という名前のフォルダーに入っている。
5行目 LEDの個数である。
8行目 クラスClass_ws2812bのオブジェクト(?)を取得している。
11行目 smという変数にオブジェクトwsのインスタンスを取得している。
14行目 smはまた、ステートマシンでもあるので、それをオンの状態にしている。
17行目 今までの流れとは別にarというリスト型変数を定義している。要素数はLEDの個数と等しい。
21~25行目 ar_color_all()という関数を定義している。コメントにもあるが、すべてのLEDのRGB値をred、blue、greenの値にセットする。
28~31行目 clear_all()という関数を定義している。すべてのLEDのRBG値を0にしている。
(上の2つの関数のなかに ”sm.put(ar,8)”という記述がある。これにより、変数ar のなかに記述されているデータがWS2812Bに書きこまれている)
34~58行目 プログラムの本体である。if 文とtry と except にて CtrlーC が押されたとき、すべてのLEDを消してプログラムを終了する。
プログラムの中身としては、関数 ar_color_all() により、7色の色を順番に点灯させている。
5.まとめ
WS2812Bの初期設定を行う、ラズベリーパイPico専用のライブラリを製作した(試作の段階)。microPyhtonの学習の一環でもある。また、少しだけ、独自の関数も例示した。(あくまで自分用である)
今回は示していないが、もっとグラフィカルな表示も可能である。今後試してみたい。