※なにか気になる点がありましたらコメント欄にご記入ください。また、工作や回路を製作する場合には、細かい作業などに対して、細心の注意を払われるようお願いいたします。
目次
1.はじめに
前に以下の記事を書きました。
tanuki-bayashin.hatenablog.com
今回、上の記事の内容をバージョンアップしたのでご紹介します。
免責事項:
この記事は電子工作レベルのお話です。実用に際し、いかなる損害も自己責任でお願いします。
筆者はいかなる場合においても、一切の責任がないことをご承知おきください。
2.変更内容
変更した内容は以下の2点です。
- データの書き込みを1個のセルずつ行っていたのを、100個まとめて行うようにした
- オーバークロックが気軽に行えることを知ったので、試してみた
2の変更点に関しては、知人であるもりしーさん(@kotaMorishita)のYoutubeの番組内で知りました。
また、具体的記述の仕方については、こちらの方の記事を参考にしました。
お二方共々、ありがとうございました。
3.ソースコード
リスト1に前回分のソースコードを再掲します。
リスト1 main.py (再掲)
#必用なライブラリをインポートします import array, utime, math from machine import Pin import rp2 from rp2 import PIO, StateMachine, asm_pio #WS2812 のLEDの数を指定します NUM_LEDS = 100 # Pico特有のstate machine を用いてWS2812の制御を行っています #このあたりの処理はリスト1の下のリンク先の図書より引用しました # PIO State Machine to display ws2812 @asm_pio(sideset_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_LEFT, autopull=True,\ pull_thresh=24) def ws2812(): 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] # Create the StateMachine with the ws2812 program, outputting on Pin(16)(). sm = StateMachine(0, ws2812, freq=8000000, sideset_base=Pin(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)]) #position の位置のLEDをred, green, blue の値にて指定します def ar_color(position, red, green, blue): ar[position] = (green<<16) + (red<<8) + blue #全てのLEDを消灯する関数です def clear_all(): for i in range(NUM_LEDS): ar[i] = 0 sm.put(ar,8) # 色をカラフルに表示するための仕掛けが(ちょこっと)秘められています def triangle(x): if x < 20.0: y = int(1.5 * x) elif x < 40.0: y = 60 - int(1.5 * x) else: y = 0 return y # 6個のリストのメモリーを確保しています red = [0.0 for i in range(NUM_LEDS)] green = [0.0 for i in range(NUM_LEDS)] blue = [0.0 for i in range(NUM_LEDS)] y_red = [0.0 for i in range(NUM_LEDS)] y_green = [0.0 for i in range(NUM_LEDS)] y_blue = [0.0 for i in range(NUM_LEDS)] #ここから処理がスタートします if __name__ == '__main__': # Process arguments print('Press Ctrl-C to quit.') # Neopixelを同心円上に色を変化させて表示するための計算です r_max = math.sqrt(4.5 * 4.5 * 2) for i in range(NUM_LEDS): x = float(i % 10) - 4.5 # 左から何列目かを計算し、4.5を引いています y = float(i) / 10.0 - 4.5 # 下から何段目かを計算し、4.5を引いています # 中心(4.5, 4.5)からの距離を求め、最大値を1に規格化しています r = math.sqrt(x*x + y*y) / r_max # 同心円状に色を変えて表示するための処理です。20、0、40と値をずらしています red[i] = (r * 40 + 20.0) % 60.0 green[i] = (r * 40 + 0.0 ) % 60.0 blue[i] = (r * 40 + 40.0) % 60.0 try: # 無限ループです while True: #それぞれのLEDの色を計算し、表示しています for i in range(NUM_LEDS): # 1ステップ前から色を1つずらします red[i] = (red[i] - 1.0) % 60 green[i] = (green[i] - 1.0) % 60 blue[i] = (blue[i] - 1.0) % 60 # 関数triangle() により色を計算しています y_red[i] = triangle(red[i]) y_green[i] = triangle(green[i]) y_blue[i] = triangle(blue[i]) # 色を表示しています ar_color(i, y_red[i], y_green[i], y_blue[i]) sm.put(ar,8) utime.sleep_us(100) utime.sleep_us(1) # ctl-C が押されたときの処理です except KeyboardInterrupt: #### clear ws2812b clear_all()
【変更その1】
今回変更したのは102-104行と部分です。
sm.put(ar,8) utime.sleep_us(100) utime.sleep_us(1)
ここを
sm.put(ar,8)
と変更しました。要は Neopixel への書き込みを、セル1個ずつ行っていたのを、100個まとめて行ったということです。(インデントを1段減らしています)
また、100μsや1μsの時間待ちは、今回の書き方に変えたところ、必要なくなりました。(理由は分かりません)
【変更その2】
以下の文をリスト1の7行の手前に付け加えました。
from machine import freq machine.freq(250_000_000)
これはラズパイpicoのクロック周波数を250MHzに変更するというものです。(デフォルトでは125MHz。いわゆるオーバークロックです)
こうすることにより確かに動作速度が格段に速くなりました。
ただ動作の安定性や異常が発生しないかという点について筆者はそれほど詳しくないので、使用する際には注意していただきたいと思います。