LEDでナナイロづくり 2

WS.LED命令を簡単に使うための、便利なサブルーチンをまとめました。
WS.LED命令の基本的なプログラミングはこちら「LEDでナナイロ」も参考にしてください。

  1. SET_WS.LED LED色の設定
  2. GET_WS.LED LED色の取得
  3. STR_WS.LED 一括色設定
  4. SHIFT_WS.LED LEDシフト設定
  5. LUMINA_WS.LED 輝度設定


1.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||L>255)&&(C%8) THEN L=20
1030 LET[I*3],C&1*L,C>>1&1*L,C>>2&1*L
1040 RETURN

・LED位置I番の配列(GRBの3か所)に、変数C(色)と変数L(明るさ)を設定します。
———————————————————————
変数 I LED点灯位置
0~33 (LEDの数は最大34個まで)
———————————————————————
変数 C 色
0■無(光らない)、1緑、2赤、3黄、4青、
シアン(青緑)、6マゼンタ(紅紫)、7
———————————————————————
変数 L 輝度
1~255(範囲外は強制的に20)
———————————————————————
※変数L=0は無効にしています。LED光らせたくないときは、変数Cに0を設定してください。
もし、変数Lの0を有効にするときは、1020行目を削除してください。

※変数Cは下位3ビット分しか使用していません。C=9は、C=1と同じ色です。マイナス値でも何かしら光ります(ABS(C%8)と同じ)。

※変数Lも下位8ビットしか使用していません。L=256はL=0と同じ明るさです(ABS(L%256)と同じ)。

サンプルプログラム1

10 L=100
20 FOR C=1 TO 7
30 FOR I=0 TO 11
40 GSB @SET_WS.LED(I,C,L)
50 WS.LED 12
60 WAIT 10
70 NEXT
80 NEXT
90 END


2.LED色の取得
@GET_WS.LED(I,C,L)

2000 @GET_WS.LED(I,C,L)
2010 IF I>33 THEN I=33
2020 C=([I*3]&&1)+([I*3+1]&&1)*2+([I*3+2]&&1)*4
2030 L=[I*3]|[I*3+1]|[I*3+2]
2040 RETURN

・LED位置I番の、色と明るさを、変数Cと変数Lに取得します。
現在WS.LED命令で光っているLEDの値を知ることができます。
・ただし、@SET_WS.LEDサブルーチンで設定したRGB値でないと正しい値を取得できません。
———————————————————————
変数 I
LED位置を指定する
0~33
———————————————————————
変数 C
変数Iで指定したLED位置の色が返る。
0■無(光らない)、1■緑、2■赤、3■黄、4■青、
5■シアン(青緑)、6■マゼンタ(紅紫)、7■白

変数 L 
変数Iで指定したLED位置の輝度が返る。
0~255

サンプルプログラム2

10 FOR I=0 TO 11
20 C=RND(8)
30 L=RND(255)
40 GSB @SET_WS.LED(I,C,L)
50 NEXT
60 WS.LED 12
70 WAIT 120
80 FOR I=0 TO 11
90 GSB @GET_WS.LED(I,C,L)
100 ? I,C,L
110 NEXT
120 END


3.一括色設定
@STR_WS.LED(S,(I,C,L))

3000 @STR_WS.LED(S,(I,C,L))
3010 FOR I=0 TO LEN(S)-1
3020 C=ASC(S+I)-48
3030 GOSUB @SET_WS.LED(I,C,L)
3040 NEXT

3050 RETURTN

・文字列を使用して、一度に色設定を行います。
———————————————————————
変数 S 色パターン
文字列で0~7をLED数分を指定します 。最大34文字。
———————————————————————
変数 L 輝度
———————————————————————
※変数 I 位置
 変数 C 色
これらの変数は文字列の文字パターンを作るために使います。
そのため、I,Cの値は、文字列最後の文字の設定値が入ります。

※@SET_WS.LEDサブルーチンを呼びますが、
つぎの行のように、直接置き換えてもよいです。
ただし、各変数の範囲チェックはしません。
3030 LET[I*3],C&1*L,(C&2&&1)*L,(C&4&&1)*L

※LEN(S)命令では、文字数を取得できます。これを利用するとWS.LEDの引数に直接使用できて便利です。
10 S=”12345″
20 GSB @STR_WS.LED(S,(I,C,L))
30 K=LEN(S):WS.LED K

サンプルプログラム3

10 S=”123456700000″
20 L=50
30 GSB @STR_WS.LED(S,(I,C,L))
40 WS.LED 12
50 END


4.LEDシフト設定
@SHIFT_WS.LED(R)

4000 @SHIFT_WS.LED(R)
4010 IF R<0 THEN GOTO @WSREV
4020 COPY #900,#800,R*6:COPY#806,#900,R*6
4030 LET[0],[(R*3],[R*3+1],[R*3+2]:RETURN
4040 @WSREV:R=-R
4050 LET[R*3],[0],[1],[2]
4060 COPY #900,#806,R*6:COPY#800,#900,R*6:R=-R:RETURN

・WS.LEDで点灯しているLED色を右または左に1つシフトします。
・ Rが正数(+)だと右、負数(-)だど左にシフトします。
———————————————————————
変数 R シフト個数
  整数(+プラス)なら右方向へ、R個分のLED色を1つずらす。
  負数(ーマイナス)なら左方向へ1つずらす。
———————————————————————

※内部処理では、配列を3個分をずらしています。
※変数Rには通常はWS.LEDの数と同じ値を設定しますが、1以下は意味をなしません。また、33はエラーになるので、最大シフトは32個までです。
※シフトして空いたLED位置には、シフト前の変数R値の値を代入します。つまりR=12のとき、右シフトとなり、12個目LEDの色が、1個目に入ります。

※IchigoJamBASICのCOPY命令は、 コピー元の領域とコピー先の領域が重なっていると正しく動作しません(c言語のmemcopyと同等)。そこで、画面表示用のメモリエリア(#900)に一旦コピーしています(c言語のmemmoveと同じ)。
画面表示がおかしくなるので、不都合であればキャラクタ用のメモリエリア(#700)に変更するとよいでしょう。
4020 COPY#700,#800,R*6:COPY#806,#700,R*6
4060 COPY#700,#806,R*6:COPY#800,#700,R*6:R=-R:RTN

サンプルプログラム4

10 CLV
20 S=”123456700000″
30 R=LEN(S)
40 L=50
50 GSB @STR_WS.LED(S,(I,C,L))
60 WS.LED 12
70 WAIT 120
80 FOR M=1 TO 24
90 GSB @SHIFT_WS.LED(R)
100 WS.LED 12
110 WAIT 30
120 NEXT
130 WAIT 180
140 R=-R
150 GOTO 80


5.輝度設定
@LUMINA_WS.LED(L,V,I)

5000 @LUMINA_WS.LED(L,V,I)
5010 IF V<1 OR V>34 OR !L THEN RETURN
5020 IF L>255 THEN L=255
5030 FOR I=0 TO V*3-1
5040 IF [I] THEN [I]=L
5050 NEXT
5060 RETURN

・WS.LEDで点灯している輝度を変更します。
———————————————————————
変数 L 変更する輝度 (1~255)
変数 V 変更するLED個数 (1~34)
いずれも範囲外の設定なら、サブルーチンは実行しない。
———————————————————————
変数 I 位置
文字列の文字パターンを作るために使います。
変数V×3-1と同じ値が入ります。

サンプルプログラム5

10 CLV
20 S=”123456700000″
30 L=75
40 GSB @SET_WS.LED(S,(I,C,L))
50 WS.LED12
60 WAIT 120
70 FOR L=100 TO 0 STEP -5
80 V=LEN(S)
90 GSB @LUMINA_WS.LED(L,V,I)
100 WS.LED12
110 WAIT 10
120 NEXT
130 END




OMAKE

WS.LED用のサブルーチンを応用して12個のLEDサークルをイルミネーションのように光らせるプログラムです。

10 @ARUN:’OTARU LED-DEMO 2020
20 CLS:CLV:R=12
30 L=50
40 S=”112233445566″
50 GSB @STR_WS.LED(S,(I,C,L))
60 WS.LED 12
70 WAIT 180
80 FOR M=1 TO 12
90 GSB @SHIFT_WS.LED(R)
100 IF R>0 WS.LED 12:WAIT 12
110 IF R<0 WS.LED 2,6:WAIT 50
120 NEXT
130 WAIT 60
140 R=-R
150 IF R>0 S=”666655554444333322221111″:R=24
160 IF R<0 S=”123456712345″:R=-12
170 GOTO 50

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

明るいほうはどっち?

光ロボットカーの動き

左目  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,


君だけが開けられる、ひみつの箱

サーボモータとセンサを使って、自分しか知らないパスコード(開け方)で解除する、小箱を作ろう。
サーボモータの制御方法とパスコードの処理方法をIchigoJamで学びます。

【必要な材料】

  1. IchigoJam基板(FW ver1.3.1以上)×1
  2. 箱 1300 × 1700 × 600 (Daiso:WOODENBOX 木のボックス74)  ×1
  3. ミニサーボモータ   ×1
  4. タッチセンサ(他に、光、スイッチ等やボリュームなども応用可能)   ×1
  5. 電池ボックス単三4本  × 1
  6. スペーサ、ねじなど

※箱は加工しやすい木製がよい。また、蓋がスライド式で透明だと作りやすい

配線図

プログラム準備

サーボモータ

1 ‘サーボモータ(鍵)
10 PWM 2,100
20 WAIT 60
30 PWM 2,200
40 WAIT 60
50 GOTO 10

2 ‘アナログジョイスティック
10 OUT 1,-1 :’OUT1をANA5に機能切換
20 ? ANA(2),ANA(5),IN(1)
30 GOTO 20


3'2桁の暗号
10 P=5: GSB @PASS
20 IF P ?"PASS1 OK" ELSE ?"PASS1 NG"
30 P=1: GSB @PASS
40 IF P ?"PASS2 OK" ELSE ?"PASS2 NG"
50 END

100 @PASS:CLT: K=0: LED0
110 IF IN(2)=0 GOSUB 500
140 IF TICK()<120 GOTO 110
150 BEEP5: IF K=P LED1: RTN
160 P=0:RTN

500 @COUNT: IF IN(2)=0 CONT
510 BEEP: K=K+1 : ?K
520 CLT: RTN



でじたる百葉箱(温度ロガー)

5V充電ケースとIchioJam本体+センサ基板(LCD+LED付き)。

測定場所でオートランさせて計測を開始。
計測した温度はLCDで確認しEEPROMへ自動記録。

計測終了後は、EEPROMの記録データを表示させて、模造紙のグラフ用紙( 1センチ四方のマス目模造紙 )にプロットする。
グラフ用紙は、温度と回数の比を2:1にして、温度変化を見やすくした。

各グループ3~4カ所を計測。

サンプルプログラムは 10秒間隔で10分間(60プロット)の測定例


1 ‘LCDオンドケイ by NEXTDAY SAVE0
10 CLS: L=1:C=1
20 [0]=(ANA(2)*32-500)/10
30 LC 0,0: ?”IchigoTemp 10sec”
40 LC 0,1: ?”No.”;C, [0];”゚C “
50 GOSUB @LCD

60 LED 1
70 IF [0]>20 OUT 1
80 IF [0]>25 OUT 3
90 IF [0]>30 OUT 7

99 LRUN1
100 @continu

110 BEEP
120 WAIT 60*10
130 C=C+1: IF C <= 60 GOTO 20

140 LRUN2



29000 END
29010 @LCD
29020 LET[96],640,64,#5639,#C6C,#C080,64
29030 Z=I2CW(62,#8C3,5)
29040 Z=I2CW(62,#8C0,3,#900,16)
29050 Z=I2CW(62,#8C8,3,#920,16)
29060 RTN

【プログラム概要】
10行目 初期化
    変数L:EEPROMへの記録数(1固定)
    変数C:測定した回数(最初は1回目)
20行目 温度センサのアナログ値を摂氏温度に変換
50行目 LCDへ測定値を表示
99、100行目 EEPROMへ温度を記録
120行目 10秒間待つ
130行目 6回/分×10分=60回の測定を繰り返す
140行目 EEPROMから測定した温度をリスト表示する

29000行目 Display on LCD (hidden subroutine)
     LCD表示サブルーチン
     LIST命令では非表示。

測定値から温度の求め方
温度センサーMCP9700は、温度を電圧で出力するセンサーです。
1. 温度センサーMCP9700は、0度のとき0.5Vを出力
2.0.01V毎に1度
3.ANA(2)には、MCP9700の出力電圧を読み取り、0(0V)から1023(3.3V)の範囲です。
4.


‘ ———————————————–SAVE1
‘ EEPROMデータ書き込み(I2Caddress 80)
‘ ———————————————–
‘ LRUN1   配列[n]の値をEEPROMへ書き込み(DATA追加)
‘  実行後は、LOAD0のプログラムの100行目へジャンプする
‘ LRUN1,1111 EEPROMのデータを初期化(DATA消去))
‘  実行後は、LOAD0を実行して終了

‘ L 記録する配列の長さ
‘ [0]~[L-1] EEPROMに書き込みする値
‘ M EEPROMに書き込まれたデータ数
‘ N EEPROMの書き込み先アドレス

1000 @EWRIT:’Write to EEPROM SAVE1(INIT)
1010 N=0:IF !L ? “EEPROM Write Error L=0!”:BEEP:END
1020 IF I2CR(80,#8E6,2,#8E4,2) ?”EEPROM I2C ERROR!”:BEEP:END
1030 M=M+1
1040 N=M*L*2
1050 N=N<<8|N>>8&#FF
1060 R=I2CW(80,#8E6,2,#800,L*2)
1070 N=0
1080 R=I2CW(80,#8E6,2,#8E4,2)
1100 IF FILE()=1 LRUN0,100
1110 RTN

1111 @EINIT:N=0:M=0: ‘EEPROM Initialization
1112 IF I2CW(80,#8E6,2,#8E4,2) ?”EEPROM I2C ERROR!”:BEEP:END
1113 ?”EEPROM ヲ ショキカ シマシタ”
1114 IF FILE()=1 LOAD0
1115 RTN


‘ ———————————————–SAVE2
‘ EEPROMデータ表示(I2Caddress 80)
‘ ———————————————–
‘ LRUN2   EEPROMの全データを1画面ごとに表示(SPCキーで次)
‘ LRUN2,2222 で、EEPROMの全データを1画面に集計(L=1のみ対応)
‘  実行後は、LOAD0のプログラムを実行(温度測定)
‘※IchigoJamが整数32256までしか扱えないため、LRUN2,2222は1000個以上の集計は表示がおかしくなる。

‘ M EEPROMに書き込まれたデータ数
‘ N EEPROMの読み込み先アドレス

‘ I カウンタ(レコード)
‘ J カウンタ(データ)
‘ Q データ表示用カウンタ(0~22)
‘ X プロット位置(X座標)
‘ R,S プロット位置(Y座標)
‘ T 最大値
‘ U 最小値
‘ Z I2C用
‘F 表示モード 0:グラフ、1:リスト

2000 @EREAD:F=1:’Read from EEPROM SAVE2
2010 CLS:N=0:Q=0:R=0:S=0:T=-30:U=99:IFI2CR(80,#8E6,2,#8E4,2)?”EEPROM I2C ERROR!”:BEEP:END
2020 IF M<1 ?” NOT DATA”:GOTO @END
2030 IF !L INPUT”DATA length?”,L
2040 FOR I=1 TO M
2050 N=I*L*2:N=N<<8|N>>8&#FF:Z=I2CR(80,#8E6,2,#800,L*2)
2060 IF F Q=Q+1:X=30:?DEC$(I,4);” ,”; ELSE X=I*30/M
2070 FOR J=0 TO L-1
2080 IF F ?[J];”,”;:GOTO@L2
2090 R=R+1:S=S+[J]
2100 IF T<[J] T=[J]
2110 IF U>[J] U=[J]
2120 @L2:NEXT
2130 IF F GOTO @L3
2140 IF X=Q GOTO @L4 ELSE GSB @GDSP:GOTO@L4
2150 @L3:?
2160 IF Q<23 GOTO @L4
2170 IF !INKEY() AND !BTN() CONT ELSE Q=0
2180 @L4:NEXT
2190 @END:LC0,23,1
2200 IF !INKEY() AND !BTN() CONT
2210 IF FILE()=2 LOAD0
2220 RTN

2222 @GRAPH:’EEPROM Graph
2230 F=0:GOTO @EREAD+10

2240 @GDSP
2250 LC0,0:?”サイコウ”;T;” サイテイ”;U;” データ”;M;
2260 LCX,35-(S/R):?”*”;:Q=X:R=0:S=0
2270 LCX,20:IFI>999?I/1000;
2280 LCX,21:IFI>99?I%1000/100;
2290 LCX,22:IFI>9?I%100/10;
2300 LCX,23:?I%10;
2310 LC0,5:?”30″:LC0,10:?”25″:LC0,15:?”20″
2320 RTN

「LRUN2」の表示例
「LRUN2,2222」の表示例

※EEPROMへの書き出しと読み出しプログラムは、福野さんのコードを参考にして作成しました。
https://fukuno.jig.jp/2192(福野泰介の一日一創

せんぷう機&温度センサー

Daisoのスタンド扇風機を改造(PCN金沢さんのモータードライバ学習基板(FET)を取付け)して、温度センサーで回転速度を制御します。
モーター電源4.5Vは扇風機内臓の電池ボックスから給電するので、IchigoJamの稼働に影響しません。
2019年5月26日(日)の入門講座で使用予定です。
子どもプログラミング入門講座(PDF 札幌 菊水元町地区センター)

せんぷう機プログラム
タクトスイッチを押したらスタート、もう一度タクトスイッチを押したらストップ。

100 OUT5,0              または PWM 5,0
120 IF BTN()=0 THEN GOTO120     ←  タクトスイッチOFFならループ
130 IF BTN()=1 THEN GOTO130      ←  タクトスイッチONならループ
140 OUT5,1              または PWM 5,1500
150 IF BTN()=0 THEN GOTO150      ←  タクトスイッチOFFならループ
160 OUT5,0:BEEP50,120
190 END

温度計算プログラム

10 LET A,ANA(2)  ← センサーの測定値を A 入れる
20 V=33*A/10  ←---電圧(V)の計算式
30 T=(V-500)/10  ← 温度(T)の計算式
40 ?T,V,A  ←----- 計算結果の表示 T(温度、V電圧、A(測定値)
50 WAIT 30
60 GOTO 10

PCN金沢オリジナル 教材/キット

・測定間隔を指定 W 10 秒
・LED の点滅 :中間温度 Y )では黄色の LED だけが点灯
・最高温度以上の場合だけ、赤LED 点灯+せん ぷう 機が回る+ BEEP 音

1 ‘Termometer&Motor
10 CLS:OUT0:BEEP     初期設定
11 W=60/10         測定間隔 初期値10秒
20 INPUT “?High: “,X    温度設定 (赤 LED 点灯、せんぷう機回転)
22 INPUT “?Middle: ”,Y   温度設定 (黄 LED 点灯)
24 INPUT “?Low: ”,Z     温度設定 (青 LED 点灯)
30 CLS:? X,Y,Z,W/60      設定温度、計測間隔(秒)の表示

50 LET A,ANA(2)       温度計測
60 V=A*32/10
65 T=(V-500)/10
70 LC10,12:?T,V,A,      測定値 、 計算値の表示
80 IF T<=Z THEN OUT1    設定値の判断
82 IF T=Y THEN OUT2
84 IF T>=X THEN OUT20:BEEP2
85 WAIT W           10 秒 間隔
90 GOTO 50

HEART★6基板を、ゲーム用のコントローラにするワザ

ルーレットで使用した、HEART★6基板を、ゲーム用のコントローラに改造しよう。
まずは、ボタンを押したときの状態を次のプログラムで確かめます。

10 PRINT IN(4),IN(3),IN(2),IN(1),””,IN(9),BTN()
20 WAIT 5
30 GOTO 10

INとBTNは、ボタンを押したときの状態が違うことに注意してください。

IN(x):ボタンが押されると入力が0、押されていないと1(プルアップ)
BTN():ボタンが押されると入力が1、押されていないと0(プルダウン)

では、IchigoJam定番の「川下り」ゲームを改造して、キー操作からHEART★6基板のボタンに改造する方法を説明しましょう。

オリジナルのプログラム

1 ‘KAWAKUDARI 2018 http://fukuno.jig.jp/2194
10 CLS:X=16
20 LC X,5:?”O”
30 LC RND(32),23:?”*”
35 WAIT 3
36 X=X-BTN(28)+BTN(29)
40 IF SCR(X,5)=0 GOTO20

1 ‘KAWAKUDARI 2018 http://fukuno.jig.jp/2194
10 CLS:X=16
20 LC X,5:?”O”
30 LC RND(32),23:?”*”
35 WAIT 3
36 X=X-BTN(28)+BTN(29)
40 IF SCR(X,5)=0 GOTO20

  1. まず、HEART★6基板のどのボタンをどのように使うかきめましょう。今回は、IN(4)は左、IN(1)は右にします。
  2. 次に、プログラムからキーボード入力の個所を探します。このプログラムでは、BTN命令を使っていますね。
  3. 次に、BTN命令の使い方を理解します。これは、プログラミングする人によって考え方が違うことから、どのように使おうとしたのか(仕様を)考える必要があるためです。このプログラムでは、BTN(28)は←キー、BTN(29)は→キーを押したときに1になることを利用して動きを決めていました。
  4. これで、BTN(28)はIN(4)、BTN(29)はIN(1)に置き換えれば良いことがわかります。 X=X-!IN(4)+!IN(1)
  5. でもちょっと待って!。
    IN命令の状態を確かめたとき、ボタンを離す=1、押す=0、となり、BTN命令を逆でした。
    BASICにはこんなときに使える式が用意されていて、式NOT(省略形 ! )があります。
    式NOTは、0なら1、1なら0するという性質があります。
    36 X=X-!IN(4)+!IN(1)
  6. まとめると、以下のようなプログラムが完成します。
    さらに、IN(3)で再ゲームできるように50行目を追加しました。

HEART★6で操作できるように修正したプログラム

1 ‘KAWAKUDARI 2018
10 CLS:X=16
20 LC X,5:?”O”
30 LC RND(32),23:?”*”
35 WAIT 3
36 X=X-!IN(4)+!IN(1)
40 IF SCR(X,5)=0 GOTO20
50 IF IN(3) CONT ELSE RUN

INKEY命令を使っている場合は、少し改造方法が異なります。

10 CLS:X=16
20 LC X,5:?”O”
30 LC RND(32),23:?”*”
34 WAIT 3
35 K=INKEY():CLK
36 X=X-(K=28)+(K=29)
40 IF SCR(X,5)=0 GOTO20

10 CLS:X=16
20 LC X,5:?”O”
30 LC RND(32),23:?”*”
34 WAIT 3
35 ‘ K=INKEY():CLK
36 X=X-(IN(4)=0)+(IN(1)=0)
40 IF SCR(X,5)=0 GOTO20

6分タイマー

HEART★6基板(OUT1~6にLED,IN1~IN4にSWを追加したシールド基板)とIchigoDakeを使った、6分タイマーです。

【サンプル】

タイマーは、1分単位で時間をセットし、時間が来たらアラームが鳴ります。
SAVE0にプログラムを保存しておけば、BTNを押しながら電源を入れると、タイマーのプログラムが自動スタートします。

1.プログラムスタート時はタイマーセットモードです。
セット中の時間分だけLEDが点灯します。
ボタンを操作して時間をセットします。
IN1(SW1) -1分減らす(最小1分)
IN4(SW4) +1分増やす(最大6分)
IN3(SW3) セット完了&スタート

2.タイマー動作中は、1秒毎にLEDの光が一周し、残り時間の数だけLEDが点滅します。
IN2(SW2)ボタンを押すとキャンセルとなり、1.のタイマーセットモードになります。

3.時間が来たら、全LEDが点滅し、アラームが鳴ります。
どれかボタンを押すと、1.のタイマーセットモードになります。

【ソースコード】

1’HEART*6タイマー v1.0 by NEXTDAY
10 LET[1],4,6,7,39,55,63:C=3:CLO

20 @SET
30 OUT [C]
40 GSB @SW(S): IF S CONT
50 GSB @SW(S): IF !S CONT
60 BEEP 20
70 C=C-(S=8&&C>1)+(S=1&&C<6)
80 IF S<>4 GOTO @SET
90 CLT:BEEP5,100

100 @TIMER
110 OUT 1<<(TICK()%60)
120 IF TICK()/15%2 THEN OUT [C-TICK()/3600]
130 GSB @SW(S): IF S=2 BEEP 50,50:GOTO @SET
140 IF TICK()<C*3600 GOTO @TIMER

150 @ALM
160 PLAY”O5$B8C6″
170 OUT TICK()/10%2*63:GSB @SW(S): IF !S CONT
180 BEEP
190 GOTO @SET

1000 @SW(S):S=!IN(4)*8+!IN(3)*4+!IN(2)*2+!IN(1):RTN

【プログラム説明】

10行目 配列[1]~[6]にLED点灯パターン値を設定します。
 [1] OUT3の点灯値      ”000100=4
 [2] OUT3,2の点灯値     ”000110=6
 [3] OUT3,2,1の点灯値    ”000111=7
 [4] OUT6,3,2,1の点灯値   ”100111=39
 [5] OUT6,5,3,2,1の点灯値  ”110111=55
 [6] OUT6,5,4,3,2,1の点灯値 ”111111=63
※LED3の位置(基板頂点)を基準にした点灯値を配列設定することで、プログラムをわかりやすくしています。
 変数C タイマーセットの値。初期値3分。
 CLO IchigoJamポートのリセット。
    これをしないとボタン(IN1~IN4)が利かなくなることがあります。

20行目~ タイマー設定モード
 現在のタイマ設定値のLEDを点灯させて、40-50行目でボタンが押されるのを待ちます。ボタンの値は変数Sに入力されます。
70行目 ボタンによって設定された時間をセットします。1~6分の範囲チェックも同時に行います。
80行目 IN3ボタン(セット完了)が押されるまで、タイマー設定を繰り返します。
90行目 TICK値をゼロにリセットしてタイマーを開始します(BEEP音で合図)。

100行目~ タイマーカウントダウン
110行目 60tick(1秒)毎にLED点灯を回転させます。
120行目 15tick(0.25秒)毎に残り時間のLED数を点灯させます(110行目と合わせて、結果的に点滅となる)
130行目 IN2ボタン(キャンセル)が押されていれば、タイマー設定へ行きます。
140行目 セットした時間まで、タイマーカウントダウンを繰り返します。

150行目~ アラーム
160行目 アラーム用のPLAY文を実行します($繰り返し)。
170行目 何かボタンが押されるまで、全LEDを点滅して待ちます(この行を繰り返し)。
190行目 タイマー設定へ行きます。

1000行目 ボタン入力サブルーチン
     変数Sに、SW1(IN1)からSW4(IN4)の論理和をセットします。
     SW1が押されたとき、S=1、
     SW2が押されたとき、S=2、
     SW3が押されたとき、S=4、
     SW4が押されたとき、S=8、がセットされます。
     例えば、SW1とSW4が押されていた時は、S=9となります。

※TICK()命令の応用例
TICK()の値は0~16383を常に繰り返し変化します。
この性質を利用すると、特定の数値パーターンを作ることができます。
たとえば、

A=TICK()/60
 これは、1秒ごとに、0,1,2,3,4,5,0,1,・・が変数Aに値が入ります。さらに、

A=TICK()/60%2 
 これは、1秒ごとに0,1,0,1,0,1,0,・・が変数Aに値が入ります(%は余りを求める計算式)。

A=TICK()/30%6+1
 これは、0.5秒(30Tick)ごとに、6で割った余りプラス1、
つまり、1,2,3,4,5,6,1,2,3,・・の値が変数A入ります。

【書式】  TICK()/t%n+c
 t  変化時間(1/60秒単位=t/60秒毎)
 n 出力範囲(2なら0,1,0,1・・、3なら0,1,2,0,1,2)
 c オフセット

【ソースコード:かんたん版】

20 @SET
70 INPUT”タイマーセット(1-6)?”,C
80 IF C<1 OR C>6 THEN BEEP: GOTO @SET
90 CLT:BEEP5,100

100 @TIMER
110 T=TICK()/3600: ?”アト “;C-T;”フン”
120 OUT C-T,1 : WAIT 10
130 OUT 0 : WAIT 10
140 IF T<C GOTO @TIMER


160 PLAY”O5 $B8C3″
190 GOTO @SET

障害物を回避! センサーろぼっとカー 2019

ロボットカーを走らせよう。 進め! 止まれ! 右! 左!
壁(モノ)にぶつからない工夫は?
思いどおりに走らせるは?

【構成】
1.IchigoDake ×1 (FW ver1.2.3)
2.DAKE★IOx ver1.0 ×1 (Nextday)
3.二回路DCモータドライバ DRV8835 ×1 (秋月電子) 
 http://akizukidenshi.com/catalog/g/gK-09848/
4.シャープ測距モジュール GP2Y0E02A (アナログ出力)×1 (秋月電子)
 http://akizukidenshi.com/catalog/g/gI-07546/
5.FA130互換モータユニットタイヤ付き × 2(左右)
 https://www.mabuchi-motor.co.jp/motorize/branch/motor/
6.電源 単4(1.5V) × 2本
7.車体 × 1 ()


センサおよびモーターの動作テストプログラム

1 ‘DAKE ROBOT CAR TEST V0 2019/01/06
10 A=ANA(2)
20 B=A/25-4
30 PRINT A,BIN$(0,B)40 K=INKEY()
50 IF K=#30 OUT 0 :’数字キー0 のとき 停止 
51 IF K=#31 OUT 10 :’数字キー1 のとき 前進 OUT4,1 OUT2,1
52 IF K=#32 OUT 20 :’数字キー2 のとき 後退  OUT5,1 OUT3,1
53 IF K=#33 OUT 12 :’数字キー3 のとき 右旋回 OUT4,1 OUT3,1
54 IF K=#34 OUT 18 :’数字キー4 のとき 左旋回 OUT5,1 OUT2,1
55 IF K=#35 OUT 8 :’数字キー5 のとき 右折(L正転) OUT4,1
56 IF K=#36 OUT 2 :’数字キー6 のとき 左折(R正転) OUT2,1
57 IF K=#37 OUT 4 :’数字キー7 のとき 右折(R逆転) OUT3,1
58 IF K=#38 OUT 16 :’数字キー8 のとき 左折(L逆転) OUT5,1
999 GOTO 10


【サンプルプログラム】
 運転プログラムはSAVE0に保存します。
走らせるときはタクトスイッチを押しながら電源スイッチを入れて、コースに置きます。
 もう一度タクトスイッチを押すと、走り出します。

【ソースコード】

1 ‘DAKE ROBOT CAR by NEXTDAY
10 L=5: OUT 0
20 IF BTN()=0 THEN ? ANA(2): LED TICK()/30%2: CONT
30 @START
40 OUT 10: WAIT 1
50 IF ANA(2)<650 THEN CONT
60 OUT 0: WAIT 60
70 IF ANA(2)<450 GOTO @START
80 IF L=1 THEN OUT20: WAIT 80: OUT 0: WAIT 40
90 IF RND(3) THEN OUT16 ELSE OUT4
100 WAIT 30
110 L=L-1: IF L>0 GOTO @START
200 BEEP 5,100
999 RUN

【プログラム説明】
10行目 障害物検知回数、変数Lの初期化(5回検知したらリカバリ)
20行目 IchigoJam基板のタクトスイッチが押されるまで待つ
    そのとき、LEDは0.5秒おきに点滅させる。
30行目 @START :プログラム繰り返し点
40行目 前進。 WAITは距離センサの出力が安定するまでの時間。

50行目 手前10cm以内に障害物がなければ、この行を繰り返す。
60行目 障害物を検知したら、1秒停止。
70行目 再度、手前約20cm以内障害物がなければ@STARTへもどる。
    50行目より遠くの距離まで判断すること
    これは、人間が手や足でセンサーにかざしたときの対策。
80行目 障害物検知回数が残り1回なら、大きく後退。
    これは、袋小路などに入りこんで左右だけでは脱出できないときの対策
90行目 通常の障害物検知の時は、左右のどちらかに曲がる。
    RND(2)だと、0,1対象なのでRND(3)にして偏りをつけた。
100行目 単純に0.6秒停止。この命令はなくても、ほかには影響しない。
110行目 障害物検知回数をカウントし、なくなるまで@START
200行目 ここからリカバリー処理。
    現在はBEEPして、再度プログラムを実行するだけ。
    応用として、ここで360度ゆっくり回転して、
    センサで一番空いている方向を探すルーチンを入れてもよい。

6LEDルーレット (二進数シフト版)

HEART★6基板(OUT1~6にLED,IN1~IN4にSWを追加したシールド基板)とIchigoDakeを使った、6灯ルーレットです。

スイッチ1(IN1)を押すとルーレットスタート、スイッチ4(IN4)を押すとルーレットストップ。
ルーレットはストップボタンを押してから徐々に止まるので、どこでとまるかわかりません。
LEDは6個あるので、双六の代わりに使えます。

通常、OUTポートにつないだLEDは、OUT1,1やOUT2,1で光らせますが、このプログラムでは二進数によるシフト演算によって光らせています。

サンプルプログラム

【ソースコード】

1 ‘HEART*6ルーレット ver1.0 by NEXTDAY
10 LET N,2
20 OUT 1<<N
30 IF IN(1)=1 GOTO 30
40 LET W,1

50 OUT 1<<N
60 BEEP 100
70 WAIT W
75 PRINT N,BIN$(1<<N,6),IN(4),IN(3),IN(2),IN(1)
80 LET N,N+1
90 IF N=6 THEN LET N,0
100 IF IN(4)=1 GOTO 50

200 OUT 11,0
210 LET W,W+2
220 IF W<30 GOTO 50

230 OUT 11,-1
300 BEEP 5,60
310 GOTO 30

【プログラム説明】
10行目 変数Nを初期化。最初にLEDを点灯する位置をいれる(0~5)。
20行目 N番目のLEDを点灯する。
30行目 ボタン1が押されるのを待つ。ここがスタートボタン待ち。
40行目 変数Wを初期化。WにはLEDの点灯時間が入る。1が最も早い。

50行目 N番目のLEDを点灯する。
60行目 音を鳴らす。LEDが1つ動くごとに鳴る。
70行目 LED点灯待ち時間。W値の分だけ点灯。
80行目 Nの値を1つプラス。
90行目 もし、Nが6なら Nに0を入れる。
     これでルーレットが一周したことになる。
100行目 ボタン4が押されていなければ、GOTO50へ飛んで次のLEDを点灯。

200行目 IN4をOUTポート(OUT11)に変更して0を出力。
     こうするとIN4の値は常に0となり、
     ボタンを押したままと同じ状態になる。
210行目 WAIT値のWを少し増やす。だんだんゆっくりになる。
220行目 WAIT値Wが30以下なら、GOTO50

230行目 IN4をOUTポートからINポートに戻す。
300行目 ルーレットが停止した合図(BEEP)を鳴らす。

【応用】
・逆回りに光らせたいときは、20行目と50行目をつぎのようにします。
  OUT 1<<(5-N)
   または
  OUT 32>>N

・220行目をつぎのようにかえると、ルーレットの止まり方が毎回変わります。
  IF W<20+R GOTO 50 ELSE LET R,RND(20)

【参考】1行だけのプログラムでLEDをルーレットのように光らせる方法

例1 10 OUT 1<<(TICK()/2%6):IF IN(4)=1 CONT
例2 10 OUT 1<<(TICK()%60):IF IN(4)=1 CONT
例3 10 T=TICK():OUT 1+T/10%6,T/60%2:IF IN(4)=1 CONT ELSE OUT 1<<(TICK()/2%6)
例4 10 OUT TICK()/60%2*255:IF IN(4)=1 CONT ELSE OUT 1<<(TICK()/2%6)
例5 10 OUT 1<<(TICK()/2%6):IF !BTN() CONT ELSE WAIT180:CONT
  (逆回転にするなら、OUT 32>>(TICK()/2%6)に替える)

【機能変更したサンプルプログラム】
・どのボタンでもスタート&ストップ
・右回り回転
・ストップボタンで止まるタイミングも変化
・止まったLEDを点滅

1 ‘HEART*6ルーレット v1.05 by NEXTDAY
10 @START
20 W=2: N=0: R=10

30 @LOOP
40 BEEP 100
50 N=N+1: IF N>5 N=0
55 ? N,W,BIN$(32>>N,6),IN(4),IN(3),IN(2),IN(1)
60 OUT 32>>N: WAIT W
70 GSB @SW(S)
80 IF !S GOTO @LOOP

90 P=0: GSB @PORT(P)
100 W=W+2
110 IF W<20+R GOTO @LOOP

120 R=RND(30)
130 P=-1: GSB @PORT(P)
140 BEEP 5,60
150 GSB @SW(S): IF S CONT
160 FOR S=0 TO 1
170 OUT 6-N,TICK()/30%2
180 GSB @SW(S)
190 NEXT
200 GSB @SW(S): IF S CONT
210 GOTO @START

1000 @SW(S):S=!IN(4)*8+!IN(3)*4+!IN(2)*2+!IN(1):RTN
2000 @PORT(P):OUT8,P:OUT9,P:OUT10,P:OUT11,P:RTN