7セグメント数字表示のデジタル時計

 投稿者:山中和義  投稿日:2008年12月31日(水)09時21分11秒
  以前作った論理回路サブルーチンの一部を使って電子工作ふ~(チップの組み立て)の記述です。
!7セグメント数字表示のデジタル時計(Clock)

LET w=400 !画面の大きさ
LET h=120
SET bitmap SIZE w+1,h+1 !ドット単位にする
SET WINDOW 0,w,h,0 !クライアント座標(左上が原点)


LET S0=-1
DO
   LET t$=TIME$ !時刻をhh:mm:ss形式で得る

   LET S=VAL(t$(7:8)) !秒
   IF S<>S0 THEN !更新されたら
      LET S0=S

      LET H=VAL(t$(1:2)) !時
      LET M=VAL(t$(4:5)) !分

      CALL clock_display(INT(H/10),MOD(H,10),INT(M/10),MOD(M,10),INT(S/10),MOD(S,10))
   END IF
LOOP



!電子部品(配置と配線)

!         ↓BCD(h10,h1,m10,m1,s10,s1)
!  ┌─ データラッチ
!  │     ↓BCD
!  │   デコーダ
!  │     ↓abcdefg
!  └→ 88:88:88
!         │
!         GND
SUB clock_display(h10,h1,m10,m1,s10,s1) !表示部
   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   DRAW LED(1,GND) WITH SCALE(20)*SHIFT(155,40) !コロン
   DRAW LED(1,GND) WITH SCALE(20)*SHIFT(155,80)

   !ダイナミック点灯表示
   DRAW DRIVER7segment(h10) WITH SCALE(20)*SHIFT(50,60) !時
   DRAW DRIVER7segment(h1) WITH SCALE(20)*SHIFT(110,60)

   DRAW DRIVER7segment(m10) WITH SCALE(20)*SHIFT(200,60) !分
   DRAW DRIVER7segment(m1) WITH SCALE(20)*SHIFT(260,60)

   DRAW DRIVER7segment(s10) WITH SCALE(15)*SHIFT(320,70) !秒
   DRAW DRIVER7segment(s1) WITH SCALE(15)*SHIFT(370,70)

   SET DRAW mode explicit !ちらつき防止(終了)
END SUB

PICTURE DRIVER7segment(BCD) !7セグメント数字表示にする
   CALL DECODE7segment(BCD, Za,Zb,Zc,Zd,Ze,Zf,Zg)
   DRAW LED7segmentKwithoutDP(Za,Zb,Zc,Zd,Ze,Zf,Zg)
END PICTURE


!電子部品(上位)

SUB DECODE7segment(n, Za,Zb,Zc,Zd,Ze,Zf,Zg) !7セグメント数字表示デコーダ
   IF n=0 THEN
      LET ptn$="1111110" !abcdedfgのオン・オフ状態
   ELSEIF n=1 THEN
      LET ptn$="0110000"
   ELSEIF n=2 THEN
      LET ptn$="1101101"
   ELSEIF n=3 THEN
      LET ptn$="1111001"
   ELSEIF n=4 THEN
      LET ptn$="0110011"
   ELSEIF n=5 THEN
      LET ptn$="1011011"
   ELSEIF n=6 THEN
      LET ptn$="1011111"
   ELSEIF n=7 THEN
      LET ptn$="1110000"
   ELSEIF n=8 THEN
      LET ptn$="1111111"
   ELSEIF n=9 THEN
      LET ptn$="1111011"
   ELSE
      PRINT "不正な値です。"; n
   END IF

   LET Za=VAL(ptn$(1:1))
   LET Zb=VAL(ptn$(2:2))
   LET Zc=VAL(ptn$(3:3))
   LET Zd=VAL(ptn$(4:4))
   LET Ze=VAL(ptn$(5:5))
   LET Zf=VAL(ptn$(6:6))
   LET Zg=VAL(ptn$(7:7))
END SUB

!    --a-      配置位置
!  f|    |b
!    --g-
!  e|    |c
!    --d-
PICTURE LED7segmentKwithoutDP(a,b,c,d,e,f,g) !7セグメント数字表示器  ※カソード・コモン
   DRAW bar(a,GND) WITH SHIFT(0,-2) !※左上が原点
   DRAW bar(b,GND) WITH ROTATE(PI/2)*SHIFT(1,-1)
   DRAW bar(c,GND) WITH ROTATE(PI/2)*SHIFT(1,1)
   DRAW bar(d,GND) WITH SHIFT(0,2)
   DRAW bar(e,GND) WITH ROTATE(PI/2)*SHIFT(-1,1)
   DRAW bar(f,GND) WITH ROTATE(PI/2)*SHIFT(-1,-1)
   DRAW bar(g,GND) WITH SHIFT(0,0)
END PICTURE


!電子部品(下位)

PICTURE bar(a,k) !発光ダイオードを表示する
   IF a=1 AND k=0 THEN
      PLOT AREA: -1,-0.3; 1,-0.3; 1,0.3; -1,0.3 !点灯 ※塗り潰し
   ELSE
      PLOT LINES: -1,-0.2; 1,-0.2; 1,0.2; -1,0.2; -1,-0.2 !消灯 ※枠
   END IF
END PICTURE

PICTURE LED(a,k) !発光ダイオードを表示する
   IF a=1 AND k=0 THEN
      DRAW disk WITH SCALE(0.4) !点灯
   ELSE
      DRAW circle WITH SCALE(0.4) !消灯
   END IF
END PICTURE

END
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:SECOND  投稿日:2009年 1月 1日(木)03時00分30秒
  > No.223[元記事へ]

! 山中さんの7セグ数字で、気が付いた。ありがとうございます。
! plot_lines の、vector_fontで、PLOT TEXT を、カバーできた。
! やや長文と、やせた字形は難点ながら、時計の数字も、鏡像になった。
!
!-------------------
LET N=2
LET NN=2^N
SET WINDOW -250/NN,250/NN,250/NN,-250/NN
SET TEXT COLOR 4
SET TEXT BACKGROUND "OPAQUE"
LET φ=0
LET stp=-PI/180*6
DO
   LET t=INT(TIME)
   IF t0<>t THEN
      LET t0=t
      IF 2*PI<=ABS(φ) THEN LET stp=-stp
      LET φ=REMAINDER(φ, 2*PI) +stp
      !-----
      SET DRAW mode hidden
      CLEAR
      DRAW D4(N) WITH SHIFT(-300/2,-300/2/SQR(3))*ROTATE(φ*(-1)^N)*SCALE(1,(-1)^N)
      DRAW center WITH SHIFT(-300/2/NN,-300/2/NN/SQR(3))*ROTATE(φ)
      PLOT TEXT,AT 137/NN,-234/NN:"右クリックで停止"
      SET DRAW mode explicit
   ELSE
      WAIT DELAY 0.05 ! 省電力効果
   END IF
   MOUSE POLL mx,my,mlb,mrb
LOOP UNTIL mrb>=1 ! 右クリックで停止

PICTURE center
   SET LINE COLOR 2
   SET LINE width 2
   PLOT LINES:0,0;300/NN,0;300/2/NN,300/2/NN*SQR(3);0,0
   SET LINE width 1
   SET LINE COLOR 1
END PICTURE

!------
PICTURE D4(k)
   IF 0< k THEN
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の上
      DRAW D4(k-1) WITH SCALE(1/2,-1/2)*SHIFT(300/4,SQR(3)*300/4) ! 内側の中
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(-PI*2/3)*SHIFT(300/4,SQR(3)*300/4) !内側の左
      DRAW D4(k-1) WITH SCALE(1/2,1/2)*ROTATE(PI*2/3)*SHIFT(300,0) ! 内側の右
   ELSE
      DRAW 時計図 WITH ROTATE(-φ)*SHIFT(300/2,300/2/SQR(3))
      PLOT LINES:0,0;300,0;300/2,SQR(3)*300/2;0,0 ! 外側の基準三角形(直接の描画は無し。)
   END IF
END PICTURE

!------
PICTURE 時計図
   SET AREA COLOR 1
   FOR i=1 TO 60
      LET a=PI/30*(i-15)
      IF MOD(i,5)=0 THEN
         CALL linefont(i/5, 60*COS(a), 60*SIN(a)) !数字
         DRAW disk WITH SCALE(1)*SHIFT(72*COS(a),72*SIN(a)) !5分目盛り
      ELSE
         DRAW disk WITH SCALE(.5)*SHIFT(72*COS(a),72*SIN(a)) !1分目盛り
      END IF
   NEXT i
   !--- 00:00 からt秒 の針回転 Gear
   DRAW hand(1) WITH SCALE(2.5, 0.75)*ROTATE(t*PI/21600) ! 時針
   DRAW hand(1) WITH ROTATE(t*PI/1800) ! 分針
   DRAW hand(2) WITH SCALE(0, 1.1)*ROTATE(t*PI/30) ! 秒針
   !--- 中心の飾り
   DRAW disk WITH SHIFT(0,0)*SCALE(4)
END PICTURE

PICTURE hand(c) ! 3針共用
   SET AREA COLOR c
   PLOT AREA: -1,15; 1,15; 1,-60; -1,-60
END PICTURE

!-------------------------------------
SUB linefont(i,x,y) ! plot text の代替
   SELECT CASE i
   CASE 1
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
   CASE 2
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y;x-2.6,y;x-2.6,y+5;x+2.6,y+5 ! 2
   CASE 3
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 3a
      PLOT LINES:x-2.6,y;x+2.6,y ! 3b
   CASE 4
      PLOT LINES:x-2.6,y-5;x-2.6,y;x+2.6,y ! 4a
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 4b
   CASE 5
      PLOT LINES:x+2.6,y-5;x-2.6,y-5;x-2.6,y;x+2.6,y;x+2.6,y+5;x-2.6,y+5 ! 5
   CASE 6
      PLOT LINES:x+2.6,y-5;x-2.6,y-5;x-2.6,y+5;x+2.6,y+5;x+2.6,y;x-2.6,y ! 6
   CASE 7
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y+5 ! 7
   CASE 8
      PLOT LINES:x-2.6,y;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5;x-2.6,y;x+2.6,y ! 8
   CASE 9
      PLOT LINES:x+2.6,y;x-2.6,y;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 9
   CASE 10
      LET x=x-7
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+11
      PLOT LINES:x-2.6,y+5;x-2.6,y-5;x+2.6,y-5;x+2.6,y+5;x-2.6,y+5 ! 0
   CASE 11
      LET x=x-5
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+9
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
   CASE 12
      LET x=x-7
      PLOT LINES:x+2.6,y-5;x+2.6,y+5 ! 1
      LET x=x+11
      PLOT LINES:x-2.6,y-5;x+2.6,y-5;x+2.6,y;x-2.6,y;x-2.6,y+5;x+2.6,y+5 ! 2
   CASE ELSE
   END SELECT
END SUB

END
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:荒田浩二  投稿日:2009年 1月 2日(金)21時16分48秒
  > No.224[元記事へ]

SECONDさんへのお返事です。

文字の鏡像を描画できるようにしました。MAT PLOT CELLSではその領域のすべての画素を描画し時間がかかるので、文字線のある画素のみ読込み、MAT PLOT POINTSで描画するようにしました。

SECONDさんのプログラムの3行目のSET WINDOW文の後ろにつぎのプログロムを挿入してみてください。既存のSUB linefontは廃してください。
Century体は日本語に対応してないので"右クリックで停止"を"Right Click to Stop"にもどしてください。

MAT PLOT文は3次元の配列には適応してないので、あまりスマートではないですがなんとか1秒以内に描画できると思います。遅れる場合は文字サイズ(th=13)を小さくしてみて下さい。

!
ASK TEXT HEIGHT ath
ASK TEXT JUSTIFY atjx$,atjy$
SET POINT STYLE 1
SET TEXT JUSTIFY "CENTER","HALF"
LET th=13
SET TEXT HEIGHT th
SET TEXT FONT "Century" ,0
ASK TEXT WIDTH("WW") tw
ASK PIXEL SIZE (0,0;1.2*th,1.2*tw) px,py
LET p=ABS(px*py)
DIM f0(p,2),f1(p,2),f2(p,2),f3(p,2),f4(p,2),f5(p,2),f6(p,2),f7(p,2),f8(p,2),f9(p,2),f10(p,2),f11(p,2),f12(p,2)
LET pitchx=WORLDX(PIXELX(0)+1)
LET pitchy=WORLDY(PIXELY(0)+1)
FOR i=1 TO 12
   PLOT TEXT ,AT 0,0 : STR$(i)
   MAT f0=ZER
   LET k=0
   FOR x=-0.6*tw TO 0.6*tw STEP pitchx
      FOR y=0.6*th TO -0.6*th STEP pitchy
         ASK PIXEL VALUE (x,y) pc
         IF pc=1 THEN ! 中間色(灰色)を読み込むなら条件を pc<>0
            LET k=k+1
            LET f0(k,1)=x
            LET f0(k,2)=y
         END IF
      NEXT y
   NEXT x
   CALL font_read
   CLEAR
NEXT i
SET TEXT HEIGHT ath
SET TEXT JUSTIFY atjx$,atjy$
!
SUB font_read
   MAT f12=ZER(k,2)
   FOR j=1 TO k
      LET f12(j,1)=f0(j,1)
      LET f12(j,2)=f0(j,2)
   NEXT j
   SELECT CASE i
   CASE 1
      MAT f1=f12
   CASE 2
      MAT f2=f12
   CASE 3
      MAT f3=f12
   CASE 4
      MAT f4=f12
   CASE 5
      MAT f5=f12
   CASE 6
      MAT f6=f12
   CASE 7
      MAT f7=f12
   CASE 8
      MAT f8=f12
   CASE 9
      MAT f9=f12
   CASE 10
      MAT f10=f12
   CASE 11
      MAT f11=f12
   CASE ELSE
   END SELECT
END SUB
SUB linefont(fi,x,y)
   SELECT CASE fi
   CASE 1
      DRAW  numplot(f1) WITH SHIFT(x,y)
   CASE 2
      DRAW  numplot(f2) WITH SHIFT(x,y)
   CASE 3
      DRAW  numplot(f3) WITH SHIFT(x,y)
   CASE 4
      DRAW  numplot(f4) WITH SHIFT(x,y)
   CASE 5
      DRAW  numplot(f5) WITH SHIFT(x,y)
   CASE 6
      DRAW  numplot(f6) WITH SHIFT(x,y)
   CASE 7
      DRAW  numplot(f7) WITH SHIFT(x,y)
   CASE 8
      DRAW  numplot(f8) WITH SHIFT(x,y)
   CASE 9
      DRAW  numplot(f9) WITH SHIFT(x,y)
   CASE 10
      DRAW  numplot(f10) WITH SHIFT(x,y)
   CASE 11
      DRAW  numplot(f11) WITH SHIFT(x,y)
   CASE 12
      DRAW  numplot(f12) WITH SHIFT(x,y)
   END SELECT
END SUB
PICTURE numplot(fm(,))
   MAT PLOT POINTS : fm
END PICTURE
!
 

Re: 7セグメント数字表示のデジタル時計

 投稿者:SECOND  投稿日:2009年 1月 2日(金)21時36分40秒
  > No.225[元記事へ]

荒田浩二さんへのお返事です。

ありがとうございます。
ただ私のパソコンは、Pentium-3, 500MHz なので、やや速度不足で、2秒飛びが増えて、
使用できませんでした。ごめんなさい。でも、MAT PLOT CELLS に比べ格段に高速です。
 

戻る