光を追いかけるロボットカー

明るいほうはどっち?

光ロボットカーの動き

左目  ANA(2)
右目  ANA(5)

前進  OUT 4,1 OUT 2,1
後退  OUT 5,1 OUT 3,1
左折  OUT 4,0 OUT 2,1
右折  OUT 4,1 OUT 2,0



プログラムを考えよう

Mission1.「光が当たったら前進!」

光センサーをひとつだけ使って、光が当たったら前進するという、シンプルな動きです。

左側光センサーANA2の値を読み込んで、変数L に入れます。
このプログラムでは、センサー値を1/100にして、明るさが0から10の数値になるようにしました。
数字が大きいほど明るいことを意味します(30行目)。

もし、明るさが5よりも小さいならば、光ロボットカーを止めます。
光ロボットカーの両方のモータを停止する命令は、OUT 0 です(50行目)。

もし、明るさが5以上なら、光ロボットカーを前進させます。
両方のモータを回す命令は、OUT 4,1: OUT 2,1です(60行目)。

最後に、0.1秒(6/60)待って、センサ入力に戻ります(100,110行目)。

 昼間や日光のよく当たる場所では、懐中電灯で光を当てなくても、勝手にロボットカーが動く場合があります。
その場合は、明るさの基準を5ではなく、7や8にしてください。
 光ロボットカーの走らせる場所によっては、明るさの基準を下げたり上げたりして、最適な値をみつける必要があります。

10 ‘HIKARI-ROBOT1
30 L=ANA(2)/100
40 ? L
50 IF L<5 OUT 0

60 IF L>=5 OUT 4,1: OUT 2,1
100 WAIT 6
110 GOTO 30

 


Mission2.「光スキ! 明るい方向へ走れ」

右側光センサーANA5も加え、左右のセンサーで、光の方向へロボットカ-を走らせましょう。

さて、ANA5は電源を入れた直後は入力ポートとして機能しません※1。
事前にANA5として使えるよう、おまじないが必要です(20行目)。

ANA2とANA5の準備ができたならば、それぞれセンサーの値を読み込みます。
ANA2は左=変数L、ANA5は右=変数R、として読み込みます(30行目)。

もし、右も左も両方とも明るさが5よりも小さい(暗い)なら、光ロボットカーを止めます(50行目)。

もし、右と左の両方とも同じ明るさなら、光ロボットカーを前進させます(60行目)。

もし、左側のほうが明るい(左>右)なら、光ロボットカーを左へ向けます。
左へ進みたい場合は、左モーターは停止して、右モーターのみを前進させます。
左モーターを止める命令は、OUT 4,0
右モーターを前進させる命令は、OUT2,1
(70行目)

もし、右側センサーのほうが明るい(左<右)なら、光ロボットカーを右へ向けます。
左モーターを前進させる命令は、OUT 4,1
右モーターを止める命令は、OUT2,0
(80行目)

IF命令の最後のGOTO100命令は必要です。
もう少し正しく説明すると、50行目のIF命令だけGOTO100が必要なのです。
70,80,90行目のGOTO100はなくても良いのです。

10 ‘HIKARI-ROBOT2
20 OUT1,-1
30 L=ANA(2)/100:R=ANA(5)/100
40 ?”ヒカリ スキ”,L,R
50 IF L<5 AND R<5 OUT 0:GOTO 100
60 IF L=R OUT 4,1: OUT 2,1:GOTO 100
70 IF L>R OUT 4,0: OUT 2,1:GOTO 100
80 IF L<R OUT 4,1: OUT 2,0:GOTO 100
100 WAIT 5
110 GOTO 30

※1 IchigoJamCPUのOUT1(出力)と ANA5(入力)は、IO端子を共有しており、切り替えて使用できる仕組みです。
OUT1,-1とすると以降はANA(5)として使用できます。
OUT1,1等を実行するとOUT端子になります。


Mission3. 「光はきらい・・ 光から逃げる」

ひかりが当たったら、逃げるプログラムです

10 ‘HIKARI-ROBOT3
20 OUT1,-1
30 L=ANA(2)/100:R=ANA(5)/100
40 ? “ヒカリ キライ”,L,R
50 IF L<5 AND R<5 OUT 0:GOTO 100
60 IF L=R OUT3,1:OUT5,1: GOTO 100
70 IF L>R OUT3,0:OUT5,1: GOTO 100
80 IF L<R OUT3,1:OUT5,0: GOTO 100
100 WAIT 5
110 GOTO 30


Mission4. 「光は好き!でも、強い光は嫌い・・」

さて、光ロボットカーに、もう少しわがままを聞いてもらうようにしましょう。
1.光があればそちらによっていく(Mission1の動き)。
2.でも、強すぎる光はキライなので、光から逃げるようにします(Mission3の動き)。
  2秒間は光から逃げる動きをしますが、その後は、また光があれば寄っていきます。

10 ‘HIKARI-ROBOT4
20 OUT 1,-1

30 L=ANA(2)/100:R=ANA(5)/100
40 ? “ヒカリキ スキ” L,R
45 IF L>7 AND R>7 GOTO 200
50 IF L<5 AND R<5 GOTO 300
60 IF L=R OUT 4,1:OUT 2,1: GOTO 100
70 IF L>R OUT 4,0:OUT 2,1:GOTO 100
80 IF L<R OUT 4,1:OUT 2,0:GOTO 100
100 WAIT 5
110 GOTO 30

200 CLT:OUT 0
210 L=ANA(2)/100:R=ANA(5)/100
220 ? “ヒカリ キライ”,L,R
230 IF L=R OUT 5,1:OUT 3,1: IF L<5 GOTO 280
240 IF L>R OUT 5,1:OUT 3,0
250 IF L<R OUT 5,0:OUT 3,1
260 WAIT 5
270 IF TICK()<120 GOTO 210
280 OUT 0
290 GOTO 30


300 OUT 0:H=L:?:?”ヒトヤスミ”
310 LED1:L=ANA(2)/100:R=ANA(5)/100
320 IF L>H OR R>H OUT 0:GOTO 30
330 IF !RND(500) OUT 4,1: OUT 2,1
340 IF !RND(100) OUT 4,0: OUT 2,1: WAIT 10*RND(7)
350 IF !RND(100) OUT 4,1: OUT 2,0: WAIT 10*RND(7)
360 WAIT 10
370 OUT 0
380 GOTO 310



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,