新しく発言する  EXIT  インデックスへ

ラダーロジック-リレーによる論理回路


  ラダーロジック - リレーによる論理回路 山中和義 2008/04/23 17:12:03 
  つづき 山中和義 2008/04/23 17:15:13 
  │└つづき 山中和義 2008/04/23 17:16:33 
  │ └テストrunの結果 島村1243 2008/04/23 21:23:26 
  │  └試用、ありがとうございます。 山中和義 2008/04/23 22:30:51 
  ラダー図からのシミュレーション 山中和義 2008/04/25 16:14:17  (修正1回)
   └つづき 山中和義 2008/04/25 16:14:55  (修正2回)
    └つづき 山中和義 2008/04/25 16:16:32  (修正3回)
     └つづき 山中和義 2008/04/25 16:17:11 
      └つづき(DATA文) 山中和義 2008/04/25 16:18:46  (修正1回)

  ラダーロジック - リレーによる論理回路 山中和義 2008/04/23 17:12:03   ツリーへ
ラダーロジック - リレーによる論理回路  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/23 17:12:03
!ラダーロジック - リレーによる論理回路

DEF AND(x,y)=MIN(x,y) !基本論理演算
DEF OR(x,y)=MAX(x,y)
DEF NT(x)=1-x


LET N=9 !機器の数

DIM X(0 TO N) !スイッチの接点
MAT X=ZER !状態 ※開

DIM Y(0 TO N) !リレーの接点 ※最大9個
MAT Y=ZER !状態 ※開
SUB relay(n, L) !リレー型の出力(コイル)
LET Y(n)=L
END SUB

DIM T(0 TO N) !タイマの接点
MAT T=ZER !状態 ※開
DIM TMR(0 TO N)
MAT TMR=ZER
SUB tim(n,t0, L) !タイマ型の出力
IF L=1 THEN !オンなら
IF TMR(n)>0 THEN !時間経過を監視する
LET TMR(n)=TMR(n)-1
IF TMR(n)=0 THEN LET T(n)=1 !経過(タイムアップ)
ELSE !設定
LET TMR(n)=t0
END IF

ELSE !オフなら、リセット
LET TMR(n)=0
LET T(n)=0
END IF
END SUB

DIM C(0 TO N) !カウンタの接点
MAT C=ZER !状態 ※開
DIM CNTR(0 TO N)
MAT CNTR=ZER
SUB cnt(n,c0, L,r) !カウンタ型の出力
IF r=1 THEN !リセットなら
LET CNTR(n)=0
LET C(n)=0
ELSE
IF L=1 THEN !Hなら
IF CNTR(n)>0 THEN !エッジ(L→H)なら
LET CNTR(n)=-ABS(CNTR(n)-1) !※Lになるのを待つ
IF CNTR(n)=0 THEN LET C(n)=1 !完了
ELSEIF CNTR(n)=0 THEN !設定
LET CNTR(n)=-c0 !※Lになるのを待つ
ELSE !負の場合、何もしない
END IF
ELSE !Lなら
LET CNTR(n)=ABS(CNTR(n))
END IF
END IF
END SUB
!------------------------------ ここまでがサブルーチン

  つづき 山中和義 2008/04/23 17:15:13   ツリーへ
Re: ラダーロジック - リレーによる論理回路  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/23 17:15:13
つづき

LET h=5 !行数
LET w=5 !列数
SET WINDOW 0,w,0,h !表示領域 ※正方形

SET TEXT JUSTIFY "center","bottom"

DIM cTBL$(h,w),nTBL(h,w) !機器の配置位置

DO
mouse poll mx,my,left,right !マウスの情報を得る

IF left=1 THEN !左ボタンが押されたら
LET xx=INT(mx)+1
LET yy=INT(my)+1

LET tt$=UCASE$(cTBL$(yy,xx))
IF tt$="SA" OR tt$="SB" THEN !スイッチなら
LET v=nTBL(yy,xx) !番号
LET X(v)=NT(X(v)) !反転させる
END IF

WAIT DELAY 0.3 !※要調整
END IF

IF TIME-oldtime>0.1 THEN !ほぼ実時間
CALL ladder
LET oldtime=TIME
END IF

SET DRAW mode hidden !ちらつき防止の開始
CLEAR
DRAW grid !目盛
CALL ladder_display !ラダー図
SET DRAW mode explicit !ちらつき防止の終了

LOOP UNTIL right=1 !右ボタンが押されるまで


SUB ladder_display !ラダー図を表示する
RESTORE 10

FOR yy=h TO 1 STEP -1 !※左上から
FOR xx=1 TO w !格子を走査する
READ cmd$,nm$,s$ !機器、番号、注釈を得る
LET nm=VAL(nm$)

IF cmd$<>"" THEN !機器なら
SELECT CASE UCASE$(cmd$) !記号へ
CASE "SA" !スイッチのa接点
LET el$="─[ ]─" !機器記号
LET cc=X(nm) !状態
CASE "SB" !スイッチのb接点
LET el$="─[/]─"
LET cc=NT(X(nm))

CASE "A" !リレーのa接点
LET el$="─| |─"
LET cc=Y(nm)
CASE "B" !リレーのb接点
LET el$="─|/|─"
LET cc=NT(Y(nm))

CASE "TA" !タイマのa接点
LET el$="─| |─"
LET nm$="T"&nm$
LET cc=T(nm)
CASE "TB" !タイマのb接点
LET el$="─|/|─"
LET nm$="T"&nm$
LET cc=NT(T(nm))

CASE "CA" !カウンタのa接点
LET el$="─| |─"
LET nm$="C"&nm$
LET cc=C(nm)
CASE "CB" !カウンタのb接点
LET el$="─|/|─"
LET nm$="C"&nm$
LET cc=NT(C(nm))

CASE "O" !リレーのコイル
LET el$="─( )─"
LET cc=Y(nm)
CASE "T" !タイマ
LET el$="─("&s$&")─" !値
LET nm$="T"&nm$
READ s$
LET cc=T(nm)
CASE "C" !カウンタ
LET el$="─("&s$&")─" !値
LET nm$="C"&nm$
READ s$
LET cc=NT(T(nm))

  │└つづき 山中和義 2008/04/23 17:16:33   ツリーへ
Re: つづき  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/23 17:16:33
つづき

CASE ELSE !結線なら
LET el$=cmd$
LET nm$="" !番号は無視する
LET cc=0
END SELECT

IF cc=1 THEN !状態を表示する
SET AREA COLOR 4 !※閉
PLOT AREA: xx-1,yy-1; xx,yy-1; xx,yy; xx-1,yy
END IF

PLOT TEXT ,AT xx-0.5,yy-0.5: el$ !機器記号
PLOT TEXT ,AT xx-0.5,yy-0.3: nm$ !番号
PLOT TEXT ,AT xx-0.5,yy-0.9: s$ !注釈

IF nm$<>"" THEN !機器、番号の配置位置を記録する
LET cTBL$(yy,xx)=cmd$
LET nTBL(yy,xx)=nm
END IF
END IF
NEXT xx
NEXT yy
!MAT PRINT cTBL$
!MAT PRINT nTBL
END SUB


SUB ladder !ラダーロジック
LET L=AND(X(3),NT(T(1))) !1行目
CALL tim(0,10, L)
LET L=T(0) !2行目
CALL tim(1,20, L)
LET L=T(0) !3行目
CALL relay(2, L)

LET L=AND(OR(X(0),Y(0)),NT(X(1))) !4、5行目
CALL relay(0, L)
END SUB


10 DATA "sa",3,"SW" !フリッカ
DATA "tb",1,""
DATA "t",0,10,"1秒タイマ"
DATA "",0,""
DATA "",0,""

DATA "ta",0,""
DATA "─",0,""
DATA "t",1,20,"2秒タイマ"
DATA "",0,""
DATA "",0,""

DATA "ta",0,""
DATA "─",0,""
DATA "o",2,"ランプ"
DATA "",0,""
DATA "",0,""

DATA "sa",0,"運転釦" !自己保持回路(リセット優先)
DATA "┬",0,"│"
DATA "sb",1,"停止釦"
DATA "─",0,""
DATA "o",0,"運転中"

DATA "a",0,"運転中" !2行目
DATA "┘",0,""
DATA "",0,""
DATA "",0,""
DATA "",0,""

END



現状、結線情報(data文)と演算部分(サブルーチンladder)とを別々に定義する必要がある。

結線情報から生成するよう検討中、、、
  │ └テストrunの結果 島村1243 2008/04/23 21:23:26   ツリーへ
Re: つづき  返事を書く  ノートメニュー
島村1243 <bjllmpcujp> 2008/04/23 21:23:26
テストrunの結果

未だ検討中との事ですが非常に興味があり、試させて頂きました。その結果報告です。

次の様に変更すると、運転ボタンを押すと
タイマーでランプが点滅するシーケンスになり、停止ボタンを押すとランプ点滅制御
が停止する、と言う動きになりプログラムが実用的なシーケンスシミュレータになると思いました。

1)運転ボタンはマウスで押した時だけONし、マウスを離すとOFFする様に変える。
2)停止ボタンは通常はONで、マウスで押したときだけOFFし、マウスを離すとONする様に変える。
3)番号3のSWを、番号0リレーのa接点に取り替える。
  │  └試用、ありがとうございます。 山中和義 2008/04/23 22:30:51   ツリーへ
Re: テストrunの結果  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/23 22:30:51
試用、ありがとうございます。

元のプログラムは、2つの回路の例ということです。2つを繋げると実例になりますね。
また、マウスの左ボタンの動作は、同時にスイッチを押すことを考えるためクリックで反転させています。

また、要望などがあればお願いします。反映できればいいのですが、、、




仕様変更に対応するプログラム(変更箇所のみ)

●マウス左ボタンの動作変更

DO
mouse poll mx,my,left,right !マウスの情報を得る


!---------- ↓↓↓↓↓ ---------- ※
LET xx=INT(mx)+1
LET yy=INT(my)+1

LET tt$=UCASE$(cTBL$(yy,xx))
IF tt$="SA" OR tt$="SB" THEN !スイッチなら
LET v=nTBL(yy,xx) !番号
IF left=1 THEN LET X(v)=1 ELSE LET X(v)=0 !左ボタンが押されたら
END IF
!---------- ↑↑↑↑↑ ---------- ※


IF TIME-oldtime>0.1 THEN !ほぼ実時間
CALL ladder
LET oldtime=TIME
END IF

  :(略)
  :



●結線の変更

SUB ladder !ラダーロジック
LET L=AND(Y(0),NT(T(1))) !1行目 <-------------------- ※
CALL tim(0,10, L)
LET L=T(0) !2行目
CALL tim(1,20, L)
!!!LET L=T(0) !3行目
CALL relay(2, L)

LET L=AND(OR(X(0),Y(0)),NT(X(1))) !4、5行目
CALL relay(0, L)
END SUB


10 DATA "a",0,"運転中" !フリッカ <-------------------- ※
DATA "tb",1,""
DATA "t",0,10,"1秒タイマ"
DATA "",0,""
DATA "",0,""

  :(略)
  :
  ラダー図からのシミュレーション 山中和義 2008/04/25 16:14:17  (修正1回)  ツリーへ
Re: ラダーロジック - リレーによる論理回路  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/25 16:14:17 ** この記事は1回修正されてます
ラダー図からのシミュレーション



!ラダーロジック - リレーによる論理回路

DEF AND(x,y)=MIN(x,y) !基本論理演算
DEF OR(x,y)=MAX(x,y)
DEF NT(x)=1-x


LET N=9 !機器の数

DIM X(0 TO N) !スイッチの接点 ※a接点側、b接点はNT(X(i))とする。
MAT X=ZER !状態 ※開

DIM Y(0 TO N) !リレーの接点 ※最大9個
MAT Y=ZER !状態 ※開
SUB relay(n, L) !リレー型の出力(コイル)
LET Y(n)=L
END SUB

DIM T(0 TO N) !タイマの接点
MAT T=ZER !状態 ※開
DIM TMR(0 TO N)
MAT TMR=ZER
SUB tim(n,t0, L) !タイマ型の出力 ※L:入力 ※オンディレイ
IF L=1 THEN !オンなら
IF TMR(n)>0 THEN !時間経過を監視する
LET TMR(n)=TMR(n)-1
IF TMR(n)=0 THEN LET T(n)=1 !経過(タイムアップ)
ELSE !設定
LET TMR(n)=t0
END IF

ELSE !オフなら、リセット
LET TMR(n)=0
LET T(n)=0
END IF
END SUB

DIM C(0 TO N) !カウンタの接点
MAT C=ZER !状態 ※開
DIM CNTR(0 TO N)
MAT CNTR=ZER
SUB cnt(n,c0, L) !カウンタ型の出力
IF C(n)=0 AND CNTR(n)=0 THEN LET CNTR(n)=-c0 !電源投入時 ※Lになるのを待つ

IF L=1 THEN !オンなら
IF CNTR(n)>0 THEN !エッジ(L→H)なら
LET CNTR(n)=-(CNTR(n)-1) !※Lになるのを待つ
IF CNTR(n)=0 THEN LET C(n)=1 !完了
ELSE !負の場合、何もしない
END IF
ELSE !オフなら
LET CNTR(n)=ABS(CNTR(n))
END IF
END SUB
SUB cntclr(n, L) !カウンタ型の出力のリセット
IF L=1 THEN !オンなら
LET CNTR(n)=0 !リセット
LET C(n)=0
END IF
END SUB
!------------------------------ ここまでがサブルーチン

   └つづき 山中和義 2008/04/25 16:14:55  (修正2回)  ツリーへ
Re: ラダー図からのシミュレーション  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/25 16:14:55 ** この記事は2回修正されてます
つづき



LET h=5 !行数
LET w=5 !列数 ※4接点+1コイル
!SET bitmap SIZE 500,500
SET WINDOW 0,w,0,h !表示領域 ※正方形

SET TEXT JUSTIFY "center","bottom"

DIM cTBL$(h,w),nTBL(h,w) !機器の配置位置

DIM vTMR(0 TO N) !タイマの設定値
MAT vTMR=ZER
DIM vCNT(0 TO N) !カウンタの設定値
MAT vCNT=ZER

DIM vTBL(h,w) !ラダーロジックのテーブルの値
MAT vTBL=ZER

DO
LET CurTime=TIME !現在の時刻

mouse poll mx,my,left,right !マウスの情報を得る

IF CurTime-oldtime>0.1 THEN !100msごとに ※ほぼ実時間
LET xx=INT(mx)+1 !該当する格子位置を計算する
LET yy=INT(my)+1 !※ドラッグして格子から外れないこと

IF xx<1 OR xx>w OR yy<1 OR yy>h THEN
ELSE !範囲内なら
LET tt$=UCASE$(cTBL$(yy,xx)) !機器を得る
IF tt$="SA" OR tt$="SB" THEN LET X(nTBL(yy,xx))=left !スイッチなら、左ボタンの状態に応じる

CALL ladder !ラダーロジックの計算
!!!PRINT S(0);S(1);Y(0); T(0);T(1);Y(2) !タイムチャート

SET DRAW mode hidden !ちらつき防止の開始
CLEAR
DRAW grid !目盛
CALL ladder_display !ラダー図
SET DRAW mode explicit !ちらつき防止の終了

LET oldtime=CurTime
END IF
END IF

LOOP UNTIL right=1 !右ボタンが押されるまで



FUNCTION xPrev(x,y) !横方向の計算
IF x>1 THEN !2列目以降なら
LET xPrev=vTBL(y,x-1) !1つ前の値
ELSE !1列目なら
LET xPrev=1 !母線
END IF
END FUNCTION

    └つづき 山中和義 2008/04/25 16:16:32  (修正3回)  ツリーへ
Re: つづき  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/25 16:16:32 ** この記事は3回修正されてます
つづき


SUB ladder !ラダーロジックのテーブルを計算する
FOR xx=1 TO w !1列目から(母線から順次右へ) ※サイクルタイム

!AND結線の計算
FOR yy=h TO 1 STEP -1 !1行目から(先頭行から末尾行まで1列ごと)
LET tt$=UCASE$(cTBL$(yy,xx)) !機器を得る

IF tt$<>"" THEN !機器なら
LET nm=nTBL(yy,xx) !番号を得る

LET v1=xPrev(xx,yy) !前列からの積を考慮して

SELECT CASE tt$
CASE "SA" !スイッチのa接点
LET v0=X(nm)
CASE "SB" !スイッチのb接点
LET v0=NT(X(nm))

CASE "A" !リレーのa接点
LET v0=Y(nm)
CASE "B" !リレーのb接点
LET v0=NT(Y(nm))

CASE "TA" !タイマのa接点
LET v0=T(nm)
CASE "TB" !タイマのb接点
LET v0=NT(T(nm))

CASE "CA" !カウンタのa接点
LET v0=C(nm)
CASE "CB" !カウンタのb接点
LET v0=NT(C(nm))

CASE "O" !リレーのコイル
CALL relay(nm,v1)
LET v0=Y(nm)
CASE "T" !タイマ
CALL tim(nm,vTMR(nm),v1)
LET v0=T(nm)
CASE "C" !カウンタ
CALL cnt(nm,vCNT(nm),v1)
LET v0=C(nm)
CASE "CR" !カウンタリセット
CALL cntclr(nm,v1)
LET v0=C(nm)

CASE "─","┬","┤","┘","┴" !結線
LET v0=1
CASE "│","├","└" !結線
LET v0=0 !前列とは無関係

CASE ELSE
PRINT cTBL$(yy,xx);" は未サポートです。"
STOP

END SELECT

LET vTBL(yy,xx)=AND(v1,v0) !状態を設定する
END IF
NEXT yy

!OR結線の計算
LET v1=0
FOR yy=h TO 1 STEP -1 !1行目から
SELECT CASE UCASE$(cTBL$(yy,xx)) !結線なら
CASE "┬" !開始
LET v1=vTBL(yy,xx)
LET sav_yy=yy !行を記録する
CASE "┤","│","├" !延長
LET v1=OR(v1,vTBL(yy,xx)) !1つ上との論理和
CASE "┘","└","┴" !終了
LET v1=OR(v1,vTBL(yy,xx))

FOR tmp=yy TO sav_yy !ここまでを同じにする
LET vTBL(tmp,xx)=v1
NEXT tmp
LET v1=0

CASE ELSE
END SELECT
NEXT yy

NEXT xx

!MAT PRINT vTBL !debug
END SUB

     └つづき 山中和義 2008/04/25 16:17:11   ツリーへ
Re: つづき  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/25 16:17:11
つづき



SUB ladder_display !ラダー図を表示する
RESTORE 10

FOR yy=h TO 1 STEP -1 !※左上から格子を走査する
FOR xx=1 TO w
READ cmd$,nm$,s$ !機器、番号、注釈を得る
LET nm=VAL(nm$)

SELECT CASE UCASE$(cmd$) !記号へ
CASE "SA" !スイッチのa接点
LET el$="─[ ]─" !機器記号 ※横方向
LET cc=X(nm) !状態
CASE "SB" !スイッチのb接点
LET el$="─[/]─"
LET cc=NT(X(nm))

CASE "A" !リレーのa接点
LET el$="─| |─"
LET cc=Y(nm)
CASE "B" !リレーのb接点
LET el$="─|/|─"
LET cc=NT(Y(nm))

CASE "TA" !タイマのa接点
LET el$="─| |─"
LET nm$="T"&nm$
LET cc=T(nm)
CASE "TB" !タイマのb接点
LET el$="─|/|─"
LET nm$="T"&nm$
LET cc=NT(T(nm))

CASE "CA" !カウンタのa接点
LET el$="─| |─"
LET nm$="C"&nm$
LET cc=C(nm)
CASE "CB" !カウンタのb接点
LET el$="─|/|─"
LET nm$="C"&nm$
LET cc=NT(C(nm))

CASE "O" !リレーのコイル
LET el$="─( )─"
LET cc=Y(nm)
CASE "T" !タイマ
LET vTMR(nm)=VAL(s$) !タイマ値を記録する
LET el$="─("&STR$(TMR(nm))&")─" !値
LET nm$="T"&nm$
READ s$ !注釈
LET cc=T(nm)
CASE "C" !カウンタ
LET vCNT(nm)=VAL(s$) !カウンタ値を記録する
LET el$="─("&STR$(CNTR(nm))&")─"
LET nm$="C"&nm$
READ s$
LET cc=C(nm)
CASE "CR" !カウンタリセット
LET el$="─(R)─"
LET nm$="C"&nm$
LET cc=C(nm)

CASE ELSE !結線なら
LET el$=cmd$
LET nm$="" !番号は無視する
LET cc=0
END SELECT

IF cc=1 THEN !状態を表示する
SET AREA COLOR 4 !※閉
PLOT AREA: xx-1,yy-1; xx,yy-1; xx,yy; xx-1,yy
END IF

PLOT TEXT ,AT xx-0.5,yy-0.5: el$ !機器記号
PLOT TEXT ,AT xx-0.5,yy-0.3: nm$ !番号
PLOT TEXT ,AT xx-0.5,yy-0.9: s$ !注釈

LET cTBL$(yy,xx)=cmd$
LET nTBL(yy,xx)=nm
NEXT xx
NEXT yy
END SUB

      └つづき(DATA文) 山中和義 2008/04/25 16:18:46  (修正1回)  ツリーへ
Re: つづき  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/04/25 16:18:46 ** この記事は1回修正されてます
つづき(DATA文)




10 DATA "a",0,"" !フリッカ
DATA "tb",1,""
DATA "t",0,10,"1秒タイマ"
DATA "",0,""
DATA "",0,""

DATA "ta",0,""
DATA "┬",0,"│" !※分配
DATA "t",1,20,"2秒タイマ"
DATA "",0,""
DATA "",0,""

DATA "",0,""
!DATA "ta",0,0
DATA "└",0,"" !※分配
!DATA "─",0,""
DATA "o",2,"ランプ"
DATA "",0,"※フリッカ"
DATA "",0,""

DATA "sa",0,"運転釦" !自己保持回路(リセット優先)
DATA "┬",0,"│" !※結合
DATA "sb",1,"停止釦"
DATA "─",0,""
DATA "o",0,"運転中"

DATA "a",0,"運転中" !2行目
DATA "┘",0,"" !※結合
DATA "",0,""
DATA "",0,""
DATA "",0,""


END




他のサンプル(差し替え)


10 DATA "sa",3,"SW"
DATA "─",0,""
DATA "o",1,""
DATA "",0,""
DATA "",0,""

DATA "a",1,""
DATA "b",3,""
DATA "o",2,"パルス"
DATA "",0,""
DATA "",0,""

DATA "a",1,""
DATA "o",3,""
DATA "",0,"1スキャンパルス発生回路"
DATA "",0,""
DATA "",0,""

DATA "a",2,""
DATA "b",0,""
DATA "┬",0,"│"
DATA "o",0,"ランプ"
DATA "",0,""

DATA "b",2,""
DATA "a",0,""
DATA "┘",0,""
DATA "",0,"オルタネイト回路"
DATA "",0,""


 インデックスへ  EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。