自作FunとFB

なぜ自作?

ファンクションとファンクションブロックはプログラムの共有が目的で、同じようなプログラムを複数の人がそれぞれで作っていたものを1つにして、同じプログラムをみんなで使いましょうというのが目的です
● 複数の人がバラバラで同じようなものを作るよりプログラムの作成工数が減ります
● 同じプログラムを使うことでプログラムの品質は一定になります

ファンクションを作るか? ファンクションブロックを作るか? どっち?

1スキャンで結果を出力できる処理内容ならファンクション
計算ならよほど大量の計算が必要でない限りファンクションで作ります
複数スキャン必要な処理ならファンクションブロック
複数スキャン必要な処理とは、通信処理、モーション、ファイル操作などがあげられます

ルール お作法的な

入出力
入力に何らかの値を入れれば出力にその結果を出力します
その入力と出力は以下の3つの基本形のどれかに合わせるようにします

実際はInput,Outoutは複数になるでしょうが、入力変数が10個とか多くなるようなら関係ある変数を構造体にしてまとめるのがいいでしょう

ファンクション
変数名 内容
入力 EN 実行
ONしているときにファンクション内部の処理を実行します
Input 入力パラメータ
出力 ENO
空白(Out) 戻り値
BOOL以外の時にこちらに出力される

ファンクションブロック(Execute型)
変数名 内容
入力 Execute 起動
常にFB内部は実行し続ています
Executeの立ち上がりで処理を開始します
ExecuteがOFFになっても完了するまで処理を続けます
処理が完了したらDoneかErrorのどちらかをONにします
Input 入力パラメータ
出力 Done 正常終了時にON
Busy 実行中にON
Error 異常終了時にON
ErrorID 異常コード出力
Output 処理結果

Execute型の各フラグは以下のタイムチャートのような動作をするように作ります


ファンクションブロック(Enable型)
変数名 内容
入力 Enable 実行
常にFB内部は実行し続ています
EnableがONしたらEnabledをONにして処理をします
EnableがOFFになったらEnableをOFFにして処理を終了します
Input 入力パラメータ
出力 Enabled 実行中
Output 処理結果


入力変数と出力変数と入出力変数
入力変数出力変数は値渡し(ByVal)です
入出力変数はポインタ渡し(ByRef)です

通常は入力変数出力変数を使います
大きな変数(例えばWORD型の配列10000個とか)を入力変数に入れたいときは入出力変数にするのがよいでしょう

その理由は・・・
入力変数は値をFBのインスタンス内の変数に値をコピーしてからFB内のプログラムを実行します
処理した結果を出力変数にコピーしてFBの外部に値を渡します(内部的にそうなっていると思います)
この処理はプログラマーからは見えないところで行われているので、コピーする時間だけスキャンタイムが伸びることに注意してください

それに対して入出力変数はコピーはせずに変数の値を直接読み書きします
コピー処理は行われないので大きなサイズの変数を入出力変数にしてもスキャンタイムが伸びることはありません

外部変数
使っちゃダメです
使っていいのはシステム定義変数のみ
ここにユーザが作ったグローバル変数が入った時点で部品化できずにそのプロジェクトだけで使用できるFun/FBになってしまいします
ユーザが作った変数を使いたい場合は入力変数にすべきです

入力チェック
入力変数に想定外の値が入ってきたときのエラー処理を忘れずやりましょう
入力変数に変数を入れなかった時のために必要なところは初期値も入れましょう

ErrorIDに入れる値
ErrorIDは基本的にFB内部で使用した命令のErrorIDをそのまま出力します
ErrorExがある場合はErrorIDExも出力変数に追加します
それ以外にオリジナルのエラーIDを付ける場合はErrorIDにオリジナルのエラーであるコードを入れて(例えば#FFFFなど)、ErrorIDExに詳細なエラーIDを入れるようにすると区別しやすくなります