LEDでナナイロづくり

IchigoJam BASIC 1.4.1にて、フルカラーLEDをコントロールする命令が追加されました(2019/12/6)。

 そこで、このLED基板と新命令を使って、いろいろな色を光らせるプログラムを組んでみましょう。
今回使用したLED基板は12個のLEDが円形に並んだWS2812 12ビット RGBリングです。
他に24個や7個の円形や、テープ状のもの、8個のスティック型などがありますが、WS2812というLED部品が載っているものならば、どれでも試せると思います。


IchigoJam基板とは次の図のようにつなげます。

IchigoJam側    LED基板側   
 VCC(3.3V)  ー  VCC      
 GND     ー  GND      
 LED      ー  IN       
           OUT(繋がない) 


LEDを光らせる新しい命令です(参考:WS.LED命令) 。

WS.LED 光らせるLED数 [, 繰り返し数]

 WS.LED 12 のような命令になりますが、残念ながらこれだけでは光りません。
あらかじめ、それぞれのLED位置に相当する配列に、色(約1600万色の中から1色)をRGB値で設定する必要があります(参照:RGB Wikipedia )。

次の例では、1番目のLEDが緑色に光ります(GRBの順であることに注意)。

[0]=100:[1]=0:[2]=0
OK
WS.LED 12
OK

配列[0]に、緑色の値 = 100 (0~255までの値で明るさを指定)
配列[1]に、赤色の値 = 0  (赤色は光らない)
配列[2]に、青色の値 = 0  (青色は光らない)


 しかし、この方法では色の組み合わせが多く配列も複雑なため、プログラミングが難しいです。
そこで、簡単にプログラミングができるように、7色に限定し た「LED色設定」サブルーチンを作りました。
(サブルーチン命令:GSB命令

LED色設定: @SET_WS.LED(I,C,L)

1000 @SET_WS.LED(I,C,L)
1010 IF I>33 THEN I=33
1020 IF(L<1 OR L>255)AND(C%8) THEN L=20
1030 [I*3]=C&1*L
1031 [I*3+1]=C>>1&1*L
1032 [I*3+2]=C>>2&1*L
1040 RETURN

変数 I LED点灯位置
0~33 (LEDの数は最大34個まで)
———————————————————————–
変数 C 色
0■無(光らない)、1緑、2赤、3黄、4青、
シアン(青緑)、6マゼンタ(紅紫)、7
———————————————————————–
変数 L 輝度
1~255(範囲外は強制的に20にする。100以上はあまり変わらない)
———————————————————————–
※以下のPRINT命令を入れておくと動きがわかりやす
 1025 PRINT “I=”;I,”C=”;C,”L=”;L
※「色設定サブルーチン」の詳細説明はこちらを参考に(別サイト)。
※WS.LED命令用の便利なサブルーチン集をこちらに追加しました(2019/10/29)。


I=0:C=1:GSB 1000
OK
WS.LED12
OK

I=1:C=2:GSB 1000
OK
WS.LED12
OK

I=2:C=3:GSB 1000
OK
WS.LED12
OK

I=3:C=4:GSB 1000
OK
WS.LED 12
OK

I=4:C=5:GSB 1000
OK
WS.LED12
OK

I=5:C=6:GSB 1000
OK
WS.LED12
OK

I=6:C=7:GSB 1000
OK
WS.LED12
OK

面倒な配列を考えなくても、変数Iと変数Cを設定してサブルーチンを呼ぶだけで、色を設定してくれます。
あとは、WS.LED命令を実行するだけです。

LEDを消すには、変数Cの色を0にします 。
例えば、3番目のLEDを消すには、、、

I=2:C=0:GSB 1000
OK
WS.LED12
OK

すべてのLEDを消すには、CLV命令が便利です (参考:CLV命令) 。

CLV
OK
WS.LED 12
OK





Mission !

色設定サブルーチンは、一度に一か所のLEDしか設定できません。
複数のLEDを設定するには、 FOR~NEXT命令を使うと便利です。
この命令は、指定した変数が条件を満たすまで順番に処理を繰り返してくれます(参考:FOR命令)。
今回のLED基板のように、順番に並んでいるLEDをコントロールするのには、すごく相性がよい命令なのです。

LEDの光らせ方を、つぎのミッションプログラムで試しましょう。
同時に、FOR~NEXT命令の使い方も理解してみましょう。

※以下のMissionプログラムを実行するときは、予め「色設定サブルーチン」を事前に入力しておいてください。


Mission1(FOR命令の使い方1)

LED位置(変数I)の0から11の順番に、色(変数C)を設定して、12個すべてのLEDを光らせます(40~80行目)。
プログラムをRUNして、画面に ? が表示されたら、0~7の色コードを入力して、何色が光るかみましょう。

10 ‘WS.LED1 設定した色で12個全部のLEDを光らせる
20 CLV
30 INPUT C
40 FOR I=0 TO 11
50 GSB 1000
60 WS.LED 12
80 NEXT
100 END


※次のプログラムを加えると、 LED位置(変数I) の変わり方がわかります。
45 PRINT “I=”;I

※ INPUT命令の代わりに、RND命令で 色(変数C)の値を決めると、RUNするたびに、IchigoJamが気まぐれに色を決めてくれます。
30 C=RND(7)+1

※次のプログラムを追加すると、1秒毎にLEDが順に光ります。
70 WAIT 60

※FOR命令は必ず1回は実行します。

RUN
?4
OK


Mission2(FOR命令の使い方2 二重ループ)

Mission1のプログラムを基本に、色(変数C)もFOR命令で変化させて、7色全部を光らせます。
FOR~NEXTが入れ子になっているのに注目してください。

10 ‘WS.LED2 七色を順番に光らせる
20 CLV
30 FOR C=1 TO 7
40 FOR I=0 TO 11
50 GSB 1000
60 WS.LED 12
70 WAIT 10
80 NEXT
90 NEXT
100 END



※次のプログラムを加えると、変数CとIの変わり方がわかります。
45 PRINT “C=”;C,”I=”;I


Mission3(FOR命令の使い方3 STEPオプション)

FOR命令のSTEPオプションを使うと、LEDを光らせる位置を飛ばすこともできます。
FOR I=0 TO 11 STEP 2
これは、変数Iが、0,2,4,・・,8,10 と2づつ増えていきます。

10 ‘WS.LED3 LEDをひとつ置きにひからせる
20 CLV
30 FOR C=1 TO 7
40 FOR I=0 TO 11 STEP 2
45 PRINT “C=”;C,”I=”;I
50 GSB 1000
60 WS.LED 12
70 WAIT 10
80 NEXT
90 NEXT
100 END



※STEPの値を3や5や11に変更して試しましょう。
11以上だとどうなるか?
また、0にするとどうなる?

※STEPは省略できます。省略した場合は、STEP 1 と同じ動きになります。


Mission4(FOR命令の使い方4 STEPオプション2)

Mission3までのプログラムでは、LEDが右回りに順に点燈しました。
左回りに光らせるにはどうすればよいでしょうか。
これも、STEPオプションで解決できます。

FOR I=11 TO 1 STEP -1
こうすると、変数Iが、11,10,9,・・・,2,1,0 と1づつ減っていきます。

変数Lの値で明るさも変えましょう。
L値は1~255までの範囲です。
L=8

10 ‘WS.LED4 ひかりを逆回転させる
20 CLV: L=8
30 FOR C=1 TO 7
40 FOR I=11 TO 0 STEP -1
45 PRINT “C=”;C,”I=”;I,”L=”;L
50 GSB 1000
60 WS.LED 12
70 WAIT 10
80 NEXT
90 NEXT
100 END


※STEP -1 としたときは、TOの値が初期値Iより小さくなければいけません。例えばつぎは文法エラーになります。
FOR I=11 TO 12 STEP -1

※次のプログラムを加えると、光が一周すると2秒停止します。これは、サンプル2や3でも同じように動きます。
85 WAIT 120

※次のように変更すると、プログラムをずっと繰り返しますね。
100 GOTO 30

※LEDを点灯したとき、最初は明るく、徐々に暗くして点灯するようにしてみましょう。
変数Lを、FOR~NEXTを利用して変化させます。
ヒント:42 FOR L=50 TO 5 SETP ?




Mission5(応用プログラム1)

Mission1を応用して、簡易ルーレットを作ってみました。
光が回って見えるようにするには少し工夫が必要です。
50行目で、現在のLED位置に紫色(C=6)を設定しています。
80行目で、今度はLED位置に無色(C=0)に設定することでLEDを消しています。

サブルーチンの呼び出し方法も、ラベル方式にしました。

ルーレットを止めるときは、[ESC]キーを押します。
しかし、このプログラムでは少し問題が起きます??。どこが問題なのか探してみてください。

10 ‘WS.LED5 ルーレット
20 CLV
30 L=15
40 @LOOP: FOR I=0 TO 11
45 PRINT “I=”;I
50 C=6: GSB @SET_WS.LED(I,C,L)
60 WS.LED 12

70 WAIT 3
80 C=0: GSB @SET_WS.LED(I,C,L)
90 WS.LED 12

100 NEXT
110 GOTO @LOOP



※BEEP命令を追加して、ルーレットに合わせて音も出せます。
60 WS.LED12: BEEP 5,10

※次のプログラムをどこかに追加すると、IchigoJam基板のタクトスイッチを押したら止まるようになります。
??に入る行番号を探してください(ヒント:LEDが光ったあとに押す?)。
?? IF BTN()=1 THEN END


Mission6.(応用プログラム2)

センサー(光や音など)の値によって変化するレベルメータ―です。

ANA2にアナログセンサーを接続します。
センサーの値は0~1023ですが、90で除算しているので、Aの値には0~11になります(30行目)。
0~11であれば、LED位置と簡単に比較できるようになります。
LED位置(変数I)よりセンサー値(変数A)が大きければ、色(変数C)を設定します(C=4:青)。そうでなければ、色はなし(C=0)を設定します(50行目)。
センサー値が0であれば、どのLED位置にも色は設定されないので、ひかりません。

WS.LED命令もFOR~NEXTの後に実行するようにしています。
LED位置すべての色設定を終えてからLEDを表示することで、処理も速くなります(80行目)。

10 ‘WS.LED6 レベルメーター
20 CLV:L=100
30 A=ANA(2)/90
40 FOR I=0 TO 11
50 IF A>I THEN C=4 ELSE C=0
60 GSB @SET_WS.LED(I,C,L)
70 NEXT
80 WS.LED 12
90 GOTO 30


※次を加えると、変数I,C,Lの変わり方が画面に表示されます。
45 PRINT “I=”;I,”C=”;C,”L=”;L

※このサンプルプログラムでは、センサー値が0だとLEDは光りませんが、次のように比較条件式を変えると、最低1コは必ず光らせることができます。
50 IF A>=I THEN C=4 ELSE C=0

※ 次のプログラムを加えると、 レベルが高いほど(センサー値が高いほど)明るくひからせることができます。
LED位置(変数I)の小さい順に、 輝度(変数L)に、
5,6,9,14,21,30,41,54,69,86,105,126 の値が入力されます。
55 L=5+I*I


Mission7.(応用プログラム3)

加速度センサーを使った傾き計です。

写真の加速度センサーはX,Y,Z軸の3軸センサーですが、このプログラムでは、X軸のみを使います。
ANA2に接続されたX軸の加速度センサーから、0~1023の値を得ます。
この加速度センサーの値は、水平のときに、約510になります。

変数Aに、右に傾けると+1~+11以上、左に傾けると-1~-11以上になるように計算しています(30行目)。

変数Aが0なら水平なので、LEDは光らせません(50行目)。

変数Aが正数(+)なら右に傾いているので、LEDを右回りにマゼンダ色を光らせます。
IF命令が続いていますが、色を設定するプログラムは、サンプル6と同じ仕組みです(60行目) 。

変数Aが負数(ー)なら左に傾いているので、LEDを左回りにシアン色を光らせます(70行目) 。

10 ‘WS.LED7 傾き計
20 L=100
30 A=(ANA(2)-510)/10
40 FOR I=0 TO 11
50 IF A=0 THEN C=0
60 IF A>0 THEN IF A>I THEN C=6 ELSE C=0
70 IF A<0 THEN IF A<I-11 THEN C=5 ELSE C=0
80 GSB @SET_WS.LED(I,C,L)
90 NEXT
100 WS.LED 12
110 GOTO 30


※ 次のプログラムを加えると、変数A,I,Cの変わり方がわかります。
15 CLS
85 LC 0,0
86 ?”A=”;A, “I=”;I, “C=”;C,