はじめに
プログラミングマニュアルプログラム設計編に以下の記述があります
「マクロ型ファンクションブロックのプログラム本体以外では、ファンクションブロックの引数は使用せずに、引数引き渡しに使用したデバイス/ラベルを使用してください。」
マクロ型の場合、ファンクションブロック型のラベルをプログラムの他の場所で使用しないという注意書きですが、内部的にどういう処理をしているのか調べてみました。
1.サンプルプログラム
用意したのは単純なプログラムなので特に説明はしません。
2.プログラム実行結果
マクロ型ファンクションブロックに直接引数を接続した方はプログラム中でファンクションブロック型のラベルを使用すると正常に動作していません。
直接引数を接続しない場合は特に問題なく正常動作しました。
3.プログラム変換結果を確認する
下記の2種類の変換結果を確認しました。
- エディタ上の右クリックで表示する変換結果(V1.110Q以降)
- プログラムファイルの照合結果での変換結果
エディタ上の右クリックで表示する変換結果
0 *マクロ型FB引数指定
1 LD M0
1 OUT FbPou_1.i_b_label ※FB型ラベルに出力しているようだがステップ増えてない
1 FBCALL FbPou (FbPou_1)
5 LD FbPou_1.o_b_label
5 OUT M1
5 LD FbPou_1.o_b_label
7 OUT Y0
9 LD FbPou_1.i_b_label
11 OUT Y1
13 *マクロ型FB引数無指定
14 LD M0
16 OUT FbPou_2.i_b_label ※FB型ラベルへの出力でステップ増えている
18 FBCALL FbPou (FbPou_2)
22 LD FbPou_2.o_b_label
24 OUT Y10
26 LD FbPou_2.i_b_label
28 OUT Y11
30 END
プログラムファイルの照合結果での変換結果
0 ;*マクロ型FB引数指定
1 LD M0
3 OUT M1 ※FB型ラベルのメモリを介さずに処理が行われている
5 LD LV:0.3 ※LV:0.3には何も代入されていない
7 OUT Y0
9 LD LV:0.2 ※LV:0.2には何も代入されていない
11 OUT Y1
13 ;*マクロ型FB引数無指定
14 LD M0
16 OUT LV:34.2 ※FB呼び出し外でラベルメモリに出力
18 LD LV:34.2
20 OUT LV:34.3 ※FBはラベルメモリで処理を行う
22 LD LV:34.3 ※ステップ16で値が代入されている
24 OUT Y10
26 LD LV:34.2 ※ステップ18で値が代入されている
28 OUT Y11
30 END
V1.110Qで手軽に変換結果が表示されるようにはなったのですがマクロ型でもFBCALLが記述されていたりと、中間ファイルと受け取れば良いのかという結果が表示されます。
シーケンサに書き込まれる変換結果は「オンライン-照合」から確認できます。
ラベルはラベルメモリアドレスで記述されるので解読は難しくなります。
マクロ型ファンクションブロックは平文のプログラムに書き直されています。
ファンクションブロックの呼び出しで引数を直接指定した場合、インプットとアウトプットのラベルメモリには引数に引き渡したデバイスが直接記述されていました。
これではプログラムの他の部分でファンクションブロック型ラベルを参照しても何も値が入っていません。
ファンクションブロックの呼び出しで引数を直接指定しない場合はラベルメモリを介して処理が行われていました。
ですので、プログラムの他の部分でファンクションブロック型ラベルの参照が可能になります。
おわりに
いままで、マニュアルの注意書きが気持ち悪く感じてマクロ型ファンクションブロックの使用は考えていなかったのですが、スキャンタイムを考慮する必要がある分野では無視できないと考えて調べてみました。
結論としては、
「ファンクションブロックの呼び出しに直接引数を記述しなければサブルーチン型と同様にプログラム内でファンクションブロック型ラベルが使用できる」
ということになりました。
実はST言語で記述するにしてもファンクションブロックの呼び出しに直接引数を記述しない方がステップ数的に有利だったりするので、引数への代入や引数からの取り出しは呼び出しの外で行うのをデフォルトとしていこうと考えています。