はじめに
この記事では、ST言語のCASE文を使用してビットフラグによる条件分岐を試みます。プログラミングの自由度は広がりそうですが、フラグの管理などでトラブルを誘発しそうなデザインなので、実用の際は最新の注意が必要になりそうです。
フラグ管理っぽいことをST言語でやってみようという実験です。安全や実用性に関しては考慮していない点はご注意をお願いします。
使用機材
機種など | |
---|---|
PLC | Q02CPU, QX41, QY41P, Q62P, Q38B |
アプリ | GX Works 2 |
I/O割り付けはこちらを参照してください。
ビットフラグを条件に使用するCASE文の例
以下の例では、進行状況などの状態をビットフラグ風に管理し、そのフラグに応じてCASE分で出力状況を制御しています。
IF X1 THEN
M0 := TRUE;
END_IF;
IF M0 AND X91 AND X93 THEN
D0 := D0 OR 16#1; (* 2#0001; *)
END_IF;
IF D0 = 16#1 AND X90 THEN
D0 := D0 OR 16#2; (* 2#0010; *)
END_IF;
IF D0 = 16#3 AND TS1 THEN
D0 := D0 OR 16#4; (* 2#0100; *)
END_IF;
IF D0 = 16#7 AND X91 THEN
D0 := D0 OR 16#8; (* 2#1000; *)
END_IF;
IF D0 = 16#F AND X92 THEN
D0 := D0 OR 16#10; (* 2#00010000; *)
END_IF;
IF D0 = 16#1F AND X90 THEN
D0 := D0 OR 16#20; (* 2#00100000; *)
END_IF;
IF D0 = 16#3F AND TS2 THEN
D0 := D0 OR 16#40; (* 2#01000000; *)
END_IF;
IF D0 = 16#7F AND X91 THEN
D0 := D0 OR 16#80; (* 2#10000000; *)
END_IF;
IF D0 = 16#FF AND X93 THEN
D0 := D0 OR 16#100; (* 2#000100000000; *)
END_IF;
CASE D0 OF (* D0のフラグをもとに出力を振り分け *)
0: YA0 := FALSE; YA1 := FALSE; RST(TRUE, T1); RST(TRUE, T2);
1: YA0 := TRUE;
3: OUT_T(TRUE, TC1, 10);
7: YA0 := FALSE;
15: YA1 := TRUE;
31: YA0 := TRUE;
63: OUT_T(TRUE, TC2, 30);
127: YA0 := FALSE;
255: YA1 := FALSE;
511: D0 := 0; M0 := FALSE;
END_CASE;
ビットフラグは16進数とORなどを用いて管理しています。一方でCASE分では条件に10進数しか使えないため、数字の置き換えが必要になります。
この変換作業が発生するために、CASE文でプログラムミスが発生する可能性がかなり高くなってしまうデザインです。
アドレス指定を用いることで以下のような表記が可能です。
- D0 := D0 OR 16#8; (* 2#1000; *)
+ D0.3 := TRUE;
OUT_T(TRUE, TC2, 30);
第一引数をTRUEとすることで、SETを使用した時と同じような状態になっています。第一引数はM1などのビットデバイスを使い、M1のON, OFFでタイマーの起動とリセットを制御したほうが良さそうです。
まとめ
この記事では、ST言語のCASE文とビットフラグを用いることで、複雑な条件分岐ができるようになりました。ただし、10進数と2進数や16進数との読替が発生するため、プログラムミスの発生が十分起こり得るデザインです。実用性は疑わしいので、利用の際には十分に検討と注意をお願いします。