今回の記事ではBeckhoff TwinCAT3のOR_ELSE・JMP・MUX・SEL構文動作を説明します。さ、FAを楽しもう!
前書き
いつも私の技術ブログとYouTubeチャンネルをご覧いただき、心より感謝申し上げます。また、いまFullさん(full@桜 八重 (@fulhause) / X)と共に毎週水曜日の夜にお届けしている「高橋クリス」ラジオ番組を運営しています。
現在、私達の活動はほぼ無償で続けており、より多くのコンテンツを提供するためには、皆様の温かいご支援が大変重要です。もし可能であれば、以下のリンクから応援していただけると大変嬉しく思います。
高橋クリスのメンバーシップ
こちらはFullさん(full@桜 八重 (@fulhause) / X)と共にやっているラジオにメンバーシップを登録いただけます。
https://note.com/fulhause/membership/join
AMAZON ギフトリスト
こちらは自分のブログのコンテンツ制作や設備の充実に大いに役立てさせていただきます。
https://www.amazon.co.jp/hz/wishlist/ls/H7W3RRD7C5QG?ref_=wl_share
Patreon
こちらは自分のブログのコンテンツ制作や設備の充実に対する小さな応援の気持ちのPatreonです。
https://www.patreon.com/user?u=84249391
皆様のサポートが、私たちの活動をより充実させる力となります。
どうぞよろしくお願いします。
メールアドレス(*=@)
X
Implementation
それでは実際に各構文の動作をプログラムに動きながら確認しましょう。
OR_ELSE
OR_ELSEはIEC 61131-3規格の拡張版であり、STでのプログラミングにのみ使用可能です。IEC の OR 演算子とは対照的に、OR_ELSE では、オペランドのひとつが TRUE で評価された場合、それ以降のすべてのオペランドに対する式は実行されません。
Program
OR_ELSEの動作を検出するために、fbTest Function Blockを作成します。Method mCounterがあり、そのMethodを実行するたびにiCounterを加算し、TrueをReturnします。
そしてpCounterのPropertyを作り、プログラム内にiCounter値を取得できるようにします。
FUNCTION_BLOCK fbTest VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR iCounter:INT; END_VAR METHOD mCounter : bool VAR_INPUT END_VAR iCounter:=iCounter+1; mCounter:=True; PROPERTY pCounter : INT pCounter:=iCounter; |
最後は実際ORとOR_ELSEを同時に実行し動作の違いを確認しましょう。
PROGRAM pOrElse VAR fbOr:fbTest; fbOrElse:fbTest; iCounterOr,iCounterOrElse:INT; xON:BOOL:=TRUE; xResult1,xResult2:BOOL; END_VAR xResult1:=xON OR fbOr.mCounter(); iCounterOr:=fbOr.pCounter; xResult2:=xON OR_ELSE fbOrElse.mCounter(); iCounterOrElse:=fbOrElse.pCounter; |
Result
iCounterOrが加算され、iCounterOrElseが0のまま加算されていません。それはiCounterOrがOR文で条件判断しますので、fbOR.mCounter()が実行するようにします。でもiCounterOrElseがOr_ELSEで条件判断するので、fbORElse.mCounter Methodが実行できず、iCounterOrElseが加算しません。
次はxONがFalseの状態になると、iCounterOrとiCounterOrElseが両方とも加算されます。iCounterOrElseが加算されてる理由としてはOr_ELSEで条件判断するので、fbORElse.mCounter MethodのReturn値がTRUEになり、xResult2もTRUEになります。
JMP
JMP命令は、ラベルで示された行に(無条件に)ジャンプするために使用します。 ラベルの位置はJMP命令の上でも下でもかまいませんが、JMP命令と同じスコープ(エディターウィンドウ、例えばMETHOD、PROGRAM、FUNCTIONなど)でなければなりません。 ラベルは自由に選択できる一意の識別子で、行の先頭に付けます。
また、JMP文はデフォルトでは無条件ですが、JMPとlabelの間に丸中括弧()で囲んだ式を追加することができ、条件は、ブール値を返す必要があります。 条件が TRUE の場合、ラベルへのジャンプが実行されます。
Program
次はJMPとLABELを組み合わせて動作検証しましょう。
iResult:=4; JMP(Cond2) label2; IF Cond1 THEN iResult:=2; JMP label1; END_IF; JMP labelEND; label2: iResult:=3; JMP labelEND; label1: iResult:=2; JMP labelEND; labelEND: ; |
Result
Cond1がTrueの場合はiResult値が2になります。それはプログラムがlabel1にJUMPしたからです。
Cond2がTrueの場合はiResult値が3になります。それはプログラムがlabel2にJUMPしたからです。
もしCond1とCond2が両方ともFalseの場合はiResult値が4になります。それはプログラムがlabelENDにJUMPしたからです。
MUX
MUX演算子は、CASE文と同様に動作します。 それは整数式を評価し、in0からinNまでの整数値に基づいてn番目の文を選択します。 一般的な操作のように見えますが、選択されたステートメントのみを計算することで、異なる動作をします。 一致する値がない場合は、デフォルトで最後の文を選択します。
Program
プログラムに複数の関数を作成します。freturn1が実行した場合は、111がReturnします。
FUNCTION freturn1 : INT VAR_INPUT END_VAR VAR END_VAR freturn1:=111; |
freturn2が実行した場合は、222がReturnします。
FUNCTION freturn2 : INT VAR_INPUT END_VAR VAR END_VAR freturn2:=222; |
freturn3が実行した場合は、333がReturnします。
FUNCTION freturn3 : INT VAR_INPUT END_VAR VAR END_VAR freturn3:=333; |
freturn4が実行した場合は、444がReturnします。
FUNCTION freturn4 : INT VAR_INPUT END_VAR VAR END_VAR freturn4:=444; |
最後はMUXの動作を検証しましょう。
PROGRAM pMUX VAR iResult:INT; iSelector:INT:=0; END_VAR iResult:=MUX( iSelector ,-99 ,freturn1() ,freturn2() ,freturn3() ,freturn4() ); |
Result
iSelectorが0の場合は、MUXがDefault値を使用しますので、iResult値が-99になります。
iSelectorが1の場合は、MUXがfreturn1関数を実行しますので、iResult値が111になります。
iSelectorが2の場合は、MUXがfreturn2関数を実行しますので、iResult値が222になります。
iSelectorが3の場合は、MUXがfreturn3関数を実行しますので、iResult値が333になります。
iSelectorが4の場合は、MUXがfreturn4関数を実行しますので、iResult値が444になります。
SEL
SEL演算子の機能は、三項条件演算子と似ている。 SEL演算子はブーリアン式を評価し、そのブーリアン式がTRUEと評価されるかFALSEと評価されるかに応じて、2つの式のどちらかの結果を返します。 関数のように見えますが、動作は異なります。 TwinCATでは、ブーリアン式がTRUEと評価された場合、in0に先行する式は計算されず、FALSEと評価された場合、in1に先行する式は計算されません。 優先順位は関数呼び出しのままです。 ただし、この動作はST/ExSTに特有のもので、ラダー・ロジックのようなグラフィカル言語では、ブーリアン式の結果に関係なくin0とin1の両方が計算されます。
Program
プログラムに複数の関数を作成します。fPlus10を実行した場合は、iValueを+10します。
FUNCTION fPlus10 : INT VAR_INPUT iValue:INT; END_VAR VAR END_VAR fPlus10:=iValue+10; |
fPlus20を実行した場合は、iValueを+20します。
FUNCTION fPlus20 : INT VAR_INPUT iValue:INT; END_VAR VAR END_VAR fPlus20:=iValue+20; |
最後はSEL動作を検証しましょう。
iResult:=SEL(iSelector >=0 ,fPlus10(iValue:=iPlusValue) ,fPlus20(iValue:=iPlusValue) ); |
Result
iSelector値が0より大きい場合は、2つ目の式を実行しますので、iResultが20になります。
iSelector値がそれ以外の場合は、1つ目の式を実行しますので、iResultが10になります。