フォト
無料ブログはココログ

IchigoJam

2015年11月17日 (火)

IchigoJam(10) <8x8LEDを光センサーにする>

 飽きもしないでIchigoJamと8x8マトリクスLEDで遊んでいる。

 一度試してみようと思いながら先送りしていた、LEDを光センサーとして使うアイディアを試してみた。このアイディアをは古くからあって、初めて読んだのはエレクトロニクスライフと記憶している。

 その他にも

に実装例がある。

 IchigoJamはVer1.1b5から、ポートの出力、入力を切り替えられるようになったので、IchigoJamと8X8マトリクスLEDでやってみた。 IchigoJam(8) <8x8LED>IchigoJam(9) <8x8LEDで8Qeen問題>で使用したハードウェア使う。

 表示しながら、LEDをスイッチ代わりに使える。(はずだ。)

Ichigo8x8sensor

基本動作は

OUT 1,-1 : '入力ポートに切り替える
A=ANA(5): '電圧を読む
OUT 1,0   : '出力ポートに切り替える

で、光が当たっているときと指で光を遮ったときで読み取った電圧に差が生じるはずである。

↓のようなプログラムを作って試してみると、ちゃんと変化が読み取れた。

1 'Nov.2015/Yoshi
1 'LED Senser Test
10 GOSUB 1000

100 FOR P=1 TO 2
110  M=#7FFF: X=0
120  A=0: OUT P,-1: FOR I=0 TO 19: [I]=ANA(P+4): NEXT
130  FOR I=0 TO 19
140   IF [I]<M M=[I]
150   IF X<[I] X=[I]
160   A=A+[I]
170  NEXT
180  ?"ANA(";P+4;") MIN:";M,"MAX:";X,"AVE:";A/20
190 NEXT
199 END

1000 'Initialize
1000 VIDEO 0
1020 OUT 8,0: OUT 9,0: OUT 10,0: OUT 11,0
1100 RETURN
list

run
ANA(5) MIN:57   MAX:78  AVE:65   
ANA(6) MIN:48   MAX:84  AVE:63

run
ANA(5) MIN:0    MAX:18  AVE:3
ANA(6) MIN:0    MAX:35  AVE:10

run
ANA(5) MIN:2    MAX:34  AVE:18
ANA(6) MIN:22   MAX:77  AVE:44

上から

  • 隠していない状態(8個のLEDに光が当たっている)
  • 全て隠した状態(8個のLEDに光が当たっていない)
  • 半分隠した状態(4個のLEDに光が当たっている)

 マトリクスLEDは1列のLEDのアノード側が繋がっているので、隠したLEDの数によって電圧に差が出ている。 IchigoJamの速度では隠した列の判定はできるが、座標まで特定するのは難しそうだ。

 ということで、指で触れると表示がカウントアップするプログラムを書いてみた。

1 'Nov.2015/Yoshi
1 'LED Senser Demo
10 GOSUB 500

100 'Main loop
100 I=(I+1)&7: OUT (I<<8)|[I+C]: GOSUB P: GOTO 100

200 '
200 OUT 1,-1: L=L+ANA(5): OUT 1,0: IF J=7 GOTO 280
201 GOTO 290
210 OUT 2,-1: R=R+ANA(6): OUT 2,0: IF J=15 GOTO 280
211 GOTO 290
220 L=L>>3: R=R>>3: IF D=1 GSB 700
221 GOTO 280
230 IF L<T AND U<R C=(C+8)%80: GOTO 270
231 GOTO 280
240 IF T<L AND R<U C=(C+72)%80: GOTO 270
241 GOTO 280
250 J=J+1: IF J<100 RTN
260 J=0: L=0: R=0: P=200: RTN
270 P=250: BEEP: RTN
280 P=P+10
290 J=J+1: RTN

500 'Initialize
500 VIDEO 0: FOR I=8 TO 11: OUT I,0: NEXT: CLV: P=200
510 D=1: T=55: U=40
510 T=55: U=40

600 'bit pattern
600 LET[0],#00,#3C,#E4,#EC,#F4,#E4,#E4,#3C
610 LET[8],#00,#18,#18,#38,#18,#18,#18,#FC
620 LET[16],#00,#3C,#E4,#84,#0C,#30,#60,#FC
630 LET[24],#00,#3C,#E4,#84,#1C,#84,#E4,#3C
640 LET[32],#00,#0C,#1C,#3C,#4C,#FC,#0C,#0C
650 LET[40],#00,#FC,#60,#7C,#84,#84,#E4,#3C
660 LET[48],#00,#3C,#E4,#60,#7C,#E4,#E4,#3C
670 LET[56],#00,#FC,#E4,#0C,#18,#18,#18,#18
680 LET[64],#00,#3C,#E4,#E4,#3C,#E4,#E4,#3C
690 LET[72],#00,#3C,#E4,#E4,#BC,#84,#E4,#3C
699 RETURN

700 'debug
700 ?"L:";L,"R:";R: RTN
list

 8x8LEDの両端の列を表示用兼光センサとして使っている。片方の端はOUT 1に繋がっているのでOUT 1、ANA(5)で使える。もう片方の列は OUT 8に繋がっているので ANA(1)で使えるのかと思ったが使えないようなので、OUT 2とOUT 8を入れ替えている。

 数字を表示する合間にLEDの電圧を読んでいる。ばらつきがあるので8回読んで平均を取るようにした。

 510行目のTとUが閾値だ。D=1を指定すると、電圧を表示するので、ちゃんと動くようにTとUの値を指定しなければならない。(VIDEO 0なのでシリアルで確認する)

Ichigo8x8sensor_2
ダウンロード Ichigo8x8Sensor1M.avi (981.6K)

 LEDを光センサとして使っているので周囲の明るさで読み取る電圧が変化する。ちゃんと使えるようにするには周囲の明るさに合わせて閾値を自動的に変化させる工夫が必要だ。


2015年11月10日 (火)

IchigoJam(9) <8x8LEDで8Qeen問題>

IchigoJamだけで8x8マトリクスLEDが表示できるようになった(IchigoJam,(8) <8x8LED>(2015/10/))
BASICではダイナミック表示に必要な処理速度が足りないようで、スクロールさせるだけでもチラつきがある。

 ダイナミック表示+何かの処理ができると簡単なゲームならIchigoJamだけでできるのではないかと考え、8Queen問題を解きながら8x8LEDのダイナミック表示ができるかやってみた。

 8Qeen問題はチェス盤(8x8)の上にQueen(将棋の飛車と角を合わせた動きができる駒)を、互いに進路を邪魔しないように配置する問題だ。これを解くプログラムをFORループで書くとこんな感じだ。→(IchigoJam BASICのFOR/NEXT(2)(2015/04/07))

 FORループの中でLEDの表示(OUT xx)を行うと、処理によってOUT命令の間隔が変わるのでチラつきが激しくなるだろう。

 そこで、考え方を変えて、8Queenを解くルーチンを分割して、メインループ(100行)でLEDの表示を行い、合間に分割したルーチンを順次呼び出す方式にした。

1 '8Queen for IchigoJam 
2 'Oct. 2015/Yoshi
3 GOSUB 1000

100 'Main loop
100 N=(N+1)&7: OUT (N<<8)|[N]: GOSUB P: GOTO 100

200 IF [I]=X GOTO 420 ELSE GOTO 410
210 IF [I]=X>>(Y-I) GOTO 420 ELSE GOTO 410
220 IF [I]=X<<(Y-I) GOTO 420 ELSE GOTO 410
230 'CHK OK
230 I=I+1: IF I<Y GOTO 400 ELSE GOTO 410
240 X=1: I=0: GOTO 410
250 Y=Y+1: [Y]=X: IF Y=8 GOTO 430 ELSE GOTO 400
260 'CHK NG
260 X=X<<1: IF X=#100 [Y]=0: Y=Y-1: X=[Y]: RETURN ELSE GOTO 410
270 [Y]=X: I=0: GOTO 400

400 P=200: RETURN
410 P=P+10: RETURN
420 P=260: RETURN
430 P=430: IF BTN()=1 Y=7: GOTO 420 ELSE RETURN

900 'Print table
900 PRINT
910 FOR J=0 TO 7
920  FOR K=0 TO 7
930   IF [J]&(1<<K)=0 ?" "; ELSE ?"Q";
940   ?"|";
950  NEXT: ?
960 NEXT
970 RETURN

1000 'Initialize
1000 OUT 8,0: OUT 9,0: OUT 10,0: OUT 11,0
1010 VIDEO 0: CLV
1020 [0]=1
1030 Y=0: X=1: I=0: N=0: R=0: P=250
1100 RETURN
list

 8Queenを解くルーチン(200行~270行)は、駒を置こうとする座標(X,Y) 既に置いた駒が進路にあるかを調べている行(I)、置けるか置けないかの判定(R)によって処理が決まるので、X,Y,I,Rを保存してあれば処理を分割することが可能だ。

 メインループ(100行目)の(GOSUB P)で分割している処理を順次呼び出す。分割された処理からRETURNする前に、次に呼び出す行番号を更新している。

Ichigo8x88q千石の袋はフィルタ代わり(^^;
リンク先に(Ichigo8x88Q.avi (2,031KB)) サイト外に接続します


2015年11月 4日 (水)

IchigoJam(8) <8x8LED>

IchigoJamだけでダイナミック表示ができたので8x8マトリクスLEDを点けてみた。

Ichigo8x8led

 IchigoJamの出力ポートはOUT1~OUT11の11本しかないので、OUT1~OUT8をマトリクスLEDのR1~R8に接続して、カラム側は74HC138(3-8Decoder)を使ってOUT9~OUT11でC1~C8をドライブする。R1~R8は0Ωに(直結)した。LEDが転倒する数によって明るさが違う。

 C1~C7を駆動する74HC138の出力は負論理なので、例えば入力が"101"ならば出力Y4に"L"が出力される。したがってR1~R7は正論理で駆動すればよい。

 例えば、2列目に「○●○●●○●○」(C1→C8、○ON、●OFF)のパターンを表示する場合、OUT #2A5 とする。

 とりあえずテストプログラムを書いてみた。4つのパターンで点灯する。

  1. 順に点灯
  2. 渦巻き
  3. ランダム
  4. 反射

1 '8x8LED TEST
10 GOSUB 1000
20 GOSUB 100: GOSUB 200: GOSUB 300: GOSUB 400
30 FOR Z=0 TO 4
40  R=RND(4): R=(R+1)*100: GOSUB R
50 NEXT
90 END

100 'ALL LED ZigZag
100 FOR Y=0 TO 7
110  IF Y%2=0 T=0: E=7: S=1 ELSE T=7: E=0: S=-1
120  FOR X=T TO E STEP S
130   GOSUB 900
140  NEXT
150 NEXT
160 RETURN

200 'Spilal
200 X=0:
210 FOR A=0 TO 3: B=7-A
220  FOR Y=A TO B: GOSUB 900: NEXT
230  FOR X=X+1 TO B : GOSUB 900: NEXT
240  FOR Y=Y-1 TO A STEP -1: GOSUB 900: NEXT
250  IF A<3 FOR X=X-1 TO A+1 STEP -1: GOSUB 900: NEXT
260 NEXT 
270 RETURN

300 'Random
300 FOR P=0 TO 63
310  R=RND(63): Y=R/8: X=R%8: GOSUB 900
320 NEXT
330 RETURN

400 'Reflect
400 A=1: B=2: X=3: Y=4
410 FOR P=0 TO 63
420  GOSUB 900
430  X=X+A: Y=Y+B
440  IF X<0 X=0: A=RND(2): A=A+1: GOTO 460
450  IF 7<X X=7: A=-A
460  IF Y<0 Y=0: B=RND(2): B=B+1: GOTO 480
470  IF 7<Y Y=7: B=-B
480 NEXT
490 RETURN

900 'LED(X,Y) ON
900 OUT (X<<8)|(1<<Y): WAIT 5: RETURN

1000 'Initialize
1000 FOR I=8 TO 11: OUT I,0: NEXT
1100 RETURN
LIST

Ichigo8x8ledtest
↑リンク先に Ichigo8x8LEDtest.avi (999.2K)

↑はLEDの同時点灯数1個だから簡単だ。結構簡単にできたので 気をよくして、パターンを表示させてみた。

1 '8x8LED display
2 'NOV. 2015/ Yoshi
10 GOSUB 1000: GOSUB 1200

100 'Main loop
100 I=I+1: J=(I&7): D=(I&T)>>5: OUT (J<<8)|[D+J]: IF I&#1FF=0 GOSUB 500
110 GOTO 100

500 'button
500 IF BTN()=0 B=0: RETURN
510 'ELSE
510  P=P+1: IF P=2 P=0
520  IF P=0 T=#3E0: GOTO 540
530  IF P=1 T=#700: GOTO 540
540  IF B=0 B=1: BEEP: ELSE END
550 RETURN

1000 'Initialize
1000 CLV: VIDEO 0
1010 V=60: N=V: P=1: S=0: T=#700
1020 OUT 8,0: OUT 9,0: OUT 10,0: OUT 11,0
1030 CLT
1100 RETURN

1200 'Bit pattern
1200 LET [0],#00,#03,#0F,#1C,#F8,#F0,#0C,#03
1210 LET [8],#00,#3C,#7E,#FF,#81,#C3,#7E,#3C
1220 LET [16],#00,#46,#8F,#9F,#B9,#F9,#F1,#62
1230 LET [24],#00,#FF,#FF,#FF,#18,#18,#FF,#FF
1240 LET [32],#00,#00,#81,#FF,#FF,#FF,#81,#00
1250 LET [40],#00,#88,#58,#7C,#3F,#7C,#58,#88
1300 RETURN
LIST

1200行から1250行までが表示パターン。

例えば、1200行は、配列[0]~[7]に"Y"のパターンを格納している。

[0][1][2][3][4][5][6][7]
・ ○ ○ ・ ・ ・ ・ ○ 01h
・ ○ ○ ・ ・ ・ ・ ○ 02h
・ ・ ○ ○ ・ ・ ○ ・ 04h
・ ・ ○ ○ ○ ・ ○ ・ 08h
・ ・ ・ ○ ○ ○ ・ ・ 10h
・ ・ ・ ・ ○ ○ ・ ・ 20h
・ ・ ・ ・ ○ ○ ・ ・ 30h
・ ・ ・ ・ ○ ○ ・ ・ 40h
00 03 0F 1C F8 F0 0C 03

のように格納してある。

 メインループ(100行110行)を、どれだけ速く書くかでチラつきかたが変わってくる。(もう少し速くなるかも) 効果があるのは行数を減らすことだった。

Ichigo8x8leddisp
↑リンク先に Ichigo8x8LEDdisp.avi (900.5K)

 さすがにチラつくなあ。ビデオではわからないけどLEDの点灯数で明るさが違うのが、はっきり分かる。

メインループを早くするアイディア

  • 74HC138(3-8Decoder)でなく74HC4017(JohnsonCounter)を使う
  • 配列アクセスをPOKEに変える

くらいかなあ。

 タイマー割り込みが欲しい。


2015年11月 2日 (月)

勉強会

ゆるい勉強会に参加した。

 今回の発表は、

  • API Hook
  • Drone
  • Maker Fire&IchigoJam
  • Windows10 IoTCore
  • いいろなSecurity Conferenceにいってみた
  • FPGA入門

など、難しい話から軽い話まで。

 展示もあった。
chigoJamを使ってキーボートを押すと前進・後退、回転できる。
Photo

 息子さんの夏休みの自由研究らしい。(「大きいお友達」の影が見えるのは気のせい?)
今時の自由研究はIchigoJamなんだ。将来が楽しみだね。

 ちなみにこの台車(タミヤ、ロボクラフトシリーズNo7)はミニヘボコンで優勝したときに使ったものだって。

2015年10月19日 (月)

IchigoJam(7) 

IchigoJam Ver1.1 beta6 で IN1~IN4をOUT8~OUT11で使えるようになったらしい。

IchigoJam(6) <4桁ダイナミック表示>(2015/10/13) で作った4桁LED時計はVer1.1 beta5で作った。出力ポートがOUT1~OUT7の7本しかなかったので、桁ドライブ用に74HC4017を使った。
 OUT8~OUT11が使えるなら、新たに使えるようななった出力ポートを桁ドライブ用に使用するとちょうどよい。

Ichigojamclockd8

シンプルになった。

 プログラムの変更が少なくなるように、OUT8~OUT11を桁ドライブに使用すると3桁目(OUT10)が点灯しない。?_?)  出力電圧を測ってみると1.7vしか出ていない。配線を間違えたかと確認したが、間違えていない。

 IchigoJamの回路図を眺めたら気がついた。OUT10(IN3)はI2CのSDAだ。I2CバスはOpenDrainでドライブするので、IN3をOUT10で使った場合は当然OD出力となる。(データシートにも書いてある)

 ODは"L"を出力(電流吸込み)できるが、"H"は出力(電流吐出し)できないないので、プルアップ抵抗で"H"にする。
ところが、桁ドライブは電流を吐出さなければならないので、LEDを点灯させることができない。

 カソードコモンの7SegLEDを使おうかとも考えたが、安易に、OUT1~OUT4を桁ドライブに使用して、OUT5~OUT11をセグメントドライブに使用するように変えた。(赤色が変更した行)

1 'IchigoClock / dynamic lighting use OUT8-11
2 'Oct. 2015 / Yoshi
3 GOSUB 700

100 'Main loop
100 T=TICK(): IF BTN()=1 GOSUB 600 ELSE B=0
110  IF R=1 AND V<T GOTO 180
120  IF T<N GOTO 180
130   N=(N+D)&#7FFF: IF N<T THEN R=1 ELSE R=0
140   M=M+1: IF M<60 GOTO 160
150    M=0: H=H+1: IF 24<=H THEN H=0
160   [0]=[10+H/10]|8: [1]=[10+H%10]|4:
165   [2]=[10+M/10]|2: [3]=[10+M%10]|1

170   IF X=1 GOSUB 1000
180  I=I+1: OUT [I&3]
200 GOTO 100

600 'Button push
600 IF B=0 THEN B=T
610 IF E+B<T THEN END
620 IF B+K<T THEN D=J: N=TICK(): GOTO 650
630 IF D=J THEN D=V: N=TICK()+D: GOTO 650
640 IF T=B+J THEN D=V: N=TICK()
650 RETURN

700 'Initialize
700 [10]=#400: [11]=#790: [12]=#240: [13]=#300: [14]=#190
710 [15]=#120: [16]=#020: [17]=#780: [18]=#000: [19]=#100

730 V=3610: X=0
740 J=40: K=J*5: E=J*25
750 Z=0: F=#FF: R=0: D=V: N=D
760 OUT 8,0: OUT 9,0: OUT 10,0 OUT 11,0
770 H=23: M=50: [0]=[12]|8: [1]=[13]|4: [2]=[15]|2: [3]=[10]|1

780 VIDEO 0: CLT
880 RETURN

1000 'Send serial
1000 ? CHR$(13); H/10; H%10; ":"; M/10; M%10;
1010 RETURN
list

↓こんな感じ
 IchigoJam(6) <4桁ダイナミック表示>(2015/10/13)にあった74HC4017が無い。Ichigoclockdynamic2
↑リンク先にAVI(IchigoClockDynamic2.avi (1020.9K))

 動画は明るく見えるけど、蛍光灯の真下では見えないくらい暗い。

 R1~R8を0Ωにする(IchigoDotのように直結する)、つまりLPC1114のOUT5~OUT11を直接LEDに繋ぐと蛍光灯の下でも見えるくらい明るくなる。

 教科書にはLEDは必ず電流制限用の抵抗が必要と書いてあるが、マイコンのI/OでLEDを駆動する場合には直結することも可能だ。

 電流制限用の抵抗を省略しているわけではなく、I/Oポートには内部抵抗があるので電流が制限される。データーシートで出力電流と出力電圧の特性を確認すると、

Voliol Vohioh

 Fig38はI/Oピンに"L"を出力(OUT4,0 etc.)したときの電圧と電流の関係だ。I/Oピンに電流を吸い込むとI/Oピンの電圧が上がる。つまり内部に抵抗がある。

 一方Fig39はI/Oピンに"H"を出力(OUT1,1)したときの電圧と電流の関係だ。I/Oポートから出力する電流が増えると、出力電圧が下がる。つまり内部に抵抗がある。

 そして、LEDに流す電流とLEDの電圧降下の特性もデータシートで確認すると
Ifvf

 LEDは流れる電流で順方向の降下電圧が異なる。教科書で見かけるLEDの順方向降下電圧2.0vは20mA流したときの値だ。

 マイコンのI/Oポート直結でLEDを点灯するときは↓のような回路になっている。

Leddrive1

つまり、VoH=VoL+Vfになるように電流が流れる。

 "8"を表示(LEDが7個点灯)したときは、LEDに2.5mAくらい電流が流れる。また、"1"を表示(LEDが2個点灯)したときは、LEDに3mAくらい電流が流れる。

 OUT1は点灯しているLEDの電流を全て吐き出しているので、点灯しているLEDの個数で降下する電圧が異なり、点灯しているLEDを流れる電流が変わる。2.5mAと3mAの変化は見た目にはわからない。

 "H"を出力したときの内部抵抗 Rohより、"L"を出力したときの内部抵抗 Rolのほうが値が小さいので、カソードコモンの7セグLEDを使うとより電流が流せることになる。

 カソードコモンの7セグLEDを使うと5mAくらい流せるので明るくなる。


2015年10月13日 (火)

IchigoJam(6) <4桁時計ダイナミック表示>

IchigoJamで4桁時計を作った。( IchigoJam(5) (2015/9/24))

 スタティック表示だから、大した苦労もなく作れた。使った表示器はHDSP0760(Latch+Decoder+Driver+LED)という表示器で一般的ではない。

 普通の7セグLEDを使って、ダイナミック表示でもできるのではと思い立ったので早速作ってみた。

 4511(BCD-to-Seven Segment Latch/Decoder/Driver)と74HC139(2-4Decoder)の組み合わせはわかりやすい。

Ichigoclockd

 IchigoJamのOUT1~OUT7(LED)でLEDのa~gを駆動すると 4511(7SegDecoder)は 省略できそうだ。

Ichigoclockd2

 桁ドライブには74HC4017(JohnsonCounter)を使う。

 74HC4017(JohnsonCounter)はカウントパルスが入力されると、順番にQ0~Qnに"H"が出力される。上の回路では、Q4をRESETに繋いであるので、Q0→Q1→Q2→Q3→Q0→Q1・・・のように循環して出力される。 "H"が出力された桁に、OUT1~OUT7に数字のパターンを出力すると4桁表示できる。

 74HC4017のデータシートによると出力電流は25mAなので、コモン側のドライバを省略してみる。CD4017は出力電流が取れないのでドライブ用のトランジスタが必要だ。(点線の中の図)

 a~gまでの全てのセグメントが点灯した場合は、それぞれのセグメントに25mA/7≒3.6mA流れることになる。最近のLEDは3.6mAも流すと室内では十分な明るさで光る。 しかし、それはスタティック表示の場合だ。

 4桁のダイナミック表示なので、点灯している時間は全体の1/4だから、平均電流は3.6mA/4=0.9mAだ。さすがに0.9mAは少ないなあ。でも、トランジスタのドラバを入れると部品が増えるしなあ...まあやってみよう。

 IchigoJamの出力はOUT1~OUT7で、これをLEDのa~gに使うと、74HC4017のカウントパルスに使える出力がないので、D1,D2,R8でORを構成してカウントパルスを作る。

 OUT2,OUT3は7セグLEDの"b","c"に繋がっている。この7セグLEDはアノードコモンだからOUT1~OUT7(LED)に出力するパターンは

: gfedcba
0 : 1 0 0 0 0 0 0 : #40
1 : 1 1 1 1 0 0 1 : #79
2 : 0 1 0 0 1 0 0 : #24
3 : 0 1 1 0 0 0 1 : #30
4 : 0 0 1 1 0 0 1 : #19
5 : 0 0 1 0 0 1 0 : #12
6 : 0 0 0 0 0 1 0 : #02
7 : 1 1 1 1 0 0 0 : #78
8 : 0 0 0 0 0 0 0 : #00
9 : 0 0 1 0 0 0 0 : #10

"b","c"をよく見ると、"0"~"9"のどのパターンを表示したときでも、"b","c"どちらかが"0"である。そして、"b"はD1、"c"はD2を経由してHC4017の13ピンに繋がっているので、表示中は、HC4017の13ピン CKE は"L"になる。

 隣の桁を表示する前に、一旦、OUT1~OUT7を全て"H"(OUT #FF )にすると、HC4017の CKE は"H"になる。

 そして、次の桁の数字を表示したときに再び"L"に戻るので、カウンターが進みLEDの次の桁に"H"が供給され、同時にOUT1~OUT7(a~g)に数字のパターンが出力されているので、無事次の桁に数字が表示される。

 つまり、次の桁の数字を表示する前に、OUT #FF を実行すればよい。(170行)

プログラムは↓こんな感じ。

1 'IchigoJam 4Digit clock / dynamic lighting
2 'Aug. 2015 / Yoshi
3 GOSUB 700

100 'Main loop
100 T=TICK(): IF BTN()=1 GOSUB 600 ELSE B=0
110 IF R=1 AND V<T GOTO 170
120 IF T<N GOTO 170
130  N=(N+D)&#7FFF: IF N<T THEN R=1 ELSE R=0
140  GOSUB 800: M=M+1: IF M<60 GOTO 160
150  M=0: H=H+1: IF 24<=H THEN H=0
160  [0]=[10+H/10]: [1]=[10+H%10]: [2]=[10+M/10]: [3]=[10+M%10]
170 I=I+1: OUT F: OUT [I&3]
190 IF X=1 GOSUB 1000
200 GOTO 100

600 'Button push
600 IF B=0 THEN B=T
610 IF E+B<T THEN END
620 IF T<B+K GOTO 640
630  D=J: N=TICK(): GOTO 680
640 IF D<>J GOTO 660
650  D=V: N=TICK()+D: GOTO 680
660 IF T<>B+J GOTO 680
670  D=V: N=TICK():
680 RETURN

700 'Initialize
700 [10]=#40: [11]=#79: [12]=#24: [13]=#30: [14]=#19
710 [15]=#12: [16]=#02: [17]=#78: [18]=#00: [19]=#10
730 V=3610: ' X=0
740 J=40: K=J*5: E=J*25
750 Z=0: F=#FF: R=0: D=V: N=D
760 H=23: M=50: [0]=[12]: [1]=[13]: [2]=[15]: [3]=[10]
770 VIDEO 0: CLT

800 'Align Digit
800 FOR I=0 TO 3
810  OUT F: OUT 0: IF IN(1)=1 THEN I=3
820 NEXT
830 RETURN

1000 'Send serial
1000 ? CHR$(13); H/10; H%10; ":"; M/10; M%10;
1010 RETURN

時計をダイナミック表示するプログラムは、メインルーチンで、

  • 時間の計測
  • 時刻のカウントアップ(分は60進数、時は24/12進数)
  • ボタンの取得
  • 時刻あわせ処理

を行い。表示には割り込みを使うと、メインルーチンの処理が重くなってもチラつかない。

 IchigoJam BASICは割り込みが使えないので、全てメインルーチンで処理しなくてはならない。時刻のカウントアップは処理が増えるのでチラつくが、60秒に1回しか実行しないので気にならないだろう。また、ボタンを押すと、時刻あわせ処理が実行されるのでループ1回の処理時間が長くなりチラつく。 常時ボタンを押しているわけではないので良しとしよう。

 こんな感じ↓
Ichigoclockdynamic

↑リンク先にAVI (http://yoshi-s.cocolog-nifty.com/cpu/files/IchigoClockDynamic.avi)

 BASICは遅いという先入観があって、本当にダイナミック表示できるのだろうかと思っていたが、それほどチラつきもなくできてしまった。CortexM0 48MHzだから当然か?

 8x8マトリクスLEDもIchigoJamだけで表示できそうな気がしてきたが、出力ポートが足りない。

 OUT 8、OUT 9で入力ポートが出力ポートになればいいのになあ。

と書いたら、Ver1.1 beta 6でIN 1~IN 4がOUT 8~OUT 11に割り当て可能になったようだ。


2015年9月24日 (木)

IchigoJam(5)

 ヤフオクでLEDディスプレイ(HDSP0670)を手に入れた。 HDSP0760(2) (2015/09/24)HDSP0760 (2015/09/22)   16進数表示と勘違いしていたので、何かに使わないと死蔵してしまいそうだ。

 このディスプレイがあると、IchigoJamでも簡単に時計が作れると思い立ち、さっそく作ってみた。

 IchigoJamの出力は、OUT1~OUT6、LEDの7つしかない。HDSP0760は、Latch+Decoder+Driver+LEDなので、表示データを保持するためにLE(LatchEnable)入力が必要だ。LEの制御にLEDを使い、OUT1~OUT4を表示する数値に使うと残りは、OUT5、OUT6だ。
OUT5、OUT6で4桁を制御しようとすると、2to4のデコーダー(74139)が必要だ。

 HDSP0760は5V-TTLでIchigoJamに使用されているLPC1114FN28は3.3V-CMOSなので、IchigoJam→HDSP0760方向は直結できる。2-4Decoder(74139)は、入力レベルがTTLの74HCT139を使用する。

Ichigoclock4

 ブレッドボードで作ってみた。↓
4digitclock
リンク先にAVI (4DigitClock.avi  1008.8K) (1秒でカウントするモードで撮影)

 IchigoJamのTICK()は1/60sなので0~#7FFFは9分でカウントアップする。ちょっと工夫が必要だ。(100、130、135行)
 時刻設定はIchigoJamに乗っているSW(BTN)を使った。1個のSWで時刻を合わせるのは大変だ。(600~710行)

  • 1秒押す         →1分増
  • 3秒以上押す →早送りその後自動的に増加
  • 17秒以上押す→プログラム終了

のようにした。(600~710行)

1 '4Digit Clock
2 'Aug.2015/Yoshi / Ver2.0
3 VIDEO 0: CLV: LED 1
4 V=3600: F=0
5 H=23: M=50
6 N=V: D=V
7 GOSUB 500: GOSUB 520: CLT

95 'Main loop
100 IF W=1 AND N<TICK() GOTO 100
110  IF BTN()=1 THEN GOSUB 600 ELSE G=0
120  T=TICK(): IF T<N GOTO 110
130  N=N+D: IF N<0 N=N&#7FFF
140  IF N<T THEN W=1 ELSE W=0
150  M=M+B: IF M<60 GOTO 180
160   M=0: H=H+1: IF 24<=H H=0
170   GOSUB 520
180   GOSUB 500
190 IF F=1 GOSUB 900
200 GOTO 100

495 'Disp LED
500 OUT M%10: LED 0: LED 1
510 OUT #10+M/10: LED 0: LED 1: RETURN
520 OUT #20+H%10: LED 0: LED 1
530 OUT #30+H/10: LED 0: LED 1: RETURN

595 'Push Button
600 IF G=0 G=T
610 IF 1000+G<T END
620 IF T<240+G GOTO 640
630  D=40: N=TICK(): GOTO 710
640 IF T<>30+G GOTO 710
650 IF D=40 GOTO 700
660  M=M+1: IF M<60 GOTO 690
670   M=0: H=H+1: IF 24<=H H=0
680   GOSUB 520
690  GOSUB 500
700 D=V: N=TICK()+D
710 RETURN

895 'Send Serial
900 [0]=M%10: [1]=M/10:
910 [2]=H%10: [3]=H/10:
920 ? CHR$(13); [3]; [2]; ":"; [1]; [0];
930 RETURN

6時間で1分くらい進む。このIchigoJamそっくりさんはX'tal付きなんだけどなあ。

1日で4分くらい進んでいたので、4/60*24=1/360余分にカウントするようにした(D=3600→D=3610)日差+20秒になった。(2015/09/27追記)

 


 

娘に見せると、毎度のことだけど、
  娘  :「なに作ってるの?」
σ^^):「時計」
  娘  :「時計作ってどうするの?」
σ^^):「時間を見る」
  娘  :「時計って1個あればいいじゃん」
σ^^):「うん~...」


2015年6月 1日 (月)

IchigoJam(4) <メモリダンプ・プログラム>

 IchigoJam BASICはPEEK()が使えるようなのでメモリダンププログラムを書いてみた。 HEX$()CHR$()があるので楽だ。

1 'Memory dump
2 ' May. 2015 / Yoshi
10 INPUT "Dump address:?", A
20 INPUT "Length:?", L
30 IF L=0 THEN L=256 
40 IF (L%16)<>0 THEN L=(L/16+1)*16

100 FOR I=A TO A+L-1
110   IF (I%256)=0 THEN PRINT "     +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F"
120   IF (I%16)=0 THEN PRINT HEX$(I,4);" ";
130   C=PEEK(I)
140   IF ASC(" ")<=C AND C<=ASC("~") THEN [I%16]=C ELSE [I%16]=ASC(".")
150   PRINT HEX$(C,2);" ";
160   IF (I%16)<>15 THEN GOTO 210
170     FOR J=0 TO 15
180       PRINT CHR$([J]);
190     NEXT
200     PRINT
210   REM ENDIF
220 NEXT
230 END

ちょっと丁寧に書いてみた。^^)
メモリダンプ見てると萌えるねえ...

###

 IchigoJamの作者のページ「福野泰介の一日一創」に「IchigoJamのメモリマップと演算子優先順位」というエントリがあってIchigoJamのメモリマップが公開されている。これを見るとPEEK()で見えるアドレスは仮想的なアドレスのようだ。

 やっぱりRAM(実アドレス、0x10000000~)の中を見たい!
 USR()で機械語ルーチンをコールできるようなので、PEEK()の代わりにUSR()でRAMの実アドレスを読むようにすればよさそうだ。

 しかし!、ARMのアセンブラなど書きたくない!!、しかもthumb命令だし!!

 IchigoJamのUSR()は引数をR0レジスタで渡して戻り値をR0で受け取るらしいので、機械語への翻訳はgccにお願いすることにしよう。

uint16_t peek_ex(uint16_t addr)
{
    return *(uint8_t*)(0x10000000+addr);
}

のような関数を書いてgccでコンパイルしてobjdumpで逆汗とすると

$ arm-none-eabi-gcc -c -Os -mthumb -mlittle-endian -mno-unaligned-access
$ arm-none-eabi-objdump -d dump.o

00000000 <peek_ex>:
   0:   4b01            ldr     r3, [pc, #4]    ; (8 <peek_ex+0x8>)
   2:   5cc0            ldrb    r0, [r0, r3]
   4:   4770            bx      lr
   6:   46c0            nop                     ; (mov r8, r8)
   8:   10000000        .word   0x10000000

が得られる。

 RAMの実アドレスのデータを読む関数は

POKE #700, #01, #4B, #C0, #5C, #70, #47, #C6, #46, #00, #00, #00, #10
D=USR(#700,A)

とすればよさそうだ。
実メモリをダンプするプログラムは

1 'Memory dump
2 ' May. 2015 / Yoshi
10 POKE #700, #01, #4B, #C0, #5C, #70, #47, #46, #C0, #00, #00, #00, #10
20 INPUT "Internal:0 RAM:1 Flash:2 APB:3 AHB:4 System:5 ?", T
30 IF T<0 OR 5<T GOTO 10
40 IF T=2 THEN POKE #70B, 0
50 IF T=3 THEN POKE #70B, #40
60 IF T=4 THEN POKE #70B, #50
70 IF T=5 THEN POKE #70B, #E0
80 INPUT "Address? ", A
90 IF 3<=T AND #1000<=A THEN POKE #70A,A>>12 : A=A>>4
100 INPUT "Length? ", L
110 IF L=0 THEN L=256
120 IF (L%16)<>0 THEN L=(L/16+1)*16

200 L=A+L-1
210 FORI=ATOL
220   IF!(I&#FF)?"    ";:FORK=0TO15:?" +";K;:NEXT:?
230   IF!(I&#F)?HEX$(I,4);" ";
240   C=PEEK(I):IFTC=USR(#700,I)
250   [I&#F]=C:IFC<32OR128<c[i&#f]=46 
260   ?HEX$(C,2);" "
270   IFI&#F=15FORJ=0TO15:?CHR$([J]);:NEXT:?
280 NEXT
290 END

ダンプ・ルーチンを最適化(分かり難く)してみた。
ソースはわかり難くなったけど、速度は目に見えて早くなったようには感じないなあ


     

2015年5月21日 (木)

IchigoJam(3) <超小型ARMマイコン基板>

IchigoJamで遊んでいると、もう少しメモリがあったいいのになと感じることがある。

 IchigoJamは28Pin-DIPのLPC1114FN28用に書いてある。LPC1114FN28のRAMは4kだが、33Pin-QFPのLPC1114FHN33のRAMは8kだ。もし、IchigoJamがLPC1114FHN33で動くならプログラム領域が増えるのではないか?

 買ったまま積んであった↓を取り出してきた。
Arm

 LPC1114FHN33/301+CP2104が載った小型基板が2枚付いている。

 IchigoJamの公式サイトの下のほうにファーム・ウエアのリンクがあって、Ver0.9.9-beta(開発途上版)が公開されていた。FacebookのIchigojam-FANにはVer1.0.0がある

 今回はVer0.9.9をFlashMagicで書いてみた。

 この基板に載ったCP2104(USB-Serial)のDTRとRTSがLPC1114FHN33のRESETとPIO0_1に接続されているので、FlashMagicがLPC1114FHN33を勝手にBootloader ISPモードにしてファームを書き込んでくれる。
Marymb

 しかし、ターミナル・ソフトが接続時にDTR、RTSをアサートすると、LPC1114FHN33のリセットがかかりっ放しになってしまう。

 TeraTermも接続時にDTR,RTSをアサートするようだ。途中でシリアルポートの設定を変えてもDTR,RTSをアサートしてしまう。

↓こんなマクロを作って、その都度実行するとリセットが解除されて動くようになった。(ハマってしまった)

setrts 0
setdtr 0

プログラム領域は増えたか確認してみると

IchigoJam 0.9.9 by @taisukef OK ?FREE() 1024 OK

そんなに甘くはないようだ。

まあBASICでLチカでもやってみるかと
Ichigojamlchika0000 ←リンク先にAVI
http://yoshi-s.cocolog-nifty.com/cpu/files/IchigoJamLchika2.avi (916.5K)

PEEKが使えるようなのでRAMをダンプしてみようか


2015年5月17日 (日)

IchigoJam(2)

 IchigoJamを作ってみた。

 トラ技のオマケ基板でもいいのだけれど、最近はんだ付けしていないので作ってみるかと。

Ichigojamex

 PS/2キーボドとディスプレイは使わないで、シリアル経由でPCをターミナルで使っているので、USB-シリアルは必須だ。トラ技のオマケ基板で使ってるMPL2303SA基板を使うことにしよう。ついでにEEPROMも載せよう。
回路図は↓

Ichigojamexsch

秋月C基板を使うと載りそうだが、これくらいの密度になると、行き当たりばったりではジャンパーだらけになりそうなので、予めPassで配線してみる。
被覆線を使わないで(同一面での交差なしで)配線してみた。

Ichigojamexpcb

 昔は、律儀に90°曲がるように配線していたが、配線密度がちょっと上がると配線できなくなる。45°配線すると楽になるが、交差しないように配線しようとすると試行錯誤が必要になる。1/2ピッチで配線すると、目視でのショート確認が大変なので、基本1/2ピッチでは配線しないようにしている。

 両面スルーホール基板を使う場合には表面配線と裏面配線が90°で交差するとスルーホール経由でショートする可能性があるので、45°配線で交差するようにしなければならない。

 CADソフトなら勝手にルーティングしてくれるけど、手配線するとパズルを解いているようで楽しい。

配線した。↓

Ichigojamexomote
Ichigojamexura

ついでにファームウエアを上げておいた。

IchigoJam BASIC 1.0.0b12 jig.jp
OK
?ver()
10012
OK
?free()
1024
OK


より以前の記事一覧