Function blocks converted to a user-defined function

Convert a function block to a user-defined function to save program steps

General usage

The main purpose of these functions is to simplify the replacement of function blocks (FBs) by functions (FUNs). Multiple FB instances in separate subroutines are replaced by one function in one subroutine.

Example

Function block

Converted function

Restrictions:

Not all Panasonic instructions can be used in one common function. Examples of instruction that cannot be used in one common function:

  • Some high speed counter instructions like F166_HighSpeedCounter_Set, F165_HighSpeedCounter_Cam

  • Some positioning instructions like F166_PulseOutput_Set, F171_PulseOutput_Trapezoidal

This must be checked in detail.

Advantages:

  • Can require much less program code

  • Can require much less relays (R)

  • Can be used in loops using arrays of the memory DUTs

Disadvantages:

  • It requires additional development and maintenance work

  • The converted function must be tested very carefully

  • It requires more effort from the user

  • Monitoring is more difficult because you have no instance which can be monitored, only the last call is monitored

  • It can require more data registers (DT)

  • The PLC performance is decreased, scan time is increased

NOTE
  • The behavior of the timer functions may be slightly different compared to the timer FBs

  • Test very carefully whether the behavior of the new function corresponds to the behavior of the FB, especially when the new function is called several times.

Recommendations for use:

  • Functions instead of function blocks should only be used if really needed

  • Functions instead of function blocks should only be used as much as really necessary

  • Analyze very carefully which function block should be converted to obtain the maximum benefit with minimum work

  • The main criteria for deciding whether a function block should be converted are: How often is the function block called, how many steps does the function block require?

Estimation of program code steps saved

This is the formula for calculating how many program code steps can be saved.

The current situation is as follows:

  • A given function block

  • Is called X times

  • Uses Y steps => total number of steps: X * Y steps

  • Uses TON, SR, pulsed flags

The given FB can be replaced by a function which requires the following:

  • Additional steps for X calls to copy the memory DUT data twice, i.e. X * 2 * 7 steps approximately (e.g. for two FP10_BKMV)

  • Y * 2 steps for one common function call (some additional steps are assumed)

  • One common call of:

    • TON_FUN using xxx steps

    • SR_FUN using xxx steps

    • R_TRIG_FUN using xxx steps

Calculation example for FP0H

This calculation example gives only approximate figures.

  • A given function block

  • Is called 30 times

  • Uses 750 steps => total number of steps: 30 * 750 steps = 22500 steps

  • Uses TON, SR, pulsed flags

The given FB can be replaced by a function which requires the following:

  • Additional steps for 30 calls to copy the memory DUT data twice, i.e. 30 * 2 * 7 steps = 420 steps (e.g. for two FP10_BKMV)

  • 750 * 2 steps for one common function call = 1500 steps (some additional steps are assumed)

  • One common call of:

    • TON_FUN using 200 steps

    • SR_FUN using 35 steps

    • R_TRIG_FUN using 35 steps

Total number of steps: 420 steps + 1500 steps + 200 steps + 35 steps + 35 steps = 2190 steps

Result: Using this function you save approx. 22500 steps - 2190 steps = 20310 steps.

How to convert a function block to a user-defined function

Procedure of conversion from a user function block XXX to a function XXX_FUN

We recommend to keep the name conventions.

  1. Make a copy of your FB XXX and call it XXX_FUN

    Keep the FB XXX, do not delete it!

  2. Use the POU properties dialog to change the copy of your FB to a function
  3. Define a memory DUT e.g. XXX_FUN_INSTANCE_DUT which contains all variables with memory and all memory DUTs of other called function-of-FBs functions
  4. Define an input/output variable VAR_IN_OUT with this memory DUT, e.g. dutXXX of data type XXX_FUN_INSTANCE_DUT
  5. In the function body, do the following for all variables which require a memory e.g. because of usage in SET/RESET coils, in conditional calculations or in increasing/decreasing variable values:
    1. Define the same variable in the memory DUT XXX_FUN_INSTANCE_DUT
    2. Replace the variable by the corresponding memory DUT member
    3. If some of the variables replaced by memory variables in the memory DUT are outputs at the end of the function, they must be assigned to the corresponding output variable.
  6. Replace all FB instances with the memory DUT of the corresponding function, which has to be defined in the memory DUT XXX_FUN_INSTANCE_DUT
  7. Replace all FB instance calls with the corresponding function call with the corresponding memory DUT

    If a standard FB with EN/ENO has to be replaced, put the corresponding function in an EN/ENO function and call this function. For example, put the function TON_FUN in the EN/ENO function E_TON_FUN and call it.

  8. Replace all pulsed flags with the corresponding RTRIG_FUN/FTRIG_FUN call
  9. Test very carefully whether the behavior of the new function corresponds to the behavior of the FB, especially when the new function is called several times

Conversion examples LD/FBD

Assumption: a function XXX with a VAR_IN_OUTdutXXX of data type XXX_FUN_INSTANCE_DUT is used in all examples

Operation

Original programming example

Converted programming example

 

Calls

 

FB POU header

FUN POU header

   

DUT XXX_FUN_INSTANCE_DUT

Set

Reset

KEEP

Conditional assignment, calculation

Increasing/decreasing variable values

Pulsed flags

At the end of the function: If needed, assign some memory variables to the corresponding output variables:

SR

RS

TON

TM_100ms

Conversion examples ST

Assumption: a function XXX with a VAR_IN_OUTdutXXX of data type XXX_FUN_INSTANCE_DUT is used in all examples

Operation

Original programming example

Converted programming example

Set

Reset

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);

Conditional assignment, calculation

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;

Increasing/decreasing variable values

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

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

Pulsed flags

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;

At the end of the function: If needed, assign some memory variables to the corresponding output variables:

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);

Modified on: 2021-03-30Feedback on this pagePanasonic hotline