【シリーズすごいぞiQ-F】その場しのぎのST言語プログラミング



:::note warn
本記事はラダー言語を主に使用する電気技術者を対象として記述しています。
:::

## はじめに
GX_Works3ではラダーの表示がグリッド表示になったことや、長いコメントやラベル名を使用したりした場合にプログラムの縦の見通しが非常に悪くなります。

私の環境では初期状態の場合にラダー表示とST言語表示の縦の行数を比較すると、
+ ラダー表示10行　、ST言語表示　40行以上

とST言語表示の方がラダー表示の4倍以上の行数を表示することができます。


ST言語での記述が不慣れでも、ほとんどロジックが必要ない下記の様な回路で使用すればプログラムの縦の見通しが良くなります
+ ロギング用デバイスへのデータ転送を数十点分
+ 用途別一括異常接点への信号割付を数十から数百点分

インラインSTでは、スクロールが必要なコードの長さになると表示がもたつきます。
最初からST言語でプログラミングするとその表示のもたつきを避ける事ができます。

そういった **その場しのぎのST言語プログラミング** についてのコツを何点か記載します。

## 1．ひとつのプロジェクトにラダーとST言語プログラムを混在させる方法について
ナビゲーションツリーでプログラムブロックを追加する際にラダーやST言語など使用する言語を選べるようになっています。

この処理はラダー、この処理はST言語というようにプログラムブロックを分けて登録することが可能です。

ファンクションブロックやファンクションもプログラム毎に使用する言語を選べます。
    
## 2．アウトラインとコメントについて
### コメント記号は「//」を使いましょう
マニュアルなどでは行コメントは行頭から[//」、それ以外は「(* *)」でコメントを行っていますが、これに従うとコメントした行すべてにアウトラインアイコンが表示されてしまいます。
「//」は行の途中からでも使用できるので、こちらを使用すると無駄なアウトラインアイコンが表示されません。（下図参照）
  ![STコメント例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765338/c9c6c376-f4d1-83f6-46c8-8d2a091d5bfc.png)

### ダミーIF文でのアウトライン管理
インデントでのコードの折りたたみはできないので、ダミーIFでくくりましょう
私の場合、折りたたみさせたいコード部は
+ **IF TRUE THEN ～　END_IF；**

でくくる事にしています。
	
## 3．単純な回路をST言語で記述する時の表現方法の優先順位

:::note warn
ST言語の文法の詳細は下記を参照ください
+ 「MELSEC iQ-R/MELSEC iQ-Fストラクチャードテキスト(ST)プログラミングガイドブック」
+ 「MELSEC iQ-F FX5プログラミングマニュアル（命令/汎用FUN/汎用FB編）

:::	
同じ処理を色々な書き方で記述できますが、
**その場しのぎのST言語プログラミング**では下記の優先順位でコードの記述を検討します。
	
### 1)代入文で書けるか？
AND OR NOTなどの論理演算記号を使用した代入文で記述できるか検討します。
リストプログラムの経験があれば単純な自己保持回路程度なら特に苦にならず記述できるかと思われます。

**例**
 
    ラダープログラム       
         │  X0       X1                               Y0    │
      (0)├┤    ├──┬┤ ／ ├──────────────────────────────○────┤
         │        │                                         │
         │  Y0    │                                         │
         ├┤    ├──┘                                         │

    //ST代入文
        Y0 := (X0 OR Y0) AND NOT X1;
    

あたりまえかもしれませんが、演算式はEXCELなどに記述するようにそのまま入力できます。
論理演算記号はEXCELと違って関数では無く、演算記号として＋や＊と同様に記述できます。
文を；で終了させるまでは見易くするために改行などを挟む事も可能です。
		
###	2)シーケンス命令を使用すれば書けるか？
他メーカのPLCとの互換性は無くなるかもしれませんが、シーケンス命令を使用すればパルス出力、タイマー、カウンター命令などを使用して簡潔にプログラムを記述することができます。
		
注意点として、OUT命令を例に挙げると、実行条件が成立してONする時と不成立になってOFFにする時のいずれの場合でもOUT命令が処理可能である必要があります。
		
シーケンス命令の実行条件に論理演算式を直接記述することも可能ですが、変換した際のステップ数がかさむため、下記の2段階で記述することをオススメします。
+ ステップ1.　代入文でシーケンス命令の実行条件に論理演算結果を代入する
+ ステップ2.　シーケンス命令を記述する

**例**
    
    //シーケンス命令内に論理式を記述する場合（ステップ数大）
        OUT（ (X0 OR Y0) AND NOT X1,Y0);
        
    //シーケンス命令の外で論理式を記述する場合（ステップ数小 推奨）
        M0 := (X0 OR Y0) AND NOT X1;
        OUT(M0,Y0);
	
### 3)条件分岐を記述する必要があるか？
IF文などの条件分岐を使用すると、ラダープログラム時には意識していなかった接点解放時の出力停止などの動作を正確に記述する必要が出てきます。
また、IF文中でシーケンス命令を使用すると2)の注意点で記載した理由によりOUTがSETのような動きになったりします。
		
したがって、ここでは下記のケースで条件分岐を記述することをおすすめします。
+ 条件分岐内で行う処理は代入と演算の場合
+ 条件分岐で記述した方がコードの見通しが良い場合
			
条件分岐の結果でシーケンス命令を実行させたい場合はシーケンス命令の実行条件に条件分岐の結果を代入して条件分岐文の外でシーケンス命令を記述しましょう。

**例**
    
    //D0が100以上になったときY0の出力を行う
    IF D0>=100 THEN
    	M0:=TRUE;　//ここにOUT(TRUE,Y0)と書いてすぐEND_IF;するとY0が入りっぱなしになる
	ELSE
    	M0:=FALSE;
    END_IF;
    OUT(M0,Y0);

※OUTは代入で書けるのですが、ここはあくまで例として用いています。

## 4．実行中プログラムのデバッグについて
ラダープログラムとは作法が若干異なります。
ラダープログラムと異なりプログラムモニタに関するツールボタンは用意されていません。
### 1)書込ーモニタの切り換え
+ メニューバーまたはショートカットキー(モニタ開始:F3),(モニタ停止:ALT+F3)で切り換えます
+ STプログラムでは**モニタ書込**は存在しません
### 2)RUN中書込について
+ モニタを停止してプログラムを編集します
+ メニューバーまたは Shift＋F4 でRUN中書込を行います
		
### 3)プログラム中で呼び出しているファンクションブロック内部のモニタ
+ プログラム中のファンクションブロック呼び出し文を右クリック
+ 「表示」－「選択部品のプログラムを開く」でファンクションブロックの内部プログラムが開きます
+ ラダーの時のように該当部分のダブルクリックでは開きません

## おわりに
ここに記載した事を頭に入れて、IF文などに惑わされずにプログラミングガイドを参照すれば簡単なラダー相当ならそれほど苦も無くST言語で記述できるのでは無いでしょうか。

大量の冗長な転送処理の最後にちょっと接点を制御したい、といった時に最初からST言語でプログラムが書けると楽な場面もあるかと思い記事にしました。

**その2**でパルス入力を扱うための接点命令などについて記載する予定です。

あまり書きぶりに満足していない記事なのでちょこちょこ改訂するかもしれません。

## 過去記事一覧
+ [過去記事一覧](https://qiita.com/fujiteruo/items/af2459d320e8109963db)