ファンクションブロックのユーザ定義ファンクションへの変換

ファンクションブロックをユーザ定義ファンクションに変換してプログラムステップを節約します。

一般的な使用

これらのファンクションの主な目的は、ファンクションブロック(FB)をファンクション(FUN)に簡単に置換できるようにすることです。別々のサブルーチンにある複数のFBインスタンスが、1つのファンクションで1つのサブルーチンに置換されます。

ファンクションブロック

変換後のファンクション

制限事項:

当社の命令がすべて1つの共通ファンクションで使用できるわけではありません。1つの共通ファンクション内で使用できない命令を次に例示します。

  • F166_HighSpeedCounter_SetF165_HighSpeedCounter_Camなどの高速カウンタ命令

  • F166_PulseOutput_SetF171_PulseOutput_Trapezoidalなどの位置決め命令

これについては、詳しく確認してください。

利点:

  • 必要なプログラムコードが大幅に減少する

  • 必要なリレー(R)が大幅に減少する

  • メモリDUTの配列を使用することでループでの使用ができる

不都合な点:

  • 追加的な開発およびメンテナンス作業が必要

  • 変換後のファンクションのテストに注意が必要

  • ユーザ側の労力が必要

  • モニタできるインスタンスがなく最後の呼出のみがモニタされるため、モニタが困難

  • 多くのデータレジスタ(DT)が必要になる場合がある

  • PLCパフォーマンスの低下、スキャン時間の増加

注記
  • タイマファンクションの動作はタイマFBと若干異なります。

  • 新しいファンクションが複数回呼び出される場合は特に、新しいファンクションの動作がFBの動作と対応しているか、よく注意してテストしてください。

使用についての推奨事項:

  • ファンクションブロックをファンクションで代用することは、どうしても必要な場合のみにしてください。

  • ファンクションブロックをファンクションで代用することは、必要な部分のみにしてください。

  • 最小限の作業で最大限の利益が得るにはどのファンクションブロックを変換すべきか、注意して分析を行ってください。

  • ファンクションブロックの変換が必要かどうかの主な判断基準は以下のとおりです。ファンクションブロックを呼び出す頻度、ファンクションブロックで必要なステップ数

節約可能なプログラムコードステップ数の見積り

プログラムコードのステップがどの程度節約できるかを計算する方法です。

現在の状況は以下のとおりです。

  • 特定のファンクションブロック1つ

  • 呼び出し回数はX回

  • Y個のステップを使用 => ステップ数合計: X * Y ステップ

  • TONSR、パルス出力完了フラグを使用

このFBは、下記を必要とするファンクションに置換されます。

  • X回呼び出しを行いメモリDUTを2回コピーする追加ステップ。およそ、X * 2 * 7 ステップ(例: 2つのFP10_BKMV)

  • 1回の共通ファンクションの呼び出しにY * 1.5 ステップ (さらにステップが必要な場合もあります)

  • 以下の共通呼び出し1回:

    • TON_FUN、xxxステップ使用

    • SR_FUN、xxxステップ使用

    • R_TRIG_FUN、xxxステップ使用

FP0Hの計算例

この計算例は概算のみです。

  • 特定のファンクションブロック1つ

  • 呼び出し回数は30回

  • 750個のステップを使用 => ステップ数合計: 30 * 750 ステップ = 22500 ステップ

  • TONSR、パルス出力完了フラグを使用

このFBは、下記を必要とするファンクションに置換されます。

  • 30回呼び出しを行いメモリDUTを2回コピーする追加ステップ。30 * 2 * 7 ステップ = 420 ステップ(例: 2つのFP10_BKMV)

  • 1回の共通ファンクションの呼び出しに750 * 2 ステップ = 1500ステップ(さらにステップが必要な場合もあります)

  • 以下の共通呼び出し1回:

    • TON_FUN、200ステップ使用

    • SR_FUN、35ステップ使用

    • R_TRIG_FUN、35ステップ使用

ステップ数合計: 420ステップ + 1500ステップ + 200ステップ + 35ステップ + 35ステップ = 2190ステップ

結果: このファンクションの使用で削減できるステップは、およそ 22500ステップ - 2190ステップ = 20310ステップ です。

ファンクションブロックのユーザ定義ファンクションへの変換方法

ユーザファンクションブロックXXXからファンクションXXX_FUNへの変換の手順

命名規則はそのままにすることをおすすめします。

  1. FB XXXのコピーを作成し、これをXXX_FUNと名づけます。

    FB XXXはそのままで、削除しないでください。

  2. 「POUプロパティ」ダイアログを使用して、FBのコピーをファンクションに変更します。
  3. メモリを使用するすべての変数、FBファンクションから呼び出されたその他のファンクションのメモリDUTをすべて含むメモリDUTを定義づけます(XXX_FUN_INSTANCE_DUTなど)。
  4. メモリDUTを使用する入出力変数VAR_IN_OUTを定義します(XXX_FUN_INSTANCE_DUTのデータ型のdutXXXなど)
  5. ファンクションのボディで、SET/RESETコイルを使用する、条件付きで計算に使用する、または増減する変数値を使用する、などの理由でメモリを必要とする変数に対し、次のようにします。
    1. メモリDUT XXX_FUN_INSTANCE_DUTで同じ変数を定義します。
    2. 変数を、該当のメモリDUT要素で置換します。
    3. メモリDUTでメモリ変数に置換された変数がファンクションの最後に出力される場合、それが対応する出力変数に割り当てが必要なものです。
  6. すべてのFBインスタンスについて、対応するファンクションのメモリDUTで置換します。対応するファンクションは、メモリDUT XXX_FUN_INSTANCE_DUTで定義されたものです。
  7. すべてのFBインスタンスの呼び出しを、対応するメモリDUTを使用して、対応するファンクション呼び出しに置換します。

    EN/ENOを使用する通常のFBを置換する必要がある場合は、対応するファンクションをEN/ENOファンクション内に置いて、このファンクションを呼び出します。たとえば、ファンクションTON_FUNEN/ENOファンクションE_TON_FUN内に置いて、これを呼び出します。

  8. すべてのパルス出力完了フラグを、対応するRTRIG_FUN/FTRIG_FUN呼び出しに置換します。
  9. 新しいファンクションが複数回呼び出される場合は特に、新しいファンクションの動作がFBの動作と対応しているか、よく注意してテストしてください。

LD/FBDの変換例

前提: すべての例では、データ型XXX_FUN_INSTANCE_DUTVAR_IN_OUTdutXXXを使用するファンクションXXXが使用されています。

処理

元のプログラミング例

変換後のプログラミング例

 

呼び出し

 

FB POUヘッダ

FUN POUヘッダ

   

DUT XXX_FUN_INSTANCE_DUT

セット

リセット

KEEP

条件付きの計算

増減する変数値

パルス出力完了フラグ

ファンクション終了時: 必要に応じて、対応する出力変数にメモリ変数を割り当てます。:

SR

RS

TON

TM_100ms

STの変換例

前提: すべての例では、データ型XXX_FUN_INSTANCE_DUTVAR_IN_OUTdutXXXを使用するファンクションXXXが使用されています。

処理

元のプログラミング例

変換後のプログラミング例

セット

リセット

if (bSet) then
	bSR1:=true;
elsif (bReset) then
	bSR1:=false;
end_if;
if (bSet) then
	dutInstance.bSR1:=true;
elsif (bReset) then
	dutInstance.bSR1:=false;
end_if;

KEEP

bRS1 := KEEP(SetTrigger := bSet,
             ResetTrigger := bReset);
dutInstance.bRS1 := KEEP(SetTrigger := bSet,
                         ResetTrigger := bReset);

条件付きの計算

if (bReset) then
	di1:=0;
end_if;
if (bTrig) then
	w1 := ROL(IN := w1, N := 1);
end_if;
if (bReset) then
	dutInstance.di1 :=0;
end_if;
if (bTrig) then
	dutInstance.w1 := ROL(IN := dutInstance.w1, N := 1);
end_if;

増減する変数値

di1:=di1+1;
w2:=w2 OR w1;
dutInstance.di1:=dutInstance.di1+1;

dutInstance.w2:=dutInstance.w2 OR dutInstance.w1;

パルス出力完了フラグ

if (DF(bSet) OR DFN(bSet)) then
	di2:=di2+1;
end_if;
R_TRIG_FUN(CLK := bSet,
           dutInstance := dutInstance.dutRTrig1,
           Q => bQTemp1);
F_TRIG_FUN(CLK := bSet,
           dutInstance := dutInstance.dutFTrig1,
           Q => bQTemp2);
if (bQTemp1 OR bQTemp2) then
    dutInstance.di2:=dutInstance.di2+1;
end_if;

ファンクション終了時: 必要に応じて、対応する出力変数にメモリ変数を割り当てます。:

bSR1:=dutInstance.bSR1;
bRS1:=dutInstance.bRS1;
di1:=dutInstance.di1;
di2:=dutInstance.di2;
w1:=dutInstance.w1;
w2:=dutInstance.w2;

SR

SR_1(S1 := bSet,
     R := bReset,
     Q1 => bSR2);
SR_FUN(Set := bSet,
        Reset := bReset,
        dutInstance := dutInstance.dutSR_1, Q1 => bSR2);

RS

RS_1(S := bSet,
      R1 := bReset,
      Q1 => bRS2);
RS_FUN(Set := bSet,
        Reset := bReset,
        dutInstance := dutInstance.dutRS_1,
        Q1 => bRS2);

TON

TON1(IN := bIN,
      PT := T#10S,
      Q => bQ1, ET => tET1);
TON_FUN(IN := bIN,
        PT := T#10s,
        dutInstance := dutInstance.dutTon1,
        Q => bQ1, ET => dutInstance.tET1);

TM_100ms

TM_100ms_1(start := bIN,
            SV := 100,
            T => bT1,
            EV => iEV1);
TM_100ms_FUN(start := bIN,
              SV := 100,
              dutInstance := dutInstance.dutTM_100ms_1,
              T => bT1, EV => dutInstance.iEV1);

最終修正日: 2021-05-13このページに関するフィードバックお問い合わせ窓口