FUNCTION_BLOCK "FB15153_ZC_MARCHA_SEC_B_MEM"
TITLE = FB15153_ZC_MARCHA_SEC_B_MEM
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : ABH
FAMILY : ZeusControl
VERSION : 1.0
//Bloque de funcion para la gestion de activacion de las bombas de de una maquina de membranas
   VAR_INPUT 
      Pulso1Seg : Bool;   // Pulso de 1 segundo
      MarchaSecuencia : Bool;   // Orden de marcha secuencia
      EstadoBombaPresionVF : Bool;   // Estado bomba Presion (Variador)
      EstadoBombaPresion : Bool;   // Estado bomba Presion
      TiempoEntreBombas : Int := 10;   // SP Tiempo entre bombas
      NumeroBombasPresion : Int := 2;   // Numero de bombas presion (1 o 2)
      NumeroModulos : Int := 6;   // Numero de modulos
   END_VAR

   VAR_OUTPUT 
      MarchaBombaPresionVF : Bool;   // Activacion bomba Presion (Variador)
      MarchaBombaPresion : Bool;   // Activacion bomba Presion
      MarchaBombaModulo : Array[1..#N_MAX] of Bool;   // Activacion bomba Modulo
   END_VAR

   VAR RETAIN
      s_TonPresion { S7_SetPoint := 'False'} : Array[1..2] of "UDT_ZC_DISP_TON";
      s_TonModulos { S7_SetPoint := 'False'} : Array[1..#N_MAX] of "UDT_ZC_DISP_TON";
   END_VAR

   VAR_TEMP 
      for_i : Int;
      t_NumBombasPresion : Int;   // Numero de bombas presion
      t_NumModulos : Int;   // Numero de modulos
      t_BombasPresionOk : Bool;   // Bombas presion arrancadas Ok
   END_VAR

   VAR CONSTANT 
      N_MAX : Int := 6;
   END_VAR


BEGIN
	REGION DESCRIPCION
	(*
	###### (C)Copyright ZeusControl 2023 - 2026
	
	---
	### Información del Sistema
	| Hardware Compatible | Entorno de Ingeniería |
	|---------------------|-----------------------|
	| PLC serie 1200/1500 | TIA Portal 18         |
	
	---
	> **Restricciones:** Ninguna.
	
	---
	### Descripción Funcional
	
	Bloque de gestión de marcha secuencial de bombas de una máquina de membranas. Implementa el arranque escalonado, en cascada y temporizado, de las bombas de presión y de las bombas de los módulos de la máquina, respetando el número de bombas y módulos configurados y utilizando temporizadores individuales no retentivos.
	
	Acciones detalladas:
	- Limita el número de bombas de presión activas (`t_NumBombasPresion`) al rango válido `1`–`2`, acotando la entrada `NumeroBombasPresion`.
	- Limita el número de módulos activos (`t_NumModulos`) al rango válido `1`–`N_MAX`, acotando la entrada `NumeroModulos`.
	- Traslada el setpoint de temporización `TiempoEntreBombas` a todos los temporizadores de bombas de presión (`s_TonPresion[1..2]`) y de módulos (`s_TonModulos[1..N_MAX]`).
	- Gestiona el arranque de las bombas de presión mediante dos temporizadores en cascada: primero la bomba de variador (`s_TonPresion[1]`) y, tras su confirmación y solo si hay 2 bombas configuradas, la segunda bomba de presión (`s_TonPresion[2]`).
	- Calcula el flag `t_BombasPresionOk`, que indica que el conjunto de bombas de presión requerido está en marcha: con 1 bomba exige confirmación del variador, con 2 bombas exige confirmación de ambas.
	- Arranca el módulo 1 (`s_TonModulos[1]`) directamente cuando las bombas de presión están OK.
	- Arranca los módulos `2` a `N_MAX` en cascada, de forma que cada módulo espera a la confirmación del módulo anterior y a las bombas de presión OK; los módulos no configurados se fuerzan a `FALSE` por seguridad.
	- Ejecuta los temporizadores llamando a la `FC` de temporización individual, lo que permite disponer de un `SP`, una `IN`, una salida `Q` y un tiempo transcurrido independientes por instancia.
	- Genera las salidas finales: `MarchaBombaPresionVF` (variador), `MarchaBombaPresion` (segunda bomba) y `MarchaBombaModulo[1..N_MAX]` a partir de las salidas `Q` de los temporizadores correspondientes.
	
	---
	### Dependencias Requeridas
	| Tipo | Elementos |
	|------|-----------|
	| FC   | `FC2928_ZC_TON_INDV` |
	| FB   | - |
	| DB   | - |
	| UDT  | - |
	
	---
	### Historial de Cambios
	| Versión  | Fecha      | Técnico | Cambios |
	|----------|------------|---------|---------|
	| 01.00.00 | 09.05.2023 | (ABH)   | Primera version. |
	| 01.00.01 | 19.05.2023 | (ABH)   | Se añade parámetro de entrada para límite de número de bombas de presión. |
	| 01.00.02 | 02.10.2023 | (ABH)   | Se añade `FC22028_TON_INV` para gestión de temporizadores. |
	| 01.00.03 | 02.11.2023 | (ABH)   | Se añade gestión para 6 módulos. |
	| 01.00.03 | 06.07.2026 | (ABH)   | Cambio a SCL. Se refactoriza numero de modulos.|
	*)
	END_REGION DESCRIPCION
	
	
	//  ==========================================================================================================
	REGION LIMITES
	
	    //  Limite numero de bombas presion
	    #t_NumBombasPresion := #NumeroBombasPresion;
	    IF #t_NumBombasPresion < 1 THEN
	        #t_NumBombasPresion := 1;
	    END_IF;
	    IF #t_NumBombasPresion > 2 THEN
	        #t_NumBombasPresion := 2;
	    END_IF;
	    
	    //  Limite numero de bombas modulos
	    #t_NumModulos := #NumeroModulos;
	    IF #t_NumModulos < 1 THEN
	        #t_NumModulos := 1;
	    END_IF;
	    IF #t_NumModulos > #N_MAX THEN
	        #t_NumModulos := #N_MAX;
	    END_IF;
	    
	END_REGION LIMITES
	
	
	//  ==========================================================================================================
	REGION TRASPASO_DE_PARAMETROS
	    
	    //  Traspaso de tiempos bomba presion
	    FOR #for_i := 1 TO 2 DO
	        #s_TonPresion[#for_i].SP := #TiempoEntreBombas;
	    END_FOR;
	    
	    //  Traspaso de tiempos bomba modulos
	    FOR #for_i := 1 TO #N_MAX DO
	        #s_TonModulos[#for_i].SP := #TiempoEntreBombas;
	    END_FOR;
	    
	END_REGION TRASPASO_DE_PARAMETROS
	
	
	//  ==========================================================================================================
	REGION GESTION_BOMBAS_PRESION
	    
	    //  Temporizador bomba Presion (Variador)
	    #s_TonPresion[1].IN := #MarchaSecuencia;
	    
	    //  Temporizador bomba Presion
	    #s_TonPresion[2].IN :=
	    (#t_NumBombasPresion = 2) AND
	    #EstadoBombaPresionVF AND
	    #s_TonPresion[1].Q;
	    
	    //  Bombas presion arrancadas Ok
	    IF #t_NumBombasPresion = 1 THEN
	        #t_BombasPresionOk := #EstadoBombaPresionVF AND #s_TonPresion[1].Q;
	    ELSE
	        #t_BombasPresionOk := #EstadoBombaPresion AND #s_TonPresion[2].Q;
	    END_IF;
	    
	END_REGION GESTION_BOMBAS_PRESION
	
	
	//  ==========================================================================================================
	REGION GESTION_BOMBAS_MODULOS
	
	    //  El modulo 1 arranca directamente si las bombas de presion estan OK
	    #s_TonModulos[1].IN := #t_BombasPresionOk;
	    
	    //  Los modulos 2 a N_MAX arrancan en cascada
	    FOR #for_i := 2 TO #N_MAX DO
	        
	        IF #for_i <= #t_NumModulos THEN
	            
	            //  Si el módulo está dentro de la configuración, evalúa la cascada (Módulo anterior Q + bombas presion Ok)
	            #s_TonModulos[#for_i].IN := #s_TonModulos[#for_i - 1].Q AND #t_BombasPresionOk;
	            
	        ELSE
	            
	            //  Forzado de seguridad a FALSE para módulos no instalados/configurados en esta máquina
	            #s_TonModulos[#for_i].IN := FALSE;
	            
	        END_IF;
	        
	    END_FOR;
	    
	END_REGION GESTION_BOMBAS_MODULOS
	
	
	//  ==========================================================================================================
	REGION GESTION_TEMPORIZADORES
	    
	    //  Temporizadores bombas presion
	    FOR #for_i := 1 TO 2 DO
	        "FC2928_ZC_TON_INDV"(Pulso1seg := #Pulso1Seg,
	                             TON := #s_TonPresion[#for_i]);
	    END_FOR;
	    
	    //  Temporizadores bombas modulos
	    FOR #for_i := 1 TO #N_MAX DO
	        "FC2928_ZC_TON_INDV"(Pulso1seg := #Pulso1Seg,
	                             TON := #s_TonModulos[#for_i]);
	    END_FOR;
	    
	END_REGION GESTION_TEMPORIZADORES
	
	
	//  ==========================================================================================================
	REGION SALIDAS
	    
	    //  Bombas presion
	    #MarchaBombaPresionVF := #s_TonPresion[1].Q;
	    #MarchaBombaPresion := #s_TonPresion[2].Q;
	    
	    //  Bombas modulos
	    FOR #for_i := 1 TO #N_MAX DO
	        
	        #MarchaBombaModulo[#for_i] := #s_TonModulos[#for_i].Q;
	        
	    END_FOR;
	    
	END_REGION SALIDAS
	
END_FUNCTION_BLOCK

