Raspberry Pi Pico(d_38)NeoPixel bitstream
NeoPixel bitstream
Raspberry Pi Picoで<class ‘NeoPixel’>を使わずにNeoPixelを駆動したいと思います。
「NeoPixel」や接続例については記事d_37などを参照ください。
bitstream
micro:bitでは記事e_26、記事e_27のようにSPI通信のMOSIピンを使って駆動させましたが、Raspberry Pi Picoには「machine.bitstream」のメソッドがあり簡単にNeoPixelを駆動できます。
neopixel.pyにもbitstreamがファンクションとして使えるので、こちらを使って動作確認をしています。
そのためneopixelをインポートして使っています。。
neopixelをインポートしない場合はneopixel.bitstreamの部分をmachine.bitstreamに替えてください。
■bitstream
neopixel.bitstream(pin, encoding, timing, data, /)
で与えます。
timing は (high_time_0, low_time_0, high_time_1, low_time_1)で、nsec単位です。
WS2812 RGB LED(NeoPixel)の場合、
f=800kHz(T=1250nsec)で各々400+850=1250、800+450=1250となり(400, 850, 800, 450)値になります。
tm=(400, 850, 800, 450) #timing
GP16を出力ピンにします。(記事d_37の接続図に合わして)
p0=Pin(16,Pin.OUT)
data
8連LEDの場合、dataは8*3=24bytesなので24bytesとします。
data=bytearray(24)
結局、
neopixel.bitstream(p0, 0 ,tm ,data)
として使うことになります。※下部スクリプトではdataはabufになっています。
動作確認
動作確認のスクリプトは以下のようにしました。以下の順で点灯動作します。
個別点灯確認
pos0 RED
pos2 ORANGE > RED > ORANGE
pos5、6、7 RED、GREEN、BLUE
Colors listで点灯確認
C0 > C1 >c2
シフト確認
pos0-RED 右に3移動(pos3)、2移動(pos5)、2移動(pos7)
pos7-GREEN 左に3移動(pos4)、2移動(pos2)、2移動(pos0)
off、cls確認
C0点灯>off() > 再点灯> cls > データクリア(消灯)
バッファデータ確認
pos0、1、2 R、G、Bを設定
バッファー読み出し shellに表示
off() > 同データ shellに表示
cls() > データクリア shellに表示
pico_btreaml_test_04b.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import Pin
import neopixel
import time
# Color データ RGB-PWM data
RED=(255, 0, 0)
ORANGE=(0xff,0xfA,0)
YELLOW=(255, 150, 0)
GREEN=(0, 255, 0)
CYAN=(0, 255, 255)
BLUE=(0, 0, 255)
PURPLE=(180, 0, 255)
WHITE=(0xff,0xff,0xfd)
ALL=(255,255,255)
# LED 0 ~ 7 の色を設定
C0=[RED,GREEN,RED,GREEN,RED,GREEN,RED,GREEN] #1
C1=[RED,YELLOW,GREEN,BLUE,RED,YELLOW,GREEN,BLUE] #2
C2=[RED,ORANGE,YELLOW,GREEN,CYAN,BLUE,PURPLE,WHITE] #3
# send bitstream data
def d_send(data):
neopixel.bitstream(p0, 0 ,tm ,data)
# 表示クリア
def d_off():
buf=bytearray(n*3)
d_send(buf)
# 表示オン
def d_on():
global abuf
d_send(abuf)
# データクリア
def cls():
global abuf
abuf=bytearray(n*3)
d_send(abuf)
return abuf
# 個別位置LED表示
# N-1番目のdata bytearray(3)を書き換える
def nLed(num,dat=[0,0,0]):
#d=[0x06,0x05,0x04]
abuf[num*3]=int(dat[1]*rt) #G
abuf[num*3+1]=int(dat[0]*rt) #R
abuf[num*3+2]=int(dat[2]*rt) #B
#print(abuf)
## Color listを表示
def cLed(clist,tms):
## se C list n-LED data
i=0
for d in clist:
nLed(i,d)
i=i+1
d_send(abuf)
time.sleep_ms(tms)
# 右へ移動
def Rsh(n,tms=0):
global abuf
for i in range(n):
sbuf=abuf[-3:]
sbuf.extend(abuf[0:-3])
#print(i)
abuf=sbuf
if tms !=0:
d_send(abuf)
time.sleep_ms(tms)
else:
d_send(abuf)
# 左へ移動
def Lsh(n,tms=0):
global abuf
for i in range(n):
sbuf=abuf[3:]
sbuf.extend(abuf[:3])
abuf=sbuf
if tms !=0:
d_send(abuf)
time.sleep_ms(tms)
else:
d_send(abuf)
# バッファーデータを返す
def r_data(buf):
c_list=[]
num=len(buf)
for i in range(int(num/3)):
pos=[]
#ORDER -- (1, 0, 2, 3) G R B W
pos.append(buf[i*3+1])#R
pos.append(buf[i*3+0])#G
pos.append(buf[i*3+2])#B
c_list.append(pos)
return c_list
## example
# Control output pin
p0=Pin(16,Pin.OUT)
# machine.bitstream(pin, encoding, timing, data, /)
# timing (high_time_0, low_time_0, high_time_1, low_time_1)
tm=(400, 850, 800, 450)
# 8連LED NeoPixel
n=8 # 8LED LED Pos 0 ~ 7 (n-1)
abuf=bytearray(n*3) # 8LEDx3(RGB-PWM data)
# 明るさ減 PWM値の調整
rt=0.05
## 個別LED点灯確認
# led pos0 RED
nLed(0,RED)
d_send(abuf)
time.sleep(1)
# led pos2 ORANGE>RED>ORANGE
nLed(2,ORANGE)
#d_send(abuf)
d_send(abuf)
time.sleep(1)
nLed(2,RED)
d_send(abuf)
time.sleep(1)
nLed(2,ORANGE)
d_send(abuf)
time.sleep(1)
# led pos5,6,7 RED,GREEN,BLUE
nLed(5,RED)
nLed(6,GREEN)
nLed(7,BLUE)
d_send(abuf)
time.sleep(3)
d_off()
## Colors listで点灯確認
wt=1500 #msec
cLed(C0,wt)
d_off();time.sleep_ms(500)
cLed(C1,wt)
d_off();time.sleep_ms(500)
cLed(C2,wt)
d_off();time.sleep_ms(500)
##シフト動作確認
# Rsh(n,tms=0) test
cls()
nLed(0,RED)
d_send(abuf)
time.sleep(1)
Rsh(3,500) # 右に3シフト500ms間隔
#time.sleep(1)
Rsh(2) # 右に2
time.sleep_ms(500)
Rsh(2) # 右に2
time.sleep_ms(500)
d_off()
# Lsh(n,tms=0) test
cls()
nLed(7,GREEN)
d_send(abuf)
time.sleep(1)
Lsh(3,500) # 左に3シフト500ms間隔
#time.sleep(1)
Lsh(2) # 左に2
time.sleep_ms(500)
Lsh(2) # 左に
time.sleep_ms(500)
## off() cls() test
nLed(3,BLUE)
nLed(4,BLUE)
d_send(abuf)
time.sleep(1)
d_off()
time.sleep(1)
d_send(abuf) # LED ON (Undo Data)
time.sleep(1)
cls()
time.sleep(1)
d_send(abuf) # Not ON (Reset Data)
time.sleep(1)
## バッファー値の確認
nLed(0,RED)
nLed(1,GREEN)
nLed(2,BLUE)
d_send(abuf)
time.sleep(1)
print(r_data(abuf)) #current data
d_off()
print(r_data(abuf)) #same data
cls()
print(r_data(abuf)) #all '0'deta (Reset)
関数 部分説明
以下に部分的な説明を記載します。
■nLed(num,dat=[0,0,0])
個別のLEDに明るさ調整したpwmデータを送ります
num:NeoPixel LED連番号です。
dat:[r,g,b]の色データです。この値に明るさ比を掛けてPWM値にしています。
■cLed(Cdat,tms=0)
Cdat:NeoPixel LEDの個数分の色リスト、各値に明るさ比を掛けてPWM値にしています。
tms:待機時間です。単位はmsecです。0なら実質データ送信だけです。
■Rshf(n=1,tms=0)
右側(上)にシフトします。
n:シフト数
tms:シフト間隔の時間です。単位はmsecです。0なら実質データ送信だけです。
■Lshf(n=1,tms=0)
左側(下)にシフトします。
n:シフト数
tms:シフト間隔の時間です。単位はmsecです。0なら実質データ送信だけです。
■cls()
PWMデータをクリアします。
■d_off()
元のデータは残してLEDをoffします。
■d_on()
バッファデータを送りLEDをonします。
■r_data(buf)
bufデータを返します。[[r,g,b], [r,g,b],…[r,g,b]]のリストを返します。
実行結果
結果は以下の動画ようになりました。
動画 bitstream_01.mp4
バッファー値の確認はThonnyのShellに表示されます。
>>> %Run -c $EDITOR_CONTENT
[[12, 0, 0], [0, 12, 0], [0, 0, 12], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[12, 0, 0], [0, 12, 0], [0, 0, 12], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]# off() 前と同じ
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] # cls() クリアされる
>>>
まとめ
Raspberry Pi PicoのbitstreamでNeoPixel シリアルLEDの動作確認ができました。