シリーズテーマ
ST言語版 歩進制御ファンクションブロック
順序アルゴリズム(あれしてこれしてつぎにどうするとかの手順化)
の表現が小難しいリレー回路向けに
ステップ運転のファンクションブロック化をしました。
SFCを使えば出来るのですが、個人的に野暮ったいので作ってみました。
これを参考に改造する場合は、一般的なプログラムと処理方法が違うため注意してください。
機能:ステップごとにタイムアップ自動起動&次ステップへの信号onで移行する
バグっぽいものを発見したので備忘録
エディターでFB(ファンクションブロック)
をD&D(ドラッグアンドドロップ)した場合、
タイマーFBの最後のカッコの後にセミコロン
”;” がついて無いです。
その他、
タイマーブロックのST表記は独自?ぽいので移植時には注意が必要です
クリアーな状態からコード記入の際は気をつけてください
動作チェックの最終形態での表示
START_SWを入れるとOUT1~OUT5までを1秒ごとに順番にオンします。
動画準備中(暫定gif表示中) 動作シミュレーションの様子
ファンクションブロックの中身説明
5つまでのものですが追加すればいくつでもステップが増やせます。
個人的には、SFCで地道に作るよりかなり楽です。
起動スイッチ 論理式版立ち上がりエッジの取得
プログラマーの技巧美学的に
R-TRIGファンクションを使いたくない場合はこちらをお使いください
立ち上がりエッジを取得
START_TRG := START AND NOT(START_MEM);
START_MEM := START;
初期ステップ番号を代入
スタートが押されたら100番地へ進むおまじない
IF START_TRG & NOT(STEP1 OR STEP2 OR STEP3 OR STEP4 OR STEP5 )
THEN
BUSY :=TRUE;
SC_STEP :=INT#100;
END_IF;
リセットスイッチの処理
リセットスイッチが押されたら
BUSYをオフ
ステップ番号を初期化
各ステップのフラグをオフにする
IF RESET
THEN
BUSY :=FALSE;
SC_STEP:=INT#0;
STEP1:=FALSE;
STEP2:=FALSE;
STEP3:=FALSE;
STEP4:=FALSE;
STEP5:=FALSE;
END_IF;
オンディレイタイマー1 2~5は省きます
IN:タイマー起動
PT:タイマー数値設定
Q:タイムアップで出力
ET:タイマー現在値モニタ
TON_1(
IN := STEP1,
PT := P_TIM1,
Q => Q_TIM1,
ET => E_TIM1);
ステップ管理部
CASE SC_STEP OF
100:
STEP1:=TRUE;
IF Q_TIM1 & SHIFT1 THEN
STEP1:=FALSE;
SC_STEP:= INT#110;
END_IF;
110:
STEP2:=TRUE;
IF Q_TIM2 & SHIFT2 THEN
STEP2:=FALSE;
SC_STEP:= INT#120;
END_IF;
120:
STEP3:=TRUE;
IF Q_TIM3 & SHIFT3 THEN
STEP3:=FALSE;
SC_STEP:= INT#130;
END_IF;
130:
STEP4:=TRUE;
IF Q_TIM4 & SHIFT4 THEN
STEP4:=FALSE;
SC_STEP:= INT#140;
END_IF;
140:
STEP5:=TRUE;
IF Q_TIM5 & SHIFT5 THEN
STEP5:=FALSE;
BUSY :=FALSE;
SC_STEP:= INT#0;
END_IF;
END_CASE;
コードまとめ
(*
起動信号:START
立ち上がりを作成
*)
START_TRG := START AND NOT(START_MEM);
START_MEM := START;
IF START_TRG & NOT(STEP1 OR STEP2 OR STEP3 OR STEP4 OR STEP5 )
THEN
BUSY :=TRUE;
SC_STEP :=INT#100;
END_IF;
IF RESET
THEN
BUSY :=FALSE;
SC_STEP:=INT#0;
STEP1:=FALSE;
STEP2:=FALSE;
STEP3:=FALSE;
STEP4:=FALSE;
STEP5:=FALSE;
END_IF;
TON_1(
IN := STEP1,
PT := P_TIM1,
Q => Q_TIM1,
ET => E_TIM1);
(*--------------------------*)
TON_2(
IN := STEP2,
PT := P_TIM2,
Q => Q_TIM2,
ET => E_TIM2);
(*--------------------------*)
TON_3(
IN := STEP3,
PT := P_TIM3,
Q => Q_TIM3,
ET => E_TIM3);
(*--------------------------*)
TON_4(
IN := STEP4,
PT := P_TIM4,
Q => Q_TIM4,
ET => E_TIM4);
(*--------------------------*)
TON_5(
IN := STEP5,
PT := P_TIM5,
Q => Q_TIM5,
ET => E_TIM5);
(*--------------------------*)
CASE SC_STEP OF
100:
STEP1:=TRUE;
IF Q_TIM1 & SHIFT1 THEN
STEP1:=FALSE;
SC_STEP:= INT#110;
END_IF;
110:
STEP2:=TRUE;
IF Q_TIM2 & SHIFT2 THEN
STEP2:=FALSE;
SC_STEP:= INT#120;
END_IF;
120:
STEP3:=TRUE;
IF Q_TIM3 & SHIFT3 THEN
STEP3:=FALSE;
SC_STEP:= INT#130;
END_IF;
130:
STEP4:=TRUE;
IF Q_TIM4 & SHIFT4 THEN
STEP4:=FALSE;
SC_STEP:= INT#140;
END_IF;
140:
STEP5:=TRUE;
IF Q_TIM5 & SHIFT5 THEN
STEP5:=FALSE;
BUSY :=FALSE;
SC_STEP:= INT#0;
END_IF;
END_CASE;
(*---------------------------------------------------------*)
END := NOT(BUSY) AND BUSY_MEM;
BUSY_MEM :=BUSY;
コメント