Functionとは?
次はFunctionsについて話しします。Functionsを使用することによってあなたのプログラムスタイルが更にStep-upすることにあると思います。なぜかというとFunctionsを使うとプログラムを再利用、標準化と繋がります。作るのは一回、あとは使いまわし、です。
例えばこんな計算式があります。

もしプログラムの中に何回も繰り返し使用するのであれば、もちろんそのままMyValv3*25.4=MyVale4などCopy Pasteしてもよいです。ですが、もしやっばりこんな風に変更したい。どうします?プログラムの中に使ったところを全然見つけ出し、1つ1つ修正しにいく。効率ではないですね。

ここはFunctionの出番です。Functionという箱を作って、箱の外に一つのパラメータがあって、箱の中にそのパラメータを”なにかの計算”し、その結果をFunctionに出力します。
そしてその出力をMyVale2に繋がります。

そしてプログラムの中に何回も繰り返し使うなら、そのまま”箱”を再利用し、Inputのパラメータだけを変更すればOKです。

そして変更したいのであれば、一回だけ編集するだけでOKです。

Function作成
POUs>Add>POUします。
名前をつけて、Function選び、Return Valveを選択肢、Openします。
それでOKです。
では実際Functionをどう宣言するのか見てましょう。
こちらは簡単Function例です。
ばらしていくとこんな感じです。

戻り値はあくまてもOptions的なもので、必ず必要ではありません。
そしてこんな風に呼び出します。
もちろん、FunctionのInputパラメータ・Outputパラメータ複数もOKです。
VAR_OUTPUT .. END_VARの間に宣言すればOKです。
呼び出しするときこうなります。
そしてIN_OUTの形としてのパラメータもあります。
VAR_IN_OUTというKeywordを使えばOKです。
Functionの呼び方もあまり変わりません。
INPUT/OUTPUT/IN_OUT
私達はFunctionに対して使いまわしできる、INPUT,OUTPUT,IN_OUTのパラメータもあるとわかりした。でも、Functionを構成するときはINPUT,OUTPUT,IN_OUTその3つのパラメータ種類はなにか違うんでしょうか。

先の例からもう一度を説明します。
まず、実際Functionが呼び出されたときそのmyReal1とmyReal2の値を一回”COPY”しFunctionに渡します。そしてFunction演算したあとに演算結果をとmyReal3ととmyReal4にCopyする、になります。
そしてIN_OUTの場合は変数の”アドレス”をFunctionに渡し中に”直接”そのアドレスを参照し変数を書き読みします。
多分これだけではまだビンと来ない方がいるかもしれません。
もしINPUT/OUTPUTの場合だと、Functionのプログラムによる演算は影響されるのはFunction内だけ、になります。つまり、Function中のINPUTのパラメータを新しい値を与えても、実際はINPUTされた変数になにも影響ありません。なので、INPUTパラメータはINPUTパラメータの値をCOPYしFunctionの中に渡しします。
逆に、IN_OUTとして扱うとFunctionのプログラムによる演算は直接そのパラメータに影響します。実際IN_OUTはつまり変数の”Memory Address”をFunctionに渡しします。
例えば、いまMyFunction3というFunctionがあります。ST1という構造体をパラメータとして入れて、中にあるElementを*1.0、そしてOUTPUTします。
まずINPUT/OUTPUTの場合だと、一回INPUTの変数をOUTPUTの変数に転送し、そしてOUTPUTの変数の直接変更します。
次は、IN_OUTの場合だと、直接変数を書き読みすればOKです。
REFERENCEのやり方:
最後に
では、いつINPUT/OUTPUTでよいのか、いつIN_OUT/REFでよいか。どうやって決めるのでしょうか。私からみますと、
- もしそのパラメータはFunction内に影響されたくない・そしてパラメータは”一般”なData Type(BOOL,INT,REAL)など”大きくない”変数なら、INPUT/OUTPUTでもよい。
- もしそのパラメータはFunction内に直接影響されたくない、そしてパラメータは構造体・配列など”大きな”変数なら、REFERENCEを使ったほうがよいでしょう。前はINPUT/OUTPUTだと一回パラメータをCOPYすると言いました。パラメータは配列などの大きなメモリ領域だとかなりメモリの無駄になりますし、CPUの負担にもなります。
- もしそのパラメータはFunction内に直接影響してもよい、そしてパラメータは構造体・配列など”大きな”変数なら、IN_OUTを使うとよいでしょう。
はーい、お疲れ様です。