2022-07-14
とある場所のWS2812Bを使った照明づくり。WS2812Bを6750コ(150コx45ライン)配置して制御するので専用のドライバが必要。久々に使うArmマシン語、ひとまず16色パレット対応ドライバづくりでカンの取り戻し。

WS.LED命令は画面を汚さず配列を使ってシンプルに34コまでのWS2812Bを個別制御するIchigoJamのコマンドです。第二パラメーターにリピート数を指定すれば、繰り返し模様であれば大規模な照明も作れます。

ただ、大規模なフルカラーLEDを個別制御しようと思ったら別途ドライバが必要です。RGB、それぞれ8bitで3byteで表しますが、データ容量が大きくなり勝ちなので、GIFやPNG形式のように色との対応テーブル、パレットを使うことにします。

画面を表すメモリ(VRAM=#900)の先頭から1byteで1ピクセルをパレット番号、0-15を表します。下位4bitを使うことにしたので、0から9までの番号やアルファベット、空白のSPCは0と同じ扱いになって見た目にもわかりやすいのがポイントです。パレットは配列(#800)から配列3つを使ってWS.LEDの順と同様、緑、赤、青で指定することにします。16パレットあるので、配列を48要素、[0]から[47]までを使います。

Arm用のアセンブリ言語、asm15以前作ったモノをベースに作ったドライバがこちら。

' LED用 WS2812B 32x8 #800に3byteパレット最大16色パレット、R, G, B(キャラクターコードの下位4bit、0やSPCが0) ' R0 - data count ' R1 - data address #900(VRAM)から1byte 1pixel = 1color palette #800 ' R2 - temp OUT value 0/#FF, & 15 ' R3 - data value, temp ' R4 - GPIO address ' R5 - bit count ' R6 - wait count buf ' R7 - wait count ' R12 - none @WS2812B R2=8 R2=R2<<8 R2+=R1 PUSH {LR,R2,R4,R5,R6,R7} 'push #800 CPSID R0+=0 IF 0 GOTO @END 'err R0 must be not 0 R4=9 R4=R4<<8 R1=R1+R4 R4=[@OUT]L @LOOP_DATA R3=[R1] ' palette R2=15 R3&=R2 R2=6 ' palette #800から配列3要素、6byteずつ R3*=R2 PUSH {R1} R1=[SP+1]L R1=R1+R3 R3=[R1]W ' G R1+=2 GOSUB @SEND_BYTE R3=[R1]W ' R R1+=2 GOSUB @SEND_BYTE R3=[R1]W ' B GOSUB @SEND_BYTE POP {R1} R1+=1 R0-=1 IF !0 GOTO @LOOP_DATA @END CPSIE POP {PC,R1,R4,R5,R6,R7} @SEND_BYTE R5=#80 @LOOP_BIT R2=#FF [R4]L=R2 R7=3 '(3*4+1)=13 <- 16.8+-7.2 R6=9 '(9*4+1)=37 <- 43.2+-7.2 R3&R5 IF 0 GOTO @SKIP_LOOP_BIT R7=9 '(9*4+1)=37 <- 43.2+-7.2 R6=3 '(3*4+1)=13 <- 16.8+-7.2 @SKIP_LOOP_BIT R7-=1 'wait R7*4+1 clock IF !0 GOTO -1 R2=0 [R4]L=R2 R6-=1 'wait R6*4+1 clock IF !0 GOTO -1 R5=R5>>1 IF !0 GOTO @LOOP_BIT RET @OUT DATA L #50010000+`10000000 'LED(PIO1_5)

ながーくつないだWS2812Bで、いろいろ制御を楽しみましょう!

アセンブラ「asm15」でアセンブルして、IchigoJam BASICにシリアル通信で転送するか、打ち込みましょう。手で打ち込んだ場合、実行する前に保存しておくのがオススメです。

10 POKE#700,8,34,18,2,10,68,244,181,114,182,0,48,26,208,9,36,36,2,9,25,21,76,11,120,15,34,19,64,6,34,83,67,2,180,1,153,201,24,11,136,2,49,0,240,13,248,11,136,2,49,0,240,9,248,11,136,0,240,6,248 20 POKE#73C,2,188,1,49,1,56,232,209,98,182,242,189,128,37,255,34,34,96,3,39,9,38,43,66,1,208,9,39,3,38,1,63,253,209,0,34,34,96,1,62,253,209,109,8,239,209,112,71,128,0,1,80 RUN OK CLS:?"010101":LET[0],10,20,5,0,10,0:?USR(#700,10)

パレットの0番に10,20,5、1番に0,10,0をセットして、画面の先頭から表示した10byte分を使ってWS2812Bを制御!

FORI=0TO9:POKE#900,I:NEXT:FORI=0TO16*3-1:[I]=RND(30):NEXT:?USR(#700,10)

ランダムパレットの例。

BASICの限界を超えられるマシン語。マシン語の面倒をカバーしてくれるのがコンパイラ。そのコンパイラによって、より手軽にコンピューターを操れるさまざまなプログラミング言語や、ツールが創られてきました。その先を創るのはアナタです!


とある場所向けの照明の設計図。後で見ると自分でも何を書いたのが分からなくなるかも。

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS