Bloques de función convertidas a funciones definidas por el usuario

Convierte un bloque de función en una función definidas por el usuario para ahorra pasos de programa

Uso general

El principal propósito de estas funciones es simplificar la sustitución de los bloques de función (FBs) por funciones (FUNs). Varias instancias a FB en subrutinas separadas se reemplazan por una función en una subrutina.

Ejemplo

Bloque de función

Función convertida

Restricciones:

No todas las instrucciones Panasonic se pueden utilizar en una función común. Ejemplo de instrucciones que no se pueden utilizar en una función común:

  • Algunas instrucciones del contador de alta velocidad F166_HighSpeedCounter_Set, F165_HighSpeedCounter_Cam

  • Algunas instrucciones de posicionamiento como F166_PulseOutput_Set, F171_PulseOutput_Trapezoidal

Comprobar estas restricciones en detalle.

Ventajas:

  • Se necesita mucho menos código de programa

  • Se necesitan menos relés internos (R)

  • Se pueden utilizar en bucles utilizado arrays de las DUTs

Desventajas:

  • Se necesita tiempo y esfuerzo de desarrollo y mantenimiento adicional

  • Se debe verificar con precaución la función convertida

  • Necesita una mayor comprensión de la función por parte del usuario

  • La monitorización es más compleja puesto que no se pueden monitorizar instancias, solo se monitoriza la última llamada.

  • Se necesitan más registros de datos (DT)

  • Aumenta el ciclo de scan y disminuye el rendimiento del PLC

NOTA
  • El comportamiento de las funciones de temporizador puede diferir ligeramente comparado con los FBs de tipo temporizador

  • Comprobar en detalle si el comportamiento de la nueva función se corresponde con el comportamiento del FB especialmente si se llama varias veces a la nueva función.

Recomendaciones de uso:

  • Utilizar Funciones en lugar de Bloques de función solamente cuando sea necesario

  • No utilizar Funciones en lugar de Bloques de función si no es realmente necesario

  • Analizar en detalle que bloque de función debería convertirse para obtener el máximo beneficio con el mínimo esfuerzo

  • Los principales criterios para decidir si se debe convertir un bloque de función son: ¿Cuántas veces se llama al bloque de función? ¿Cuántos pasos necesita el bloque de función?

Estimación del ahorro en número de pasos de código de programa

Con la siguiente fórmula se puede calcular cuántos pasos de programa se pueden ahorrar con la conversión.

Para la siguiente situación actual:

  • Dado un bloque de función

  • Que se llama X veces

  • Utiliza Y pasos => Número total de pasos: X * Y pasos

  • Utiliza TON, SR, relés de pulso

El FB descrito puede reemplazarse por una función con los siguientes requisitos:

  • Pasos adicionales para X llamadas para copiar los datos de la DUT dos veces, es decir. X * 2 * 7 pasos aproximadamente (por ejemplo, para dos FP10_BKMV)

  • Y * 2 pasos para una llamada a la función común (se toman algunos pasos adicionales)

  • Una llamada común de:

    • TON_FUN que utiliza xxx pasos

    • SR_FUN que utiliza xxx pasos

    • R_TRIG_FUN que utiliza xxx pasos

Cálculo de ejemplo para FP0H

Este ejemplo proporciona solamente unas cifras aproximadas.

  • Dado un bloque de función

  • Que se llama 30 veces

  • Utiliza 750 pasos => Número total de pasos: 30 * 750 pasos = 22.500 pasos

  • Utiliza TON, SR, relés de pulso

El FB descrito puede reemplazarse por una función con los siguientes requisitos:

  • Pasos adicionales para 30 llamadas para copiar los datos de la DUT dos veces, es decir, 30 * 2 * 7 pasos aproximadamente (por ejemplo, para dos FP10_BKMV)

  • 750 * 2 pasos para una llamada a la función común (se toman algunos pasos adicionales)

  • Una llamada común de:

    • TON_FUN que utiliza 200 pasos

    • SR_FUN que utiliza 35 pasos

    • R_TRIG_FUN que utiliza 35 pasos

Nº total de pasos: 420 pasos + 1.500 pasos + 200 pasos + 35 pasos + 35 pasos = 2.190 pasos

Resultado: Utilizando esta función se ahorra aproximadamente 22.500 pasos - 2.190 pasos = 20.310 pasos.

Cómo convertir un bloque de función en una función definida por el usuario

Procedimiento de conversión de un bloque de función de usuario XXX a una función XXX_FUN

Se recomienda mantener las convenciones a la hora de asignar nombres a las funciones.

  1. Realizar una copia del FB XXX y nombrar como XXX_FUN

    ¡No borrar el FB XXX!

  2. Utilizar el cuadro de diálogo Propiedades de la POU para cambiar la copia del FB a una función
  3. Definir una DUT, por ejemplo, XXX_FUN_INSTANCE_DUT que contiene todas las variables con memoria y todas las DUTs de otras llamadas
  4. Definir una variable de Entrada/Salida VAR_IN_OUT con esta DUT, por ejemplo dutXXX del tipo de datos XXX_FUN_INSTANCE_DUT
  5. En el cuerpo de la función, realizar lo siguiente para todas las variables que necesitan memoria, por ejemplo, porque utilizan contactos SET/RESET, en cálculos condicionales o en el incremento/decremento del valor de las variables:
    1. Definir la misma variable en la memoria DUT XXX_FUN_INSTANCE_DUT
    2. Reemplazar la variable por el correspondiente elemento del área de memoria de la DUT
    3. Si algunas de las variables reemplazadas por el área de memoria en la DUT son salidas de una función, tienen que ser asignadas a la variable de salida correspondiente.
  6. Reemplazar todas las instancias del FB con el área de memoria de la DUT de la función correspondiente, que ha sido definida en la DUT XXX_FUN_INSTANCE_DUT
  7. Reemplazar todas las llamadas a las instancias del FB por las llamadas a la función correspondiente con el área de memoria de la DUT correspondiente

    Si se ha reemplazado un FB estándar con EN/ENO, introducir la correspondiente función EN/ENO y realizar la llamada a esta función. Por ejemplo, introducir TON_FUN en la función EN/ENO E_TON_FUN y ejecutar la llamada.

  8. Reemplazar todas los registros de pulso con la correspondiente llamada RTRIG_FUN/FTRIG_FUN
  9. Comprobar en detalle si el comportamiento de la nueva función se corresponde con el comportamiento del FB especialmente si se llama varias veces a la nueva función.

Ejemplos de conversión LD/FBD

En todos los ejemplos se utiliza una function XXX con una VAR_IN_OUT dutXXX del tipo de datos XXX_FUN_INSTANCE_DUT

Operación

Ejemplo de programación inicial

Ejemplo de programación convertida

 

Llamadas

 

FB Cabecera de la POU

FUN Cabecera de la POU

   

DUT XXX_FUN_INSTANCE_DUT

Set

Reset

KEEP

Asignación condicional, cálculos

Incremento/decremento de valores de variables

Relés de pulso

Al final de la función: Si es necesario, asignar algunas variables a las variables de salida correspondientes:

SR

RS

TON

TM_100ms

Ejemplos de conversión ST

En todos los ejemplos se utiliza una function XXX con una VAR_IN_OUT dutXXX del tipo de datos XXX_FUN_INSTANCE_DUT

Operación

Ejemplo de programación inicial

Ejemplo de programación convertida

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

Asignación condicional, cálculos

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;

Incremento/decremento de valores de variables

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

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

Relés de pulso

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;

Al final de la función: Si es necesario, asignar algunas variables a las variables de salida correspondientes:

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

Modificado el: 2021-08-20Comentarios sobre esta páginaLínea directa de Panasonic