{
    S7_Author := "ABH";
    S7_BlockComment := "MLC_339";
    S7_BlockNumber := "2926";
    S7_BlockTitle := "MLC_4ir";
    S7_EditorMode := "SCL";
    S7_Family := "ZeusControl";
    S7_Optimized := "TRUE";
    S7_Version := "1.0"
}
FUNCTION "FC2926_ZC_FF_INDV" : Void
    VAR_INPUT
        { S7_MLC := "MLC_4j6" }
        Pulso1Seg : Bool;
    END_VAR
    VAR_IN_OUT
        FF : _.UDT_ZC_DISP_FF;
    END_VAR
    VAR CONSTANT
        REPOSO : SInt := 0;
        FLOP : SInt := 10;
        PARO1 : SInt := 20;
        FLIP : SInt := 30;
        PARO2 : SInt := 40;
    END_VAR

    { S7_Language := "SCL" }
    NETWORK
        REGION DESCRIPCION
            (*
            ###### (C)Copyright ZeusControl 2026 - 2026
            
            ---
            ### Información del Sistema
            | Hardware Compatible | Entorno de Ingeniería |
            |---------------------|-----------------------|
            | PLC serie 1200/1500 | TIA Portal 18         |
            
            ---
            > **Restricciones:** Ninguna.
            
            ---
            ### Descripción Funcional
            
            Función encargada de gestionar un dispositivo flip flop con funcion de paro entre cambios.
            
            Las tareas que realiza son las siguientes:
            
            - Gestionar la activacion y calculos de tiempo de cambio entre ordenes Flip, Flop y paro.
            - Adicionalmente, se gestiona tambien la posibilidad de pausar el contaje del tiempo, para evitar su reinicializacion en caso de pausa.
            - En los cambios entre ´flip´ <--> ´flop´, se activa tambien la marca ´paro´ para poder gestionar los cambios y evitar golpes de ariete.
            ---
            ### Dependencias Requeridas
            | Tipo | Elementos |
            |------|-----------|
            | FC   | - |
            | FB   | - |
            | DB   | - |
            | UDT  | `UDT_ZC_DISP_FF_PARO` |
            
            ---
            ### Historial de Cambios
            | Versión  | Fecha      | Técnico | Cambios |
            |----------|------------|---------|---------|
            | 01.00.00 | 02.06.2026 | (ABH)   | Primera version. |
        *)
        END_REGION DESCRIPCION
        
        
        //  ==========================================================================================================
        REGION GESTION_DISPOSITIVO
            
            // ==========================================================================================================
            REGION COMPROBACIONES_INICIALES
                
                //  Si no hay orden o faltan tiempos, reseteamos valores y salimos de la funcion
                IF NOT #FF.Orden_Activar OR (#FF.Config_SetPointTiempoFlip <= 0 AND #FF.Config_SetPointTiempoFlop <= 0) THEN
                    #FF.Estado_Flip := FALSE;
                    #FF.Estado_Flop := FALSE;
                    #FF.Estado_Paro1 := FALSE;
                    #FF.Estado_Paro2 := FALSE;
                    
                    #FF.Aux_Tiempo := 0;
                    #FF.Estado_Etapa := #REPOSO;
        
                    #FF.Aux_Inicializado := FALSE;
                    RETURN;
                END_IF;
                
            END_REGION COMPROBACIONES_INICIALES
        
        
            // ==========================================================================================================
            REGION INICIALIZACION
                
                //  Arranque inicial forzado a Flop si no hay estado activo
                IF NOT #FF.Aux_Inicializado THEN
                    #FF.Estado_Etapa := #FLOP;
                    #FF.Aux_Inicializado := TRUE;
                END_IF;
                
            END_REGION INICIALIZACION
            
            
            // ==========================================================================================================
            REGION LOGICA_DE_ESTADOS        
                
                CASE #FF.Estado_Etapa OF
        
                    #FLOP:
                        //  Salidas
                        #FF.Estado_Flip := FALSE;
                        #FF.Estado_Flop := TRUE;
                        #FF.Estado_Paro1 := FALSE;
                        #FF.Estado_Paro2 := FALSE;
                        
                        //  Conteo de tiempo
                        IF #Pulso1Seg AND NOT #FF.Orden_Pausa THEN
                            #FF.Aux_Tiempo += 1;
                        END_IF;
                        
                        //  Transición
                        IF #FF.Aux_Tiempo >= #FF.Config_SetPointTiempoFlop THEN
                            #FF.Aux_Tiempo := 0;
                            //  Si no tenemos tiempo de paro configurado, saltamos a FLIP
                            IF #FF.Config_SetPointTiempoParo <= 0 THEN
                                #FF.Estado_Etapa := #FLIP;
                            ELSE
                                #FF.Estado_Etapa := #PARO1;
                            END_IF;
                        END_IF;
                        
                    #PARO1:
                        //  Salidas
                        #FF.Estado_Flip := FALSE;
                        #FF.Estado_Flop := FALSE;
                        #FF.Estado_Paro1 := TRUE;
                        #FF.Estado_Paro2 := FALSE;
                        
                        //  Conteo de tiempo
                        IF #Pulso1Seg AND NOT #FF.Orden_Pausa THEN
                            #FF.Aux_Tiempo += 1;
                        END_IF;
                        
                        //  Transición
                        IF #FF.Aux_Tiempo >= #FF.Config_SetPointTiempoParo THEN
                            #FF.Aux_Tiempo := 0;
                            #FF.Estado_Etapa := #FLIP;
                        END_IF;
                        
                        
                    #FLIP:
                        //  Salidas
                        #FF.Estado_Flip := TRUE;
                        #FF.Estado_Flop := FALSE;
                        #FF.Estado_Paro1 := FALSE;
                        #FF.Estado_Paro2 := FALSE;
                        
                        //  Conteo de tiempo
                        IF #Pulso1Seg AND NOT #FF.Orden_Pausa THEN
                            #FF.Aux_Tiempo += 1;
                        END_IF;
                        
                        //  Transición
                        IF #FF.Aux_Tiempo >= #FF.Config_SetPointTiempoFlip THEN
                            #FF.Aux_Tiempo := 0;
                            //  Si no tenemos tiempo de paro configurado, saltamos a FLOP
                            IF #FF.Config_SetPointTiempoParo <= 0 THEN
                                #FF.Estado_Etapa := #FLOP;
                            ELSE
                                #FF.Estado_Etapa := #PARO2;
                            END_IF;
                        END_IF;
                        
                        
                    #PARO2:
                        //  Salidas
                        #FF.Estado_Flip := FALSE;
                        #FF.Estado_Flop := FALSE;
                        #FF.Estado_Paro1 := FALSE;
                        #FF.Estado_Paro2 := TRUE;
                        
                        //  Conteo de tiempo
                        IF #Pulso1Seg AND NOT #FF.Orden_Pausa THEN
                            #FF.Aux_Tiempo += 1;
                        END_IF;
                        
                        //  Transición
                        IF #FF.Aux_Tiempo >= #FF.Config_SetPointTiempoParo THEN
                            #FF.Aux_Tiempo := 0;
                            #FF.Estado_Etapa := #FLOP;
                        END_IF;
                        
                    ELSE  
                        #FF.Estado_Etapa := #REPOSO;
                END_CASE;
                
            END_REGION LOGICA_DE_ESTADOS 
            
        END_REGION GESTION_DISPOSITIVO
        
        
    END_NETWORK
END_FUNCTION
