{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_cL";
    S7_BlockNumber := "15106";
    S7_BlockTitle := "MLC_56T";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_IECCheck := "TRUE";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION_BLOCK "FB15106_ZC_CALCULO_LIMP_4_MOD"
    VAR_INPUT
        { S7_MLC := "MLC_4AX" }
        Etapa : Bool;
        Pulso1Seg : Bool;
        EnMarcha : Bool;
        { S7_MLC := "MLC_44a" }
        SP_Tiempo : Int;
        { S7_MLC := "MLC_56Q" }
        SP_Salida1 : Real;
        { S7_MLC := "MLC_pG" }
        SP_Salida2 : Real;
        { S7_MLC := "MLC_pq" }
        SP_Salida3 : Real;
        { S7_MLC := "MLC_4kM" }
        SP_Salida4 : Real;
    END_VAR
    VAR_IN_OUT
        { S7_MLC := "MLC_3xA" }
        EtapaTiempoRestante : Int;
        { S7_MLC := "MLC_3W2" }
        Salida1 : Bool;
        { S7_MLC := "MLC_NM" }
        Salida2 : Bool;
        { S7_MLC := "MLC_dX" }
        Salida3 : Bool;
        { S7_MLC := "MLC_4jc" }
        Salida4 : Bool;
    END_VAR
    VAR RETAIN
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_PorcentajeSalida1 : Real;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_PorcentajeSalida2 : Real;
    END_VAR
    VAR
        s_PorcentajeSalida3 : Real;
        s_PorcentajeSalida4 : Real;
    END_VAR
    VAR RETAIN
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_PorcentajeRestante : Real;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_CalculoTiempoSalida1 : Int;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_CalculoTiempoSalida2 : Int;
    END_VAR
    VAR
        s_CalculoTiempoSalida3 : Int;
        s_CalculoTiempoSalida4 : Int;
    END_VAR
    VAR RETAIN
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_CalculoTiempoRestante : Int;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_TiempoSalida1 : Int;
        {
            S7_Access := "ReadOnly := External";
            S7_Visibility := "Hidden := External"
        }
        s_TiempoSalida2 : Int;
    END_VAR
    VAR
        s_TiempoSalida3 : Int;
        s_TiempoSalida4 : Int;
        { S7_Setpoint := "False" }
        S_TON : _.UDT_ZC_DISP_TON;
        { S7_Setpoint := "True" }
        s_TiempoTotal : Int;
        s_ContadorTiempo : Int;
    END_VAR

    { S7_Language := "SCL" }
    NETWORK
        REGION DESCRIPCION
        //=======================================================================
        // (C)Copyright ZeusControl 2024 - 2026
        //=======================================================================
        (*
        ### Información del Sistema
        | Hardware Compatible | Entorno de Ingeniería |
        |---------------------|-----------------------|
        | PLC serie 1200/1500 | TIA Portal 18         |
        
        ---
        ### Descripción Funcional
        Bloque de funcion que implementa el cálculo y la distribución temporal de la limpieza de 4 módulos, asignando a cada uno un porcentaje configurable del tiempo total de la etapa. A partir de los porcentajes validados y del tiempo total, calcula los tiempos individuales de cada módulo y activa secuencialmente la salida correspondiente en función de un contador interno en segundos.
        
        Funcionalidades principales:
        - Traspaso y validación de porcentajes: se leen los porcentajes de cada uno de los 4 módulos (`SP_Salida1` a `SP_Salida4`) y se comprueba que su suma no supere `100.0`. Si la suma supera dicho umbral, se asigna por defecto un valor de seguridad de `10.0` a cada uno de los cuatro porcentajes, evitando estados incoherentes.
        - Cálculo de tiempos individuales: para cada módulo, si su porcentaje es distinto de cero, se calcula el tiempo correspondiente como `Porcentaje * SP_Tiempo / 100`, truncado a entero mediante `REAL_TO_INT`.
        - Cálculo del tiempo total: se obtiene como la suma de los cuatro tiempos calculados y se utiliza para acotar el contador interno.
        - Contador de etapa: mientras `Etapa` está activa, `EnMarcha` esté activado y `Pulso1Seg` genere un pulso por segundo, se incrementa el contador `#s_ContadorTiempo` hasta alcanzar `#s_TiempoTotal`, momento en el que se reinicia a `0` para comenzar un nuevo ciclo.
        - Activación secuencial de salidas: cada salida (`Salida1`, `Salida2`, `Salida3`, `Salida4`) se activa cuando el contador se encuentra en el intervalo de tiempo correspondiente a su módulo. `Salida4` se activa por descarte cuando ninguna de las tres anteriores está activa.
        - Reset al salir de etapa: cuando `Etapa` se desactiva, el contador y todas las salidas se ponen a cero.
        - Cálculo del tiempo restante de etapa (`EtapaTiempoRestante`): se calcula en función de la salida activa como la diferencia entre el tiempo acumulado del módulo y el contador actual. Si el resultado es negativo, se satura a `0`.
        
        > **Restricciones:** Ninguna.
        
        ---
        ### Dependencias Requeridas
        | Tipo | Elementos |
        |------|-----------|
        | FC   | - |
        | FB   | - |
        | DB   | - |
        | UDT  | - |
            
        ---
        ### Historial de Cambios
        | Versión  | Fecha      | Técnico | Cambios |
        |----------|------------|---------|---------|
        | 01.00.00 | 12.09.2023 | (HCR)   | Primera versión. |
        *)
        END_REGION DESCRIPCION
        
        
        //  ==========================================================================================================
        REGION TRASPASO_PARAMETROS
            
            //  =====================================================================================
            //  TRASPASO DE PARAMETROS DE PORCENTAJE
            //  Se revisa los limites de los porcentajes metidos en pantalla
            IF (#SP_Salida1 + #SP_Salida2 + #SP_Salida3 + #SP_Salida4) > 100.0 THEN
                #s_PorcentajeSalida1 := 10.0;
                #s_PorcentajeSalida2 := 10.0;
                #s_PorcentajeSalida3 := 10.0;
                #s_PorcentajeSalida4 := 10.0;
            ELSE
                #s_PorcentajeSalida1 := #SP_Salida1;
                #s_PorcentajeSalida2 := #SP_Salida2;
                #s_PorcentajeSalida3 := #SP_Salida3;
                #s_PorcentajeSalida4 := #SP_Salida4;
            END_IF;
            
            
        END_REGION
        
        
        //  ==========================================================================================================
        REGION CALCULOS
            
            //  =====================================================================================
            //  CALCULO DE TIEMPO DE PASO
            //  MODULO 1
            IF #s_PorcentajeSalida1 <> 0.0 THEN
                #s_CalculoTiempoSalida1 := REAL_TO_INT((#s_PorcentajeSalida1 * #SP_Tiempo) / 100.0);
            END_IF;
            
            //  MODULO 2
            IF #s_PorcentajeSalida2 <> 0.0 THEN
                #s_CalculoTiempoSalida2 := REAL_TO_INT((#s_PorcentajeSalida2 * #SP_Tiempo) / 100.0);
            END_IF;
            
            //  MODULO 3
            IF #s_PorcentajeSalida3 <> 0.0 THEN
                #s_CalculoTiempoSalida3 := REAL_TO_INT((#s_PorcentajeSalida3 * #SP_Tiempo) / 100.0);
            END_IF;
            
            //  MODULO 4
            IF #s_PorcentajeSalida4 <> 0.0 THEN
                #s_CalculoTiempoSalida4 := REAL_TO_INT((#s_PorcentajeSalida4 * #SP_Tiempo) / 100.0);
            END_IF;
            
            #s_TiempoTotal := #s_CalculoTiempoSalida1 + #s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida3 + #s_CalculoTiempoSalida4;
            
        END_REGION
        
        
        //  ==========================================================================================================
        REGION SALIDAS
            IF #Etapa THEN
                
                IF #s_ContadorTiempo < #s_TiempoTotal THEN
                    IF #Pulso1Seg AND #EnMarcha THEN
                        #s_ContadorTiempo += 1;
                    END_IF;
                ELSE
                    #s_ContadorTiempo := 0;
                END_IF;
                
                //  ACTIVACION 1
                IF #s_ContadorTiempo < #s_CalculoTiempoSalida1 AND #s_CalculoTiempoSalida1 <> 0 THEN
                    #Salida1 := TRUE;
                ELSE
                    #Salida1 := FALSE;
                END_IF;
                
                //  ACTIVACION 2
                IF #s_ContadorTiempo >= #s_CalculoTiempoSalida1 AND #s_ContadorTiempo < (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1) AND #s_CalculoTiempoSalida2 <> 0 THEN
                    #Salida2 := TRUE;
                ELSE
                    #Salida2 := FALSE;
                END_IF;
                
                //  ACTIVACION FLIP 3
                IF #s_ContadorTiempo >= (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1) AND #s_ContadorTiempo < (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1 + #s_CalculoTiempoSalida3) AND #s_ContadorTiempo <> 0 THEN
                    #Salida3 := TRUE;
                ELSE
                    #Salida3 := FALSE;
                END_IF;
                
                //  ACTIVACION FLIP 4
                #Salida4 := NOT #Salida1 AND NOT #Salida2 AND NOT #Salida3;
                
            ELSE
                #s_ContadorTiempo := 0;
                #Salida1 := FALSE;
                #Salida2 := FALSE;
                #Salida3 := FALSE;
                #Salida4 := FALSE;
            END_IF;
            
            //  ACTIVACION 1
            IF #s_ContadorTiempo < #s_CalculoTiempoSalida1 AND #s_CalculoTiempoSalida1 <> 0 THEN
                #Salida1 := TRUE;
            ELSE
                #Salida1 := FALSE;
            END_IF;
            
            //  ACTIVACION 2
            IF #s_ContadorTiempo >= #s_CalculoTiempoSalida1 AND #s_ContadorTiempo < (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1) AND #s_CalculoTiempoSalida2 <> 0 THEN
                #Salida2 := TRUE;
            ELSE
                #Salida2 := FALSE;
            END_IF;
            
            //  ACTIVACION FLIP 3
            IF #s_ContadorTiempo >= (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1) AND #s_ContadorTiempo < (#s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida1 + #s_CalculoTiempoSalida3) AND #s_ContadorTiempo <> 0 THEN
                #Salida3 := TRUE;
            ELSE
                #Salida3 := FALSE;
            END_IF;
            
            //  ACTIVACION FLIP 4
            #Salida4 := NOT #Salida1 AND NOT #Salida2 AND NOT #Salida3;
            
            IF NOT #Etapa THEN
                #Salida1 := #Salida2 := #Salida3 := #Salida4 := FALSE;
            END_IF;
            
        END_REGION
        
        
        //  ==========================================================================================================
        REGION TIEMPO RESTANTE
            IF #Salida1 THEN
                #EtapaTiempoRestante := #s_CalculoTiempoSalida1 - #s_ContadorTiempo;
            END_IF;
            IF #Salida2 THEN
                #EtapaTiempoRestante := (#s_CalculoTiempoSalida1 + #s_CalculoTiempoSalida2) - #s_ContadorTiempo;
            END_IF;
            IF #Salida3 THEN
                #EtapaTiempoRestante := (#s_CalculoTiempoSalida1 + #s_CalculoTiempoSalida2 + #s_CalculoTiempoSalida3) - #s_ContadorTiempo;
            END_IF;
            IF #Salida4 THEN
                #EtapaTiempoRestante := #s_TiempoTotal - #s_ContadorTiempo;
            END_IF;
            
            IF #EtapaTiempoRestante < 0 THEN
                #EtapaTiempoRestante := 0;
            END_IF;
            
        END_REGION
        
    END_NETWORK
END_FUNCTION_BLOCK
