「Amazon.co.jp: Quimat Arduino用RGB LED パネル 5050 SMD WS2812B IC 個別にアドレス可能 256ピクセルLEDライトledスクリーン led壁 広告ボードなど作成QWS03: DIY・工具・ガーデン」
配列バージョンだと102コしか制御できないので、1灯を1byte/8bitで表す256色モードを開発。IchigoJamの画面がちょうど32文字なので、上から8行を使った画面そのまま表示が完成!
「さばえ」と読めますか?
キーボードのInsertキーで挿入モードから上書きモードに変更し、お絵かきしてマシン語呼び出すRUNでOK!
こちらが画面そのまま送信WS2812Bドライバです。(128byte)
10 POKE#700,240,181,114,182,9,36,36,2,9,25,1,36,164,70,27,76,11,120,91,9,0,240,31,248,11,120,155,8,7,34,19,64,0,240,25,248,11,120,3,34,19,64,91,0,0,240,19,248,97,68,1,48,31,34,16,66,234,209,66,9 20 POKE#73C,8,42,8,208,31,49,1,35,93,66,172,70,26,66,225,209,2,49,156,70,222,231,98,182,240,189,128,37,155,0,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 30 POKE#778,239,209,112,71,4,0,1,80 40 U=USR(#700,0)
画面に好きな文字を書いて、8行目から下でRUNで表示されます!
(32x8のWS2812Bはいつものごとく、5V-VCC,DIN-OUT1,GND-GNDで接続)
画面に表示して呼び出すだけなので、ゲームづくりも簡単にいけそうですねっ
256色は、MSXのSCREEN8に習って、G 3bit, R 3bit, B 2bit の計8bitで256色を表します。
POKE#900,`00011100:RUN:'RED POKE#900,`11100000:RUN:'GREEN POKE#900,`00000011:RUN:'BLUE
やってみると一目瞭然。`から始まる8bitの2進数、あれこれいじって試してみましょう。
FOR I=0 TO 255:POKE#900+I,I:NEXT:RUN
256色、全部表示
100 POKE#900+RND(256),RND(256):U=USR(#700,0):CONT GOTO100
ランダム
100 POKE#900+31+32*RND(8),RND(256):U=USR(#700,0):SCROLL LEFT:CONT GOTO100
流星
COPY#F00,#900,#100:SAVE
32x8の画面をプログラム領域末尾に保存
10 CLS:LC0,8:COPY#900,#F00,#100:U=USR(#700,0)
このプログラムと一緒に保存しておくと、ドライバ設定後、32x8の画面を読み出して、WS2812B表示として復元可能!
好きな文字をスクロール表示する、電光掲示板プログラム50 CLS:S=" IchigoJam":POKES+1,255:P=0:C=RND(256) 60 A=ASC(S+P/8):FORI=0TO7:N=PEEK(A*8+I):POKE#900+31+I*32,N>>(7-P&7)&1*C:NEXT 70 U=USR(#700,0):SCROLL LEFT:P=P+1:P=P%(LEN(S)*8):IF !P C=RND(256) 80 GOTO 60
Armマシン語ドライバ解説と応用
32x8のマトリクス状にならんだWS2812B、配線のしやすさからか、ジグザグに並んでいました。
一番上の行は左から右につながっていて、2行目は折り返して右から左へとつながっている。
色の8bit対応と、ジグザグに対応したドライバのasm15表記のArmマシン語コードがこちら。
' OUT1用 WS2812B 32x8 @OUTを変更でOUT1-4で変更可能、パラメータは0を指定 ' R0 - data count ' R1 - data address #900(VRAM)から1byte 1pixel G3bit,R3bit,B2bit ' 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 - increment or decrement address @WS2812B PUSH {LR,R4,R5,R6,R7} CPSID R4=9 R4=R4<<8 R1=R1+R4 R4=1 R12=R4 R4=[@OUT]L @LOOP_DATA R3=[R1] ' G R3=R3>>5 GOSUB @SEND_BYTE R3=[R1] ' R R3=R3>>2 R2=7 R3&=R2 GOSUB @SEND_BYTE R3=[R1] ' B R2=3 R3&=R2 R3=R3<<1 GOSUB @SEND_BYTE R1+=R12 R0+=1 R2=31 R0&R2 IF !0 GOTO @LOOP_DATA R2=R0>>5 R2-8 IF 0 GOTO @END R1+=31 R3=1 R5=-R3 R12=R5 R2&R3 IF !0 GOTO @LOOP_DATA R1+=2 R12=R3 GOTO @LOOP_DATA @END CPSIE POP {PC,R4,R5,R6,R7} @SEND_BYTE R5=#80 R3=R3<<2 ' 数を大きくするともっと明るくなる @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 R7=9 '(9*4+1)=37 <- 43.2+-7.2 R6=3 '(3*4+1)=13 <- 16.8+-7.2 @SKIP 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 #50010004
R0〜R15まで16コあるレジスタ、R8〜R15は使える命令が5コに制限されます。(Cortex-M0 Armマシン語表より)
Rd=Rm Rd+=Rm Rn-Rm GOTO Rm GOSUB Rm
32コデータを送信する毎に、壊しちゃってOKなR12を使って1足したり1引いたりすることで命令数をできるだけ少なく作っています。
(R8,R9,R10,R11:マシン語から戻るときに元の値にしておけば自由に使ってOK、R12:破壊してOK、R13:スタックレジスタ、R14:リンクレジスタ、R15:プログラムカウンタ)
1Mbit、EEPROMからデータを流し込んで動画にするのも楽しそうですね!
32x8の場合256byteなので、128KBで512枚分、秒間10コマで51.2秒分作成可能。
R2-8 を R2-16 や、R2-24 に変更すれば 32x8 を2つ(32x16)や3つ(32x24)接続した大スクリーンにも対応できます。
「フルカラーLED、WS2812B 16x16 をあやつるマシン語プログラムのパッチ(差分) on IchigoJam」(追記)
変数の保存を諦めれば、#800の変数領域から1KB使った32x32送信もいけちゃいます。(R4=9をR4=8に変更)
コンパクトなArmマシン語とお手軽なIchigoJam BASICの使いわけ、楽しいですよ!
「はじめてのマシン語 - IchigoJamではじめるARMマシン語その1」