create every day - 福野泰介の一日一創

IchigoJamでも光る大五郎! 300コのフルカラーLEDを簡単コントロール! IchigoJam x WS2812B/SK6812/NeoPixel

2017/09/12 23:55:00
#IchigoJam #maker 

ギャル電さんの「光る大五郎」やキラキラウェアラブルを創りたい?
1つ数十円で買えるコンピューター内蔵フルカラーLED、WS2812B。
IchigoJamへダイレクト接続、超簡単にコントロールできます。


10x10、100コ並んだSK6812(WS2812B+ホワイトLED)や、テープ状に300コ連なったWS2812Bや、8コのスティック状WS2812Bの制御実験の様子です。

LEDがいくつあっても接続電源に信号線1本だけというシンプルな配線。

IchigoJam - WS2812B
VCC - 5V
OUT1 - DIN (DOUT - 次のDIN...)
GND - GND

DIN端子に、0/1をパルスの長さで表し、GBB(SK6812ではGRBW)の順に8bitずつ上位からまとめて送ると、フルカラーLEDに内蔵されているマイコンが、先頭の自分の分のデータを抜き取りDOUTから出力。数珠つなぎにしたLEDをまとめて自在にコントロールできます!

WS2812Bの電源は3.5V〜5.5V。ちょっと足りませんが、IchigoJamの3.3V(VCC)でも一応動きました。電源を5Vを使い、3.3Vの信号のまま変換なしでも動いてくれましたが、ちゃんと作るときにはWS2812Bなど仕様書をチェック!

パルスは300nsec(ナノ秒)単位なので、ARMマシン語入門その10と同様、マシン語のループを使って時間調整しつつOUT1を制御するプログラム(ソースコードは末尾)を打ち込んで、早速実験!

10 POKE#700,240,181,114,182,64,24,80,33,9,2,1,49,9,4,4,136,1,48,128,37,1,48,3,120,255,34,74,96,3,39,10,38,43,66,1,208,10,39,3,38 20 POKE#728,1,63,253,209,0,34,74,96,1,62,253,209,109,8,239,209,1,60,234,209,98,182,240,189 RUN

まずは、WS2812B、1つを点灯してみましょう。
赤(明るさ4、最大255です)

POKE#800,3,0,0,4,0:IF USR(#700,#800)

POKE#800,3,0,4,0,0:IF USR(#700,#800)

POKE#800,3,0,0,0,4:IF USR(#700,#800)

先頭2byteで送信するデータサイズをリトルエンディアンで指定します。
3つのLEDを使って、緑、黄、赤の信号色に光らせる時はこんな感じです。(明るさ8)

POKE#800,9,0,8,0,0,8,8,0,0,8,0:IF USR(#700,#800)


(WS2812B、SK6812、NeoPixelで検索するといろいろ楽しい照明が見つかります!)

マシン語へデータを受け渡し用に#800の変数領域を使っていますが、画面用メモリ(VRAM)を使ってもOKです。

POKE#900,9,0,10,0,0,10,10,0,0,10,0:IF USR(#700,#900)

NコのLEDをランダムな全部同じ色で光らせる場合はCOPYコマンドをつかいます。(102コの配列の204byteなので68コ以上制御しようとすると変数が壊れてしまうので注意!)

N=8:M=4:POKE#800,N*8,0,RND(M),RND(M),RND(M):COPY#805,#802,N*3-3:IF USR(#700,#800)

Nコの全部、ランダム色(N<=67)

200 N=8:M=4:POKE#800,N*3,N*3>>8 210 FOR I=0 TO N*3-1:POKE#802+I,RND(M):NEXT 220 U=USR(#700,#800) 230 GOTO 210 GOTO200

ランダム色をスクロール(N<=67)

300 N=8:M=4:POKE#800,N*3,N*3>>8 310 COPY#802+N*3-1,#802+N*3-4,-N*3+3 320 POKE#802,RND(M),RND(M),RND(M) 330 IF USR(#700,#800) 335 WAIT5 340 GOTO310 GOTO300

300コで3,280円(1コ11円)!300コのテープ状LEDを制御するには、300*3+2の902byte必要になります。 VRAM領域768byteだけでは足りないので、#800からの変数領域も使います。ただし、変数が破壊されてしまうので、直接数で指定した「ランダム色をスクロール」300コ対応版です。

300 POKE#800,300*3,300*3>>8 310 COPY#802+300*3-1,#802+300*3-4,-300*3+3 320 POKE#802,RND(3),RND(3),RND(3) 330 IF USR(#700,#800) 335 WAIT5 340 GOTO310 GOTO300


WS2812Bが8コついたスティック状

応用編、8コをランダムな色でゆっくりつけたり消したり

100 N=8:M=16:POKE#900,N*3,N*3>>8 110 R=RND(M):G=RND(M):B=RND(M) 120 FOR I=0 TO 19 125 L=I:IF I>10 L=19-I 130 FOR J=0 TO N-1 135 P=N-J 140 POKE#902+J*3,G*L*P/80,R*L*P/80,B*L*P/80 150 NEXT 160 IF USR(#700,#900) 170 NEXT 180 GOTO 110 GOTO100


10x10、100コのフルカラーLED(SK6812)でなんと1,440円!?(1コ14円)
好きなように切ってつないでも使えるSK6812を10x10のマトリクスLEDにしてみました。


5V/GND/信号線をはんだづけしていきます

SK6812は、WS2812Bに加えて白色LEDが増えて入る分、1つあたり4byte使って制御します。
4byte目を使って白く光らせる。

POKE#800,4,0,0,0,0,10

100コのランダム色がスクロール RGBW版

500 N=100:M=4:POKE#800,N*4,N*4>>8 510 COPY#802+N*4-1,#802+N*4-5,-N*4+4 520 POKE#802,RND(M),RND(M),RND(M),0 530 IF USR(#700,#800) 535 WAIT5 540 GOTO500 GOTO500

応用編、文字表示 for 10x10 SK6812

10 S="IchigoJam" 20 FOR I=0 TO LEN(S)-1 25 P=#900:POKEP,400,400>>8:P=P+2 26 R=RND(2):G=RND(2):B=RND(2) 27 FORJ=0TO9:POKEP,G,R,B,0:P=P+4:NEXT 30 C=ASC(S+I) 40 FOR J=0 TO 7 45 POKEP,G,R,B,0:P=P+4 50 FOR K=0 TO 7 70 N=PEEK(C*8+J)>>(7-K)&1 75 POKEP,G,R,B,N*8:P=P+4 80 NEXT 85 POKEP,G,R,B,0:P=P+4 90 NEXT 91 FORJ=0TO9:POKEP,G,R,B,0:P=P+4:NEXT 92 IF USR(#700,#900) 95 NEXT 96 GOTO20


文字をランダムな背景色と合わせて表示

ド派手な電子工作から硬派な電車風電光掲示、ほんわかステキな演出など、手軽に作れちゃいますね!

アセンブラ「asm15」でコンパイルできる、WS2812用マシン語のソースコードはこちらです。

' OUT1 WS2812B DOUT [R1+`0001]を変更でOUTnに変更可能 ' R0 - 開始アドレス 送信byte数low,送信byte数high,G1,R1,B1,G2,R2,B2 .... ' R1 - base address (初期はRAM offset) ' R2 - OUT value 0/#FF ' R3 - data value ' R4 - data count ' R5 - bit count ' R6 - wait count buf ' R7 - wait count @WS2812B PUSH {LR,R4,R5,R6,R7} CPSID R0=R0+R1 R1=#50 'R1=#50010000 GPIO1 R1=R1<<8 R1+=1 R1=R1<<16 R4=[R0]W R0+=1 @LOOP_DATA R5=#80 R0+=1 R3=[R0] @LOOP_BIT R2=#FF [R1+`0001]L=R2 R7=3 '(3*4+1)=13 <- 16.8+-7.2 R6=10 '(10*4+1)=41 <- 43.2+-7.2 R3&R5 IF 0 GOTO @SKIP R7=10 '(10*4+1)=41 <- 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 [R1+`0001]L=R2 R6-=1 'wait R6*4+1 clock IF !0 GOTO -1 R5=R5>>1 IF !0 GOTO @LOOP_BIT R4-=1 '+6clock IF !0 GOTO @LOOP_DATA CPSIE POP {PC,R4,R5,R6,R7}

SK6812用にウェイト調整しなくても動きました。仕様に合わせて高速化したい場合、R6/R7のウェイトを調整しよう!
* ウェイトをインライン展開して、8byte削減!(72byte→64byte)

links
- マシン語を制すもの時間を制す「DMX512事例」 / IchigoJamでまなぶARMマシン語入門その10
- yhironaka/IchigoLamp: シリアルLED WS2812B をLPC810を使ってIchigoJamから光らせるっ!

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / high-res profile image