*** ## `OB1` - Main (`_CYCL_EXC` - Ejecución Cíclica Principal) ```pascal // Block Type: OB // Name: Main // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : Main; // END_NAMESPACE; // // VAR_TEMP // info : Array[0..3] of Word; // END_VAR; BEGIN // Get OB Info - required for some blocks #info[0] := #OB1_SCAN_CYCLE; // Cycle time of last OB1 scan in ms #info[1] := #OB1_DATE_TIME.YEAR; #info[2] := #OB1_DATE_TIME.MONTH; #info[3] := #OB1_DATE_TIME.DAY; // ========================================================================= // Call main control block instance // ========================================================================= "BlenderCtrl__Main_DB"(); // Instance DB call for the main blender control logic // ========================================================================= // Call HMI Interface handler // ========================================================================= "HMI_Interface_Handler_DB"(); // Example: Instance DB call for HMI data aggregation/handling // ========================================================================= // Call Communication handlers (if not handled elsewhere) // ========================================================================= "Com_Filler_DB"(); // Example: Instance DB call for Filler communication logic "Com_SyrupRoom_DB"(); // Example: Instance DB call for Syrup Room communication logic // Note: Additional calls to other general FCs/FBs might be present here. END; ```` **Análisis `OB1`: ** - **Función:** Ejecuta la lógica principal del programa en cada ciclo de scan. - **Código:** - Obtiene información básica del OB (tiempo de ciclo, fecha/hora). - **Llama a la instancia DB de `BlenderCtrl__Main` (`"BlenderCtrl__Main_DB"()`). Esta es la llamada clave que ejecuta el corazón de la lógica de control del mezclador.** - Llama a otros bloques como `"HMI_Interface_Handler_DB"`, `"Com_Filler_DB"`, `"Com_SyrupRoom_DB"`, indicando que la gestión HMI y comunicación se maneja en el ciclo principal. - **Contexto Mixer:** Punto de entrada principal que orquesta las funciones generales de la máquina ciclo a ciclo. --- ## `OB100` - Startup (`COMPLETE RESTART` - Arranque en Caliente) Structured Text ```pascal // Block Type: OB // Name: Startup // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : Startup; // END_NAMESPACE; // // VAR_TEMP // startupInfo : OB_STARTUP; // Structure with startup information // END_VAR; BEGIN // Read Startup Info #startupInfo := #OB100_STARTUP_INFO; // ========================================================================= // Initialization Logic // ========================================================================= // Example: Reset main state machine to Idle on warm restart IF #startupInfo.Event_Class = B#16#39 THEN // Check if it's a Warm Start (Event Class 39hex) "BlenderCtrl__Main_DB".StateMachine_State := 0; // Assuming 0 represents Idle state "BlenderCtrl__Main_DB".InitializeFlags := TRUE; // Trigger initialization within the FB END_IF; // Example: Call a dedicated initialization function "Initialize_Application"(); // FC call for broader initializations // Example: Set initial safe state for outputs (if not handled by HW config) // "Valve_Output_Water" := FALSE; // "Pump_Syrup_Start" := FALSE; END; ``` **Análisis `OB100`: ** - **Función:** Se ejecuta una vez al pasar el PLC de STOP a RUN (arranque en caliente/Warm Restart). - **Código:** - Lee información sobre el evento de arranque. - Si es un arranque en caliente (`Event_Class = B#16#39`), resetea el estado de la máquina principal (`"BlenderCtrl__Main_DB".StateMachine_State`) y activa un flag de inicialización en ese FB. - Puede llamar a una FC de inicialización general (`"Initialize_Application"`). - Podría establecer salidas a un estado seguro inicial. - **Contexto Mixer:** Asegura que la máquina inicie en un estado predecible y seguro tras un arranque en caliente. --- ## `OB35` - Cyclic interrupt 5 (`CYC_INT5` - Interrupción Cíclica) _(Asumiendo que `CYC_INT5` corresponde a `OB35` en la configuración del hardware)_ Structured Text ```pascal // Block Type: OB // Name: Cyclic interrupt 5 // Name might vary based on user naming // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : CyclicInterrupt; // Use the actual name from TIA Portal // END_NAMESPACE; // // VAR_TEMP // // Temporary variables if needed // END_VAR; BEGIN // ========================================================================= // Time-Critical Tasks - Executed every e.g., 100ms // ========================================================================= // Example: Call PID controllers instances "WaterFlow_PID_DB"(); // Instance DB for Water Flow PID "SyrupFlow_PID_DB"(); // Instance DB for Syrup Flow PID "Carbonation_PID_DB"(); // Instance DB for Carbonation PID "TankLevel_PID_DB"(); // Instance DB for Tank Level PID (if applicable) // Example: Call Analog Input Scaling / Processing "Analog_Input_Processing_DB"(); // FB handling scaling/filtering for multiple inputs // Example: Call critical parts of Ratio Control calculation "RatioControl_CyclicPart_DB"(); // FB handling the periodic calculation/adjustment // Example: Update totalizers "Water_Totalizer_DB"(); "Syrup_Totalizer_DB"(); "Product_Totalizer_DB"(); END; ``` **Análisis `OB35` (o similar):** - **Función:** Ejecuta tareas que requieren una temporización precisa y constante (ej. cada 100ms). - **Código:** - Llama a las instancias DB de los bloques PID para control de flujo, nivel, carbonatación. - Llama a bloques de procesamiento de entradas analógicas. - Llama a partes críticas del control de ratio. - Llama a bloques para actualizar totalizadores. - **Contexto Mixer:** Garantiza el funcionamiento estable y preciso de los lazos de control (PID) y cálculos críticos, esencial para la calidad del producto. --- ## `OB122` - IO access error (`I_O_FLT1` - Error Acceso E/S) Structured Text ```pascal // Block Type: OB // Name: IO access error // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : IO_AccessError; // END_NAMESPACE; // // VAR_TEMP // LADDR : HW_IO; // Logical address of the I/O // READ_WRITE_ACCESS : Byte; // 0=Read, 1=Write // REQUESTING_OB_NR : Int; // OB number that caused the error // PRIORITY : Int; // Priority of requesting OB // ERROR_INFO : Word; // Detailed error code // BLK_TYPE : Int; // Block type causing the error // BLK_NR : Int; // Block number causing the error // END_VAR; BEGIN // Read Fault Information from OB Temp Variables #LADDR := #OB122_LADDR; #READ_WRITE_ACCESS := #OB122_READ_WRITE_ACCESS; #REQUESTING_OB_NR := #OB122_REQUESTING_OB_NR; #ERROR_INFO := #OB122_ERROR_INFO; // ========================================================================= // Fault Handling Logic // ========================================================================= // Example: Log the error details "Log_Diagnostic_Event"(SourceOB := 122, LogicalAddress := #LADDR, ErrorCode := #ERROR_INFO); // Call a custom logging FC // Example: Set a general I/O Fault flag "Global_Status".IO_Fault := TRUE; // Example: Trigger a specific alarm based on the module address IF #LADDR = 16#100 THEN // Example: Logical address 256 "Alarms_DB".Specific_Module_Fault := TRUE; END_IF; END; ``` **Análisis `OB122`: ** - **Función:** Se ejecuta cuando hay un error al acceder (leer/escribir) a un punto de E/S. - **Código:** - Lee detalles del fallo (dirección lógica, código de error). - Llama a una función para registrar el evento (`"Log_Diagnostic_Event"`). - Activa un flag general de fallo de E/S (`"Global_Status".IO_Fault`). - Puede activar alarmas específicas basadas en la dirección del módulo afectado. - **Contexto Mixer:** Permite detectar y alarmar sobre problemas con módulos de E/S individuales sin detener el PLC. --- ## `OB82` - Diagnostic error interrupt (`MOD_ERR`, `I_O_FLT1` - Error Diagnóstico HW) Structured Text ```pascal // Block Type: OB // Name: Diagnostic error interrupt // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : DiagnosticErrorInterrupt; // END_NAMESPACE; // // VAR_TEMP // LADDR : HW_IO; // Logical address of the module // CHANNEL : UInt; // Channel number (if applicable) // MULTI_ERROR : Bool; // Multiple errors reported // FAULT_ID : DWord; // Diagnostic code // AUX_VALUE : Array[0..3] of DWord; // Additional diagnostic info // END_VAR; BEGIN // Read Diagnostic Information #LADDR := #OB82_MDL_ADDR; #FAULT_ID := #OB82_FAULT_ID; #MULTI_ERROR := #OB82_MULTI_ERROR; // ========================================================================= // Diagnostic Handling Logic // ========================================================================= // Example: Log the diagnostic event "Log_Diagnostic_Event"(SourceOB := 82, LogicalAddress := #LADDR, ErrorCode := UDINT_TO_WORD(#FAULT_ID)); // Pass fault ID // Example: Set a general Module Fault flag "Global_Status".Module_Fault := TRUE; // Example: Trigger specific alarm based on module and fault ID CASE #LADDR OF 16#100: // Module at logical address 256 IF #FAULT_ID = 16#XXXX THEN // Specific Fault ID "Alarms_DB".Module_100_Specific_Fault := TRUE; ELSE "Alarms_DB".Module_100_General_Fault := TRUE; END_IF; 16#101: // Module at logical address 257 // ... handle faults for this module ... ELSE "Alarms_DB".Unknown_Module_Fault := TRUE; END_CASE; END; ``` **Análisis `OB82`: ** - **Función:** Se ejecuta cuando un módulo hardware reporta un fallo interno vía diagnóstico. - **Código:** - Lee la dirección del módulo (`LADDR`) y el código de fallo (`FAULT_ID`). - Registra el evento (`"Log_Diagnostic_Event"`). - Activa un flag general de fallo de módulo (`"Global_Status".Module_Fault`). - Usa `CASE` y `IF` para activar alarmas muy específicas basadas en qué módulo falló y cuál fue el error. - **Contexto Mixer:** Crucial para identificar fallos específicos de hardware (cortocircuitos, rotura de hilo, etc.) y guiar al mantenimiento. --- ## `OB83` - Process diagnostics error interrupt (`ProDiagOB` - Error Diagnóstico Proceso) Structured Text ```pascal // Block Type: OB // Name: Process diagnostics error interrupt // Manual: TIA Portal help // Version: 1.0 // S7-1500 Only // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : ProDiag_OB; // Actual name might differ // END_NAMESPACE; // // VAR_TEMP // PRODIAG_INFO : OB_PRODIAG; // Structure with detailed ProDiag info // END_VAR; BEGIN // Read Process Diagnostic Information #PRODIAG_INFO := #OB83_PRODIAG_INFO; // ========================================================================= // Process Diagnostic Handling Logic // ========================================================================= // Example: Log the detailed ProDiag event "Log_ProDiag_Event"(EventClass := #PRODIAG_INFO.EVENT_CLASS, EventID := #PRODIAG_INFO.EVENT_ID, InstanceDB := #PRODIAG_INFO.INSTANCE_DB_NR, ObjectID := #PRODIAG_INFO.OBJECT_ID, EventState := #PRODIAG_INFO.EVENT_STATE); // Call custom logging FC // Example: Trigger specific alarms based on the ProDiag info // The Instance DB and Object ID usually point to the supervised element IF #PRODIAG_INFO.INSTANCE_DB_NR = "WaterValveCtrl_DB".Number THEN // Check if it's the water valve FB IF #PRODIAG_INFO.OBJECT_ID = 1 THEN // Assuming Object ID 1 is 'Position Not Reached' "Alarms_DB".WaterValve_Position_Fault := (#PRODIAG_INFO.EVENT_STATE = EnumTypeOfEventState.Came); // Set alarm if event 'Came' END_IF; END_IF; // Could also directly call a method on the affected FB instance if designed that way // Example: "GetInstanceFromDBNum"(#PRODIAG_INFO.INSTANCE_DB_NR).ReportProDiagFault(#PRODIAG_INFO); END; ``` **Análisis `OB83`: ** - **Función:** Se ejecuta cuando una supervisión de "Process Diagnostics" (S7-1500) detecta un fallo funcional. - **Código:** - Lee la estructura `#PRODIAG_INFO` con detalles del evento (qué supervisión, en qué bloque/instancia). - Registra el evento ProDiag (`"Log_ProDiag_Event"`). - Activa alarmas específicas del proceso basadas en la información (ej. fallo de posición de válvula de agua). - Podría llamar a métodos del FB afectado. - **Contexto Mixer:** Diagnóstico funcional potente para identificar problemas como válvulas atascadas, bombas sin rendimiento, etc., más allá de fallos eléctricos. --- ## `OB121` - Programming error (Error de Programación) Structured Text ```pascal // Block Type: OB // Name: Programming error // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : ProgrammingError; // END_NAMESPACE; // // VAR_TEMP // FaultID : Byte; // Error Code // ErrorReg1 : Word; // Internal Error Register 1 // ErrorReg2 : Word; // Internal Error Register 2 // OBNumber : Int; // OB Number where error occurred // BlockType : Int; // Type of block where error occurred (OB, FB, FC, DB) // BlockNumber : Int; // Number of block where error occurred // InstructionAddress : Int; // Address within the block // END_VAR; BEGIN // Read Fault Information #FaultID := #OB121_Fault_ID; #OBNumber := #OB121_OB_Number; #BlockType := #OB121_Blk_Type; #BlockNumber := #OB121_Blk_Number; #InstructionAddress := #OB121_Instr_Address; // ========================================================================= // Programming Error Handling Logic // ========================================================================= // Example: Log the programming error details "Log_Programming_Error"(FaultCode := #FaultID, SourceOB := #OBNumber, SourceBlockType := #BlockType, SourceBlockNum := #BlockNumber, SourceAddress := #InstructionAddress); // Call custom logging FC // Example: Set a general Programming Fault flag "Global_Status".Programming_Fault := TRUE; // Example: Trigger a specific alarm message "Alarms_DB".PLC_Programming_Error := TRUE; // Optionally, format a string with details for HMI display if possible END; ``` **Análisis `OB121`: ** - **Función:** Se ejecuta cuando ocurre un error en tiempo de ejecución en el código de usuario. - **Código:** - Lee detalles del error (código, bloque, dirección). - Registra los detalles del error (`"Log_Programming_Error"`). - Activa un flag general de fallo de programación (`"Global_Status".Programming_Fault`). - Activa una alarma general de error de programa. - **Contexto Mixer:** Red de seguridad para capturar 'bugs' de programación y evitar el STOP del PLC, registrando información para depuración. --- ## `OB86` - Rack or station failure (`RACK_FLT`, `MOD_ERR` - Fallo Rack/Estación) Structured Text ```pascal // Block Type: OB // Name: Rack or station failure // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : RackOrStationFailure; // END_NAMESPACE; // // VAR_TEMP // LADDR : HW_IO; // Logical address of DP master or PROFINET IO controller // StationNr : UInt; // Station number of the failed station/rack // FailureEvent : Byte; // Type of failure (e.g., 16#39=Failure, 16#38=Return) // SystemID : Word; // System ID (e.g., Profibus/Profinet subnet) // END_VAR; BEGIN // Read Failure Information #LADDR := #OB86_LADDR; // Often corresponds to the PN interface ID #StationNr := #OB86_Station_Nr; #FailureEvent := #OB86_Failure_Event; // B#16#39 = Failure, B#16#38 = Return to operation // ========================================================================= // Rack/Station Failure Handling Logic // ========================================================================= IF #FailureEvent = 16#39 THEN // Station Failed // Example: Log the failure "Log_Rack_Failure"(Station := #StationNr, System := #SystemID); // Custom logging FC // Example: Set a critical fault flag "Global_Status".Rack_Failure := TRUE; "Global_Status".Critical_Fault := TRUE; // Often considered critical // Example: Trigger specific alarm based on Station Number CASE #StationNr OF 3: // Example: Station 3 (Maybe Syrup Room I/O) "Alarms_DB".Station_3_Failure := TRUE; // Potentially trigger safe shutdown logic in BlenderCtrl__Main "BlenderCtrl__Main_DB".ExternalCriticalFault := TRUE; 10: // Example: Station 10 (Maybe Filler Interface I/O) "Alarms_DB".Station_10_Failure := TRUE; "BlenderCtrl__Main_DB".ExternalCriticalFault := TRUE; ELSE "Alarms_DB".Unknown_Station_Failure := TRUE; END_CASE; ELSIF #FailureEvent = 16#38 THEN // Station Returned // Example: Log the return event "Log_Rack_Return"(Station := #StationNr, System := #SystemID); // Example: Clear specific alarm (if fault condition cleared) CASE #StationNr OF 3: "Alarms_DB".Station_3_Failure := FALSE; 10: "Alarms_DB".Station_10_Failure := FALSE; ELSE "Alarms_DB".Unknown_Station_Failure := FALSE; // May need more logic here END_CASE; // Reset general rack failure flag ONLY if ALL racks are okay (requires more logic) // "Global_Status".Rack_Failure := CheckAllStationsOK(); END_IF; END; ``` **Análisis `OB86`: ** - **Función:** Se ejecuta al perder/recuperar comunicación con una estación de E/S remota o rack. - **Código:** - Identifica la estación y si es un fallo (`16#39`) o recuperación (`16#38`). - **Si es Fallo:** Registra, activa flags de fallo (generalmente crítico), usa `CASE` para activar alarmas específicas por estación, y crucialmente, **informa al control principal (`"BlenderCtrl__Main_DB".ExternalCriticalFault := TRUE;`) para iniciar parada segura**. - **Si es Recuperación:** Registra, desactiva alarmas específicas. - **Contexto Mixer:** Esencial para la seguridad. Detecta pérdida de comunicación con E/S críticas (válvulas, bombas remotas) y fuerza una parada controlada. --- ## `OB80` - Time error interrupt (Error Tiempo de Ciclo) Structured Text ```pascal // Block Type: OB // Name: Time error // Manual: TIA Portal help // Version: 1.0 // S7-1500 / S7-1200 // Performance optimized compilation: Yes // Safe programming: No // Language: SCL // Interface: // NAMESPACE: OBs // Block_OB : TimeError; // END_NAMESPACE; // // VAR_TEMP // FaultyOB : Int; // OB Number that exceeded cycle time // ErrorCode : Byte; // Error Code (usually B#16#01) // CycleTimeConfig : DInt; // Configured cycle time in µs // ActualCycleTime : DInt; // Actual cycle time in µs // END_VAR; BEGIN // Read Fault Information #FaultyOB := #OB80_OB_Number; #ActualCycleTime := #OB80_Cycle_Time; // Actual time in µs // ========================================================================= // Time Error Handling Logic // ========================================================================= // Example: Log the time error event "Log_Time_Error"(SourceOB := #FaultyOB, ExceededTime_us := #ActualCycleTime); // Call custom logging FC // Example: Set a general Cycle Time Fault flag "Global_Status".CycleTime_Fault := TRUE; // Example: Trigger a specific alarm message "Alarms_DB".PLC_CycleTime_Exceeded := TRUE; // Optionally, indicate which OB caused it if needed for HMI display END; ``` **Análisis `OB80`: ** - **Función:** Se ejecuta si `OB1` o un `OB3x` excede su tiempo de ciclo máximo configurado. - **Código:** - Lee qué OB causó el error y cuánto tiempo tardó. - Registra el evento (`"Log_Time_Error"`). - Activa un flag general de fallo de tiempo de ciclo (`"Global_Status".CycleTime_Fault`). - Activa una alarma general (`"Alarms_DB".PLC_CycleTime_Exceeded`). - **Contexto Mixer:** Indica sobrecarga del PLC o código ineficiente. Es vital para detectar condiciones que pueden llevar a inestabilidad del control. --- **Conclusión:** La implementación detallada de estos OBs de evento y error demuestra un enfoque robusto en la programación, buscando alta disponibilidad y facilitando el diagnóstico de problemas tanto a nivel de hardware como de software y proceso. La lógica implementada permite registrar fallos, generar alarmas específicas y, en casos críticos como `OB86`, interactuar con el control principal para llevar la máquina a un estado seguro.