From ae9667622ad27576e9192b071d132b01368dcbf8 Mon Sep 17 00:00:00 2001 From: Matthias Heisig Date: Thu, 13 Nov 2025 09:19:39 +0100 Subject: [PATCH] Added more components --- BaseComponents.tsproj | 224 +++++- DOC01321154-0000_INVEOR_M EtherCAT.xml | 161 ++++ PLC/PLC.plcproj | 175 ++++- PLC/POUs/Analog/FB_AnalogOutput.TcPOU | 65 -- .../Analog/FB_AnalogInput.TcPOU | 332 ++++----- .../Components/Analog/FB_AnalogOutput.TcPOU | 237 ++++++ .../Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT | 0 .../Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT | 0 .../Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT | 0 .../Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT | 0 .../EventListener/FB_EventListener.TcPOU | 0 .../EventListener/Types/E_EventType.TcDUT | 0 .../Types/ST_BufferEventEntry.TcDUT | 0 .../Components/Motor/FB_MotorBecker.TcPOU | 497 +++++++++++++ .../Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT | 50 ++ .../Utilities/FB_AlarmMessage.TcPOU | 106 +++ .../Components/Utilities/FB_Blinker.TcPOU | 35 + .../Utilities/FB_RampGenerator.TcPOU | 132 ++++ .../Utilities/FB_ReleaseSignal.TcPOU | 0 .../Utilities/FC_HashFNV1a_32Bit.TcPOU | 34 + PLC/POUs/Components/Valves/FB_Valve.TcPOU | 520 +++++++++++++ .../Components/Valves/FB_ValveAnalog.TcPOU | 689 ++++++++++++++++++ .../Valves/Types/ST_ValveAnalogConfig.TcDUT | 60 ++ .../Valves/Types/ST_ValveConfig.TcDUT | 35 + PLC/POUs/Constants/GVL_TYPE_CONST.TcGVL | 24 + PLC/POUs/GVL/GVL_CONFIGS.TcGVL | 12 + .../Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT | 54 ++ .../HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT | 46 ++ .../Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT | 54 ++ .../Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT | 26 + .../HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT | 46 ++ .../HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT | 50 ++ .../Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT | 47 ++ .../HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT | 49 ++ PLC/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT | 7 + .../HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT | 14 + PLC/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT | 18 + PLC/POUs/HMI/Enum/E_HMI_MODE.TcDUT | 14 + PLC/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT | 16 + PLC/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT | 16 + PLC/POUs/PRG_MAIN.TcPOU | 24 +- .../AOTests/FB_AnalogOutputTest.TcPOU | 469 ++++++++++++ .../FB_ValveAnalog_Test.TcPOU | 547 ++++++++++++++ .../FB_ReleaseSignalTest.TcPOU | 188 +++++ .../UtilitiesTests/FB_BlinkerTest.TcPOU | 301 ++++++++ .../FB_HashFNV1a_32BitTest.TcPOU | 178 +++++ .../Unittests/UtilitiesTests/FB_PT1Test.TcPOU | 276 +++++++ .../UtilitiesTests/FB_RampGeneratorTest.TcPOU | 473 ++++++++++++ .../ValveTests/FB_ValveTestHMI.TcPOU | 282 +++++++ .../ValveTests/FB_ValveTestTimoutClose.TcPOU | 77 ++ .../ValveTests/FB_ValveTestTimoutOpen.TcPOU | 78 ++ .../FB_ValveTestTriggerTimoutClose.TcPOU | 78 ++ .../FB_ValveTestTriggerTimoutOpen.TcPOU | 79 ++ .../Unittests/ValveTests/FB_Valve_Test.TcPOU | 427 +++++++++++ _Config/IO/Gerät 1 (EtherCAT).xti | 20 + .../Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti | 71 ++ 56 files changed, 7117 insertions(+), 296 deletions(-) create mode 100644 DOC01321154-0000_INVEOR_M EtherCAT.xml delete mode 100644 PLC/POUs/Analog/FB_AnalogOutput.TcPOU rename PLC/POUs/{ => Components}/Analog/FB_AnalogInput.TcPOU (63%) create mode 100644 PLC/POUs/Components/Analog/FB_AnalogOutput.TcPOU rename PLC/POUs/{ => Components}/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT (100%) rename PLC/POUs/{ => Components}/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT (100%) rename PLC/POUs/{ => Components}/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT (100%) rename PLC/POUs/{ => Components}/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT (100%) rename PLC/POUs/{ => Components}/EventListener/FB_EventListener.TcPOU (100%) rename PLC/POUs/{ => Components}/EventListener/Types/E_EventType.TcDUT (100%) rename PLC/POUs/{ => Components}/EventListener/Types/ST_BufferEventEntry.TcDUT (100%) create mode 100644 PLC/POUs/Components/Motor/FB_MotorBecker.TcPOU create mode 100644 PLC/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT create mode 100644 PLC/POUs/Components/Utilities/FB_AlarmMessage.TcPOU create mode 100644 PLC/POUs/Components/Utilities/FB_Blinker.TcPOU create mode 100644 PLC/POUs/Components/Utilities/FB_RampGenerator.TcPOU rename PLC/POUs/{ => Components}/Utilities/FB_ReleaseSignal.TcPOU (100%) create mode 100644 PLC/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU create mode 100644 PLC/POUs/Components/Valves/FB_Valve.TcPOU create mode 100644 PLC/POUs/Components/Valves/FB_ValveAnalog.TcPOU create mode 100644 PLC/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT create mode 100644 PLC/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT create mode 100644 PLC/POUs/Constants/GVL_TYPE_CONST.TcGVL create mode 100644 PLC/POUs/GVL/GVL_CONFIGS.TcGVL create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT create mode 100644 PLC/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT create mode 100644 PLC/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT create mode 100644 PLC/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT create mode 100644 PLC/POUs/HMI/Enum/E_HMI_MODE.TcDUT create mode 100644 PLC/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT create mode 100644 PLC/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT create mode 100644 PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU create mode 100644 PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU create mode 100644 PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU create mode 100644 PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU create mode 100644 PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU create mode 100644 PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU create mode 100644 PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU create mode 100644 PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU create mode 100644 _Config/IO/Gerät 1 (EtherCAT).xti create mode 100644 _Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti diff --git a/BaseComponents.tsproj b/BaseComponents.tsproj index 0f7e462..6aca71d 100644 --- a/BaseComponents.tsproj +++ b/BaseComponents.tsproj @@ -1,22 +1,193 @@ - + + + + AnalogOutput + + + ConfigError + + Error + + + + + + + Valve + + + DidNotOpen + + Error + + + DidNotClose + + Error + + + AnalogFeedbackOC + + Error + + + AnalogOutputOC + + Error + + + NotInRange + + Error + + + + + + + AnalogInput + + + ErrorHigh + + Error + + + WarningHigh + + Warning + + + WarningLow + + Warning + + + ErrorLow + + Error + + + AIConfigError + + Error + + + AIShortCircuit + + Error + + + AICardFailure + + Error + + + AIOpenCircuit + + Error + + + + + + + + Motor + + + NotInTarget + + Error + + + RepairSwitchOpen + + Error + + + MCBTripped + + Error + + + + + + + + + + + PlcTask - - - - + PLC Instance {08500001-0000-0000-F000-000000000064} + + PlcTask Outputs + + PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xOpenValve + + BOOL + + + PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xCloseValve + + BOOL + + + PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xOpenValve + + BOOL + + + PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xCloseValve + + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xOpenValve + + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xCloseValve + + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xOpenValve + + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xCloseValve + + BOOL + + + PRG_MAIN._fbValveTestHMI._fbValveOC.xOpenValve + + BOOL + + + PRG_MAIN._fbValveTestHMI._fbValveOC.xCloseValve + + BOOL + + PlcTask Inputs @@ -271,6 +442,46 @@ EL30xx also sets this if an underrange or overrange error is present]]> BOOL + + PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xOpenFeedback + BOOL + + + PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xCloseFeedback + BOOL + + + PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xOpenFeedback + BOOL + + + PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xCloseFeedback + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xOpenFeedback + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xCloseFeedback + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xOpenFeedback + BOOL + + + PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xCloseFeedback + BOOL + + + PRG_MAIN._fbValveTestHMI._fbValveOC.xOpenFeedback + BOOL + + + PRG_MAIN._fbValveTestHMI._fbValveOC.xCloseFeedback + BOOL + @@ -289,5 +500,8 @@ + + + diff --git a/DOC01321154-0000_INVEOR_M EtherCAT.xml b/DOC01321154-0000_INVEOR_M EtherCAT.xml new file mode 100644 index 0000000..8f771dd --- /dev/null +++ b/DOC01321154-0000_INVEOR_M EtherCAT.xml @@ -0,0 +1,161 @@ + + + + #x00000337 + Kostal Industrie Elektrik GmbH + 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + + + + drives + drives + 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + + + + INVEOR_M + + + drives + Outputs + Inputs + MBoxState + MBoxOut + MBoxIn + Outputs + Inputs + + #x1600 + Outputs0 + + #x2000 + 1 + 32 + Steuerwort + UDINT + + + #x2000 + 2 + 32 + Sollfrequenz + REAL + + + #x2000 + 3 + 32 + Digitalausgänge / Relais + UDINT + + + #x2000 + 4 + 32 + Analogausgang 1 + REAL + + + #x2000 + 5 + 32 + Kundenspez.SPS Eingangsgröße 1 (Digital 32Bit) + UDINT + + + #x2000 + 6 + 32 + Kundenspez.SPS Eingangsgröße 1 (Digital 32Bit) + UDINT + + + + #x1a00 + Inputs0 + + #x3000 + 1 + 32 + Statuswort + UDINT + + + #x3000 + 2 + 32 + Istfrequenz + REAL + + + #x3000 + 3 + 32 + Motorspannung + REAL + + + #x3000 + 4 + 32 + Motorstrom + REAL + + + #x3000 + 5 + 32 + Netzspannung + REAL + + + #x3000 + 6 + 32 + Frequenzsollwert + REAL + + + #x3000 + 7 + 32 + Digitaleingänge bitcodiert + UDINT + + + #x3000 + 8 + 32 + Analogeingang 1 + REAL + + + #x3000 + 9 + 32 + Fehlerwort 1 + UDINT + + + #x3000 + 10 + 32 + Fehlerwort 2 + UDINT + + + + + + + + 65536 + 06000188E8030000 + + 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + + + diff --git a/PLC/PLC.plcproj b/PLC/PLC.plcproj index 96cadb9..fda4ecf 100644 --- a/PLC/PLC.plcproj +++ b/PLC/PLC.plcproj @@ -17,7 +17,6 @@ {173a046e-fc1b-4ea3-9ec8-0d52397c403c} {c870d3c5-a637-481e-9586-ab8eaa6f8f36} false - false false false @@ -25,31 +24,114 @@ Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + true + + + Code + true + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + Code @@ -58,24 +140,79 @@ Code - + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + Code - - - - + + + + + + + + + + + + + + + + + + + - + + + Tc2_MC2, * (Beckhoff Automation GmbH) + Tc2_MC2 + Tc2_Standard, * (Beckhoff Automation GmbH) Tc2_Standard @@ -2446,9 +2583,9 @@ MaxStaticAnalysisErrors - 500U + 100U MaxStaticAnalysisWarnings - 500U + 100U PerformStaticAnalyse true SuppressedKeywords @@ -2461,7 +2598,7 @@ ActiveVisuProfile - IR0whWr8bwfyBwAAaCbC8QAAAABVAgAA1xHl6QAAAAABAAAAAAAAAAEaUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwACTHsAZgA5ADUAYgBiADQAMgA2AC0ANQA1ADIANAAtADQAYgA0ADUALQA5ADQAMAAwAC0AZgBiADAAZgAyAGUANwA3AGUANQAxAGIAfQADCE4AYQBtAGUABDJUAHcAaQBuAEMAQQBUACAAMwAuADEAIABCAHUAaQBsAGQAIAA0ADAAMgA2AC4AMQA1AAUWUAByAG8AZgBpAGwAZQBEAGEAdABhAAZMewAxADYAZQA1ADUAYgA2ADAALQA3ADAANAAzAC0ANABhADYAMwAtAGIANgA1AGIALQA2ADEANAA3ADEAMwA4ADcAOABkADQAMgB9AAcSTABpAGIAcgBhAHIAaQBlAHMACEx7ADMAYgBmAGQANQA0ADUAOQAtAGIAMAA3AGYALQA0AGQANgBlAC0AYQBlADEAYQAtAGEAOAAzADMANQA2AGEANQA1ADEANAAyAH0ACUx7ADkAYwA5ADUAOAA5ADYAOAAtADIAYwA4ADUALQA0ADEAYgBiAC0AOAA4ADcAMQAtADgAOQA1AGYAZgAxAGYAZQBkAGUAMQBhAH0ACg5WAGUAcgBzAGkAbwBuAAsGaQBuAHQADApVAHMAYQBnAGUADQpUAGkAdABsAGUADhpWAGkAcwB1AEUAbABlAG0ATQBlAHQAZQByAA8OQwBvAG0AcABhAG4AeQAQDFMAeQBzAHQAZQBtABESVgBpAHMAdQBFAGwAZQBtAHMAEjBWAGkAcwB1AEUAbABlAG0AcwBTAHAAZQBjAGkAYQBsAEMAbwBuAHQAcgBvAGwAcwATKFYAaQBzAHUARQBsAGUAbQBzAFcAaQBuAEMAbwBuAHQAcgBvAGwAcwAUJFYAaQBzAHUARQBsAGUAbQBUAGUAeAB0AEUAZABpAHQAbwByABUiVgBpAHMAdQBOAGEAdABpAHYAZQBDAG8AbgB0AHIAbwBsABYUVgBpAHMAdQBJAG4AcAB1AHQAcwAXGFYAaQBzAHUARQBsAGUAbQBCAGEAcwBlABgmRABlAHYAUABsAGEAYwBlAGgAbwBsAGQAZQByAHMAVQBzAGUAZAAZCGIAbwBvAGwAGiJQAGwAdQBnAGkAbgBDAG8AbgBzAHQAcgBhAGkAbgB0AHMAG0x7ADQAMwBkADUAMgBiAGMAZQAtADkANAAyAGMALQA0ADQAZAA3AC0AOQBlADkANAAtADEAYgBmAGQAZgAzADEAMABlADYAMwBjAH0AHBxBAHQATABlAGEAcwB0AFYAZQByAHMAaQBvAG4AHRRQAGwAdQBnAGkAbgBHAHUAaQBkAB4WUwB5AHMAdABlAG0ALgBHAHUAaQBkAB9IYQBmAGMAZAA1ADQANAA2AC0ANAA5ADEANAAtADQAZgBlADcALQBiAGIANwA4AC0AOQBiAGYAZgBlAGIANwAwAGYAZAAxADcAIBRVAHAAZABhAHQAZQBJAG4AZgBvACFMewBiADAAMwAzADYANgBhADgALQBiADUAYwAwAC0ANABiADkAYQAtAGEAMAAwAGUALQBlAGIAOAA2ADAAMQAxADEAMAA0AGMAMwB9ACIOVQBwAGQAYQB0AGUAcwAjTHsAMQA4ADYAOABmAGYAYwA5AC0AZQA0AGYAYwAtADQANQAzADIALQBhAGMAMAA2AC0AMQBlADMAOQBiAGIANQA1ADcAYgA2ADkAfQAkTHsAYQA1AGIAZAA0ADgAYwAzAC0AMABkADEANwAtADQAMQBiADUALQBiADEANgA0AC0ANQBmAGMANgBhAGQAMgBiADkANgBiADcAfQAlFk8AYgBqAGUAYwB0AHMAVAB5AHAAZQAmVFUAcABkAGEAdABlAEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwARgBvAHIAQwBvAG4AdgBlAHIAdABpAGIAbABlAEwAaQBiAHIAYQByAGkAZQBzACcQTABpAGIAVABpAHQAbABlACgUTABpAGIAQwBvAG0AcABhAG4AeQApHlUAcABkAGEAdABlAFAAcgBvAHYAaQBkAGUAcgBzACo4UwB5AHMAdABlAG0ALgBDAG8AbABsAGUAYwB0AGkAbwBuAHMALgBIAGEAcwBoAHQAYQBiAGwAZQArEnYAaQBzAHUAZQBsAGUAbQBzACwMcwB5AHMAdABlAG0ALUg2AGMAYgAxAGMAZABlADEALQBkADUAZABjAC0ANABhADMAYgAtADkAMAA1ADQALQAyADEAZgBhADcANQA2AGEAMwBmAGEANAAuKEkAbgB0AGUAcgBmAGEAYwBlAFYAZQByAHMAaQBvAG4ASQBuAGYAbwAvTHsAYwA2ADEAMQBlADQAMAAwAC0ANwBmAGIAOQAtADQAYwAzADUALQBiADkAYQBjAC0ANABlADMAMQA0AGIANQA5ADkANgA0ADMAfQAwGE0AYQBqAG8AcgBWAGUAcgBzAGkAbwBuADEYTQBpAG4AbwByAFYAZQByAHMAaQBvAG4AMgxMAGUAZwBhAGMAeQAzMEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwAVgBlAHIAcwBpAG8AbgBJAG4AZgBvADQwTABvAGEAZABMAGkAYgByAGEAcgBpAGUAcwBJAG4AdABvAFAAcgBvAGoAZQBjAHQANRpDAG8AbQBwAGEAdABpAGIAaQBsAGkAdAB5ANAAAhoD0AMBLQTQBQYaB9AHCBoBRQcJCNAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0O0A8BLRDQAAkaBEUKCwQEAAAABwAAAAAAAAAAAAAA0AwLrQEAAADQDQEtEdAPAS0Q0AAJGgRFCgsEBAAAAAcAAAAAAAAAAAAAANAMC60CAAAA0A0BLRLQDwEtENAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0T0A8BLRDQAAkaBEUKCwQEAAAABwAAAAAAAAAAAAAA0AwLrQIAAADQDQEtFNAPAS0Q0AAJGgRFCgsEBAAAAAcAAAAAAAAAAAAAANAMC60CAAAA0A0BLRXQDwEtENAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0W0A8BLRDQAAkaBEUKCwQEAAAABwAAAAAAAAAAAAAA0AwLrQQAAADQDQEtF9APAS0Q0BgZrQFFGhsB0AAbGgJFHAsEBAAAAAIAAAAAAAAAAAAAANAdHi0f0CAhGgJFIiMC0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60AAAAA0AMBLSbQJwEtEdAoAS0Q0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60BAAAA0AMBLSbQJwEtEdAoAS0QmikqAUUAAQLQAAEtK9AAAS0s0AAeLS3QLi8aA9AwC60BAAAA0DELrSQAAADQMhmtANAzLxoD0DALrQIAAADQMQutBgAAANAyGa0A0DQZrQDQNRmtAA== + IR0whWr8bwfyBwAAMxnWswAAAABVAgAADu3eawAAAAABAAAAAAAAAAEaUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwACTHsAZgA5ADUAYgBiADQAMgA2AC0ANQA1ADIANAAtADQAYgA0ADUALQA5ADQAMAAwAC0AZgBiADAAZgAyAGUANwA3AGUANQAxAGIAfQADCE4AYQBtAGUABDJUAHcAaQBuAEMAQQBUACAAMwAuADEAIABCAHUAaQBsAGQAIAA0ADAAMgA2AC4AMQA4AAUWUAByAG8AZgBpAGwAZQBEAGEAdABhAAZMewAxADYAZQA1ADUAYgA2ADAALQA3ADAANAAzAC0ANABhADYAMwAtAGIANgA1AGIALQA2ADEANAA3ADEAMwA4ADcAOABkADQAMgB9AAcSTABpAGIAcgBhAHIAaQBlAHMACEx7ADMAYgBmAGQANQA0ADUAOQAtAGIAMAA3AGYALQA0AGQANgBlAC0AYQBlADEAYQAtAGEAOAAzADMANQA2AGEANQA1ADEANAAyAH0ACUx7ADkAYwA5ADUAOAA5ADYAOAAtADIAYwA4ADUALQA0ADEAYgBiAC0AOAA4ADcAMQAtADgAOQA1AGYAZgAxAGYAZQBkAGUAMQBhAH0ACg5WAGUAcgBzAGkAbwBuAAsGaQBuAHQADApVAHMAYQBnAGUADQpUAGkAdABsAGUADhpWAGkAcwB1AEUAbABlAG0ATQBlAHQAZQByAA8OQwBvAG0AcABhAG4AeQAQDFMAeQBzAHQAZQBtABESVgBpAHMAdQBFAGwAZQBtAHMAEjBWAGkAcwB1AEUAbABlAG0AcwBTAHAAZQBjAGkAYQBsAEMAbwBuAHQAcgBvAGwAcwATKFYAaQBzAHUARQBsAGUAbQBzAFcAaQBuAEMAbwBuAHQAcgBvAGwAcwAUJFYAaQBzAHUARQBsAGUAbQBUAGUAeAB0AEUAZABpAHQAbwByABUiVgBpAHMAdQBOAGEAdABpAHYAZQBDAG8AbgB0AHIAbwBsABYUVgBpAHMAdQBJAG4AcAB1AHQAcwAXGFYAaQBzAHUARQBsAGUAbQBCAGEAcwBlABgmRABlAHYAUABsAGEAYwBlAGgAbwBsAGQAZQByAHMAVQBzAGUAZAAZCGIAbwBvAGwAGiJQAGwAdQBnAGkAbgBDAG8AbgBzAHQAcgBhAGkAbgB0AHMAG0x7ADQAMwBkADUAMgBiAGMAZQAtADkANAAyAGMALQA0ADQAZAA3AC0AOQBlADkANAAtADEAYgBmAGQAZgAzADEAMABlADYAMwBjAH0AHBxBAHQATABlAGEAcwB0AFYAZQByAHMAaQBvAG4AHRRQAGwAdQBnAGkAbgBHAHUAaQBkAB4WUwB5AHMAdABlAG0ALgBHAHUAaQBkAB9IYQBmAGMAZAA1ADQANAA2AC0ANAA5ADEANAAtADQAZgBlADcALQBiAGIANwA4AC0AOQBiAGYAZgBlAGIANwAwAGYAZAAxADcAIBRVAHAAZABhAHQAZQBJAG4AZgBvACFMewBiADAAMwAzADYANgBhADgALQBiADUAYwAwAC0ANABiADkAYQAtAGEAMAAwAGUALQBlAGIAOAA2ADAAMQAxADEAMAA0AGMAMwB9ACIOVQBwAGQAYQB0AGUAcwAjTHsAMQA4ADYAOABmAGYAYwA5AC0AZQA0AGYAYwAtADQANQAzADIALQBhAGMAMAA2AC0AMQBlADMAOQBiAGIANQA1ADcAYgA2ADkAfQAkTHsAYQA1AGIAZAA0ADgAYwAzAC0AMABkADEANwAtADQAMQBiADUALQBiADEANgA0AC0ANQBmAGMANgBhAGQAMgBiADkANgBiADcAfQAlFk8AYgBqAGUAYwB0AHMAVAB5AHAAZQAmVFUAcABkAGEAdABlAEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwARgBvAHIAQwBvAG4AdgBlAHIAdABpAGIAbABlAEwAaQBiAHIAYQByAGkAZQBzACcQTABpAGIAVABpAHQAbABlACgUTABpAGIAQwBvAG0AcABhAG4AeQApHlUAcABkAGEAdABlAFAAcgBvAHYAaQBkAGUAcgBzACo4UwB5AHMAdABlAG0ALgBDAG8AbABsAGUAYwB0AGkAbwBuAHMALgBIAGEAcwBoAHQAYQBiAGwAZQArEnYAaQBzAHUAZQBsAGUAbQBzACwMcwB5AHMAdABlAG0ALUg2AGMAYgAxAGMAZABlADEALQBkADUAZABjAC0ANABhADMAYgAtADkAMAA1ADQALQAyADEAZgBhADcANQA2AGEAMwBmAGEANAAuKEkAbgB0AGUAcgBmAGEAYwBlAFYAZQByAHMAaQBvAG4ASQBuAGYAbwAvTHsAYwA2ADEAMQBlADQAMAAwAC0ANwBmAGIAOQAtADQAYwAzADUALQBiADkAYQBjAC0ANABlADMAMQA0AGIANQA5ADkANgA0ADMAfQAwGE0AYQBqAG8AcgBWAGUAcgBzAGkAbwBuADEYTQBpAG4AbwByAFYAZQByAHMAaQBvAG4AMgxMAGUAZwBhAGMAeQAzMEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwAVgBlAHIAcwBpAG8AbgBJAG4AZgBvADQwTABvAGEAZABMAGkAYgByAGEAcgBpAGUAcwBJAG4AdABvAFAAcgBvAGoAZQBjAHQANRpDAG8AbQBwAGEAdABpAGIAaQBsAGkAdAB5ANAAAhoD0AMBLQTQBQYaB9AHCBoBRQcJCNAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0O0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQEAAADQDQEtEdAPAS0Q0AAJGgRFCgsEBAAAAAcAAAAAAAAAAAAAANAMC60CAAAA0A0BLRLQDwEtENAACRoERQoLBAQAAAAIAAAAAAAAAAAAAADQDAutAgAAANANAS0T0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQIAAADQDQEtFNAPAS0Q0AAJGgRFCgsEBAAAAAgAAAAAAAAAAAAAANAMC60CAAAA0A0BLRXQDwEtENAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0W0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQQAAADQDQEtF9APAS0Q0BgZrQFFGhsB0AAbGgJFHAsEBAAAAAIAAAAAAAAAAAAAANAdHi0f0CAhGgJFIiMC0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60AAAAA0AMBLSbQJwEtEdAoAS0Q0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60BAAAA0AMBLSbQJwEtEdAoAS0QmikqAUUAAQLQAAEtK9AAAS0s0AAeLS3QLi8aA9AwC60BAAAA0DELrSQAAADQMhmtANAzLxoD0DALrQIAAADQMQutBgAAANAyGa0A0DQZrQDQNRmtAA== {8A0FB252-96EB-4DCC-A5B4-B4804D05E2D6} diff --git a/PLC/POUs/Analog/FB_AnalogOutput.TcPOU b/PLC/POUs/Analog/FB_AnalogOutput.TcPOU deleted file mode 100644 index be69e65..0000000 --- a/PLC/POUs/Analog/FB_AnalogOutput.TcPOU +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/PLC/POUs/Analog/FB_AnalogInput.TcPOU b/PLC/POUs/Components/Analog/FB_AnalogInput.TcPOU similarity index 63% rename from PLC/POUs/Analog/FB_AnalogInput.TcPOU rename to PLC/POUs/Components/Analog/FB_AnalogInput.TcPOU index 5124de2..7401732 100644 --- a/PLC/POUs/Analog/FB_AnalogInput.TcPOU +++ b/PLC/POUs/Components/Analog/FB_AnalogInput.TcPOU @@ -1,7 +1,7 @@  - - = _rMaxErrorLevel), + +_fbAlarmErrorHigh( + xActive:= (_rScaledValue >= _rMaxErrorLevel), xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError), + xAcknowledge:= xConfirmAlarms, timOnDelay:= stAnalogEWConfig.stDelays.timErrorHighOn, - timOffDelay:= stAnalogEWConfig.stDelays.timErrorHighOff); + timOffDelay:= stAnalogEWConfig.stDelays.timErrorHighOff, + xInUnitTestMode:= xInUnitTestMode); -_xErrorHigh := _fbSignalDelayErrorHigh.xReleaseSignal; +_xErrorHigh := _fbAlarmErrorHigh.Triggered; // Latch error IF _xErrorHigh THEN _xError := TRUE; END_IF -// Raise alarm -IF _fbSignalDelayErrorHigh.xReleaseSignal AND (NOT xInUnitTestMode) AND (NOT _fbAlarmErrorHigh.bRaised) THEN - _fbAlarmErrorHigh.Raise(0); -END_IF - -// Clear alarm -IF (NOT _fbSignalDelayErrorHigh.xReleaseSignal) AND _fbAlarmErrorHigh.bRaised THEN - _fbAlarmErrorHigh.Clear(0, FALSE); -END_IF - -// Confirm alarm -IF xConfirmAlarms AND (_fbAlarmErrorHigh.eConfirmationState = TcEventConfirmationState.WaitForConfirmation) THEN - _fbAlarmErrorHigh.Confirm(0); -END_IF - // =========================== // Error low alarm handling // =========================== - -_fbSignalDelayErrorLow( - xSignal:= (_rScaledValue <= _rMinErrorLevel), + +_fbAlarmErrorLow( + xActive:= (_rScaledValue <= _rMinErrorLevel), xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError), + xAcknowledge:= xConfirmAlarms, timOnDelay:= stAnalogEWConfig.stDelays.timErrorLowOn, - timOffDelay:= stAnalogEWConfig.stDelays.timErrorLowOff); + timOffDelay:= stAnalogEWConfig.stDelays.timErrorLowOff, + xInUnitTestMode:= xInUnitTestMode); -_xErrorLow := _fbSignalDelayErrorLow.xReleaseSignal; +_xErrorLow := _fbAlarmErrorLow.Triggered; // Latch error IF _xErrorLow THEN _xError := TRUE; END_IF -// Raise alarm -IF _fbSignalDelayErrorLow.xReleaseSignal AND (NOT xInUnitTestMode) AND (NOT _fbAlarmErrorLow.bRaised) THEN - _fbAlarmErrorLow.Raise(0); -END_IF - -// Clear alarm -IF (NOT _fbSignalDelayErrorLow.xReleaseSignal) AND _fbAlarmErrorLow.bRaised THEN - _fbAlarmErrorLow.Clear(0, FALSE); -END_IF - -// Confirm alarm -IF xConfirmAlarms AND (_fbAlarmErrorLow.eConfirmationState = TcEventConfirmationState.WaitForConfirmation) THEN - _fbAlarmErrorLow.Confirm(0); -END_IF - // =========================== // Warning high alarm handling // =========================== - -_fbSignalDelayWarningHigh( - xSignal:= (_rScaledValue >= _rMaxWarningLevel), + +_fbAlarmWarningHigh( + xActive:= (_rScaledValue >= _rMaxWarningLevel), xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError), + xAcknowledge:= xConfirmAlarms, timOnDelay:= stAnalogEWConfig.stDelays.timWarningHighOn, - timOffDelay:= stAnalogEWConfig.stDelays.timWarningHighOff); + timOffDelay:= stAnalogEWConfig.stDelays.timWarningHighOff, + xInUnitTestMode:= xInUnitTestMode); -_xWarningHigh := _fbSignalDelayWarningHigh.xReleaseSignal; - -// Raise alarm -IF _fbSignalDelayWarningHigh.xReleaseSignal AND (NOT xInUnitTestMode) AND (NOT _fbAlarmWarningHigh.bRaised) THEN - _fbAlarmWarningHigh.Raise(0); -END_IF - -// Clear alarm -IF (NOT _fbSignalDelayWarningHigh.xReleaseSignal) AND _fbAlarmWarningHigh.bRaised THEN - _fbAlarmWarningHigh.Clear(0, FALSE); -END_IF - -// Confirm alarm -IF xConfirmAlarms AND (_fbAlarmWarningHigh.eConfirmationState = TcEventConfirmationState.WaitForConfirmation) THEN - _fbAlarmWarningHigh.Confirm(0); -END_IF +_xWarningHigh := _fbAlarmWarningHigh.Triggered; // =========================== // Warning low alarm handling // =========================== - -_fbSignalDelayWarningLow( - xSignal:= (_rScaledValue <= _rMinWarningLevel), + +_fbAlarmWarningLow( + xActive:= (_rScaledValue <= _rMinWarningLevel), xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError), + xAcknowledge:= xConfirmAlarms, timOnDelay:= stAnalogEWConfig.stDelays.timWarningLowOn, - timOffDelay:= stAnalogEWConfig.stDelays.timWarningLowOff); + timOffDelay:= stAnalogEWConfig.stDelays.timWarningLowOff, + xInUnitTestMode:= xInUnitTestMode); -_xWarningLow := _fbSignalDelayWarningLow.xReleaseSignal; - -// Raise alarm -IF _fbSignalDelayWarningLow.xReleaseSignal AND (NOT xInUnitTestMode) AND (NOT _fbAlarmWarningLow.bRaised) THEN - _fbAlarmWarningLow.Raise(0); -END_IF - -// Clear alarm -IF (NOT _fbSignalDelayWarningLow.xReleaseSignal) AND _fbAlarmWarningLow.bRaised THEN - _fbAlarmWarningLow.Clear(0, FALSE); -END_IF - -// Confirm alarm -IF xConfirmAlarms AND (_fbAlarmWarningLow.eConfirmationState = TcEventConfirmationState.WaitForConfirmation) THEN - _fbAlarmWarningLow.Confirm(0); -END_IF +_xWarningLow := _fbAlarmWarningLow.Triggered; // ============ @@ -429,16 +352,16 @@ _xWarning := _xWarningLow OR _xWarningHigh; // Reset error flag // ================ -_xAlarmsActive := _fbAlarmConfigError.bActive - OR _fbAlarmUnderrange.bActive - OR _fbAlarmOverload.bActive - OR _fbAlarmCardError.bActive - OR _fbAlarmErrorHigh.bActive - OR _fbAlarmErrorLow.bActive; +_xAlarmsActive := _fbAlarmConfigError.Active + OR _fbAlarmUnderrange.Active + OR _fbAlarmOverload.Active + OR _fbAlarmCardError.Active + OR _fbAlarmErrorHigh.Active + OR _fbAlarmErrorLow.Active; -_xInputErrorsActive := _fbSignalDelayUnderrangeError.xReleaseSignal - OR _fbSignalDelayOverloadError.xReleaseSignal - OR _fbSignalDelayCardError.xReleaseSignal; +_xInputErrorsActive := _fbAlarmUnderrange.Triggered + OR _fbAlarmOverload.Triggered + OR _fbAlarmCardError.Triggered; IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) AND (NOT _xConfigError) THEN _xError := FALSE; @@ -562,10 +485,10 @@ _sTempErrorMax := CONCAT(REAL_TO_STRING(stAnalogEWConfig.stLevels.rErrorMax), _s {analysis -46} // Inser message parameters -_fbAlarmErrorLow.ipArguments.Clear().AddString(_sName).AddString(_sTempErrorMin); -_fbAlarmWarningLow.ipArguments.Clear().AddString(_sName).AddString(_sTempWarningMin); -_fbAlarmWarningHigh.ipArguments.Clear().AddString(_sName).AddString(_sTempWarningMax); -_fbAlarmErrorHigh.ipArguments.Clear().AddString(_sName).AddString(_sTempErrorMax); +_fbAlarmErrorLow.Arguments.Clear().AddString(_sName).AddString(_sTempErrorMin); +_fbAlarmWarningLow.Arguments.Clear().AddString(_sName).AddString(_sTempWarningMin); +_fbAlarmWarningHigh.Arguments.Clear().AddString(_sName).AddString(_sTempWarningMax); +_fbAlarmErrorHigh.Arguments.Clear().AddString(_sName).AddString(_sTempErrorMax); {analysis +46}]]> @@ -576,10 +499,10 @@ END_VAR ]]> @@ -623,7 +546,8 @@ END_VAR +CreateAlarmMSG(); +CreateAlarmLimitsMSG();]]> diff --git a/PLC/POUs/Components/Analog/FB_AnalogOutput.TcPOU b/PLC/POUs/Components/Analog/FB_AnalogOutput.TcPOU new file mode 100644 index 0000000..721f1b4 --- /dev/null +++ b/PLC/POUs/Components/Analog/FB_AnalogOutput.TcPOU @@ -0,0 +1,237 @@ + + + + + + + + + + + 0.0 THEN + _rConversionFactor := _rNum/_rDenom; + _rBaseOffset := INT_TO_REAL(stAnalogIOConfig.iAIMin) - (_rConversionFactor * stAnalogIOConfig.rPVMin); + _rPVMax := stAnalogIOConfig.rPVMax; + _rPVMin := stAnalogIOConfig.rPVMin; + _xConfigError := FALSE; +ELSE + // Division by zero happened + // Or denom was negative + // Set scaling to zero + _rConversionFactor := 0.0; + _rBaseOffset := 0.0; + _rPVMax := 0.0; + _rPVMin := 0.0; + _xConfigError := TRUE; +END_IF]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT b/PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT similarity index 100% rename from PLC/POUs/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT rename to PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT diff --git a/PLC/POUs/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT b/PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT similarity index 100% rename from PLC/POUs/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT rename to PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT diff --git a/PLC/POUs/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT b/PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT similarity index 100% rename from PLC/POUs/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT rename to PLC/POUs/Components/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT diff --git a/PLC/POUs/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT b/PLC/POUs/Components/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT similarity index 100% rename from PLC/POUs/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT rename to PLC/POUs/Components/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT diff --git a/PLC/POUs/EventListener/FB_EventListener.TcPOU b/PLC/POUs/Components/EventListener/FB_EventListener.TcPOU similarity index 100% rename from PLC/POUs/EventListener/FB_EventListener.TcPOU rename to PLC/POUs/Components/EventListener/FB_EventListener.TcPOU diff --git a/PLC/POUs/EventListener/Types/E_EventType.TcDUT b/PLC/POUs/Components/EventListener/Types/E_EventType.TcDUT similarity index 100% rename from PLC/POUs/EventListener/Types/E_EventType.TcDUT rename to PLC/POUs/Components/EventListener/Types/E_EventType.TcDUT diff --git a/PLC/POUs/EventListener/Types/ST_BufferEventEntry.TcDUT b/PLC/POUs/Components/EventListener/Types/ST_BufferEventEntry.TcDUT similarity index 100% rename from PLC/POUs/EventListener/Types/ST_BufferEventEntry.TcDUT rename to PLC/POUs/Components/EventListener/Types/ST_BufferEventEntry.TcDUT diff --git a/PLC/POUs/Components/Motor/FB_MotorBecker.TcPOU b/PLC/POUs/Components/Motor/FB_MotorBecker.TcPOU new file mode 100644 index 0000000..01c9dab --- /dev/null +++ b/PLC/POUs/Components/Motor/FB_MotorBecker.TcPOU @@ -0,0 +1,497 @@ + + + + + + _rSetpoint, + xInTarget=> _xRampGenInTarget); + +// Calculate target tolerance +_rPVTargetMax := _rSetpoint + stMotorConfig.rTargetTolerance; +_rPVTargetMin := _rSetpoint - stMotorConfig.rTargetTolerance; + + +// ============= +// Handle alarms +// ============= + +_fbMCBTrippedDelayedSignal( + xSignal:= (NOT xMCBOk), + xRelease:= stMotorConfig.xHasMCBFeedback AND xReleaseErrors, + timOnDelay:= , + timOffDelay:= , + xReleaseSignal=> ); + + +// ================ +// Reset error flag +// ================ + + +// ================================ +// Copy internal signals to outputs +// ================================ + +udiControlword := DWORD_TO_UDINT(_dwControlword); +xError := _xError; + +// ================== +// Handle HMI outputs +// ==================]]> + + + + + 0 THEN + _xProcessINTLKOk := FALSE; +END_IF + +// Check safety interlocks +// Safety interlocks will not automatically reset +// They need to be reset via the xConfirmAlarms input +IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN + _xSafetyINTLKOk := FALSE; +END_IF]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT b/PLC/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT new file mode 100644 index 0000000..501c906 --- /dev/null +++ b/PLC/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT @@ -0,0 +1,50 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Utilities/FB_AlarmMessage.TcPOU b/PLC/POUs/Components/Utilities/FB_AlarmMessage.TcPOU new file mode 100644 index 0000000..f4f6bf4 --- /dev/null +++ b/PLC/POUs/Components/Utilities/FB_AlarmMessage.TcPOU @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Utilities/FB_Blinker.TcPOU b/PLC/POUs/Components/Utilities/FB_Blinker.TcPOU new file mode 100644 index 0000000..0fbf8b4 --- /dev/null +++ b/PLC/POUs/Components/Utilities/FB_Blinker.TcPOU @@ -0,0 +1,35 @@ + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Utilities/FB_RampGenerator.TcPOU b/PLC/POUs/Components/Utilities/FB_RampGenerator.TcPOU new file mode 100644 index 0000000..6b479ea --- /dev/null +++ b/PLC/POUs/Components/Utilities/FB_RampGenerator.TcPOU @@ -0,0 +1,132 @@ + + + + + + T#0S THEN + _rRampUpSpeed := (rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampUp)); +ELSE + _rRampUpSpeed := rTargetMax; +END_IF +IF timRampDown <> T#0S THEN + _rRampDownSpeed := -(rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampDown)); +ELSE + _rRampDownSpeed := -rTargetMax; +END_IF + + +// Calculate distance left to go +_rDistanceToGo := rTarget - rSetpoint; + +// Calculate new setpoint +IF (_rDistanceToGo > 0.0) THEN + IF (_rDistanceToGo > _rRampUpSpeed) THEN + rSetpoint := rSetpoint + _rRampUpSpeed; + ELSE + rSetpoint := rTarget; + END_IF +ELSIF (_rDistanceToGo < 0.0) THEN + IF (_rDistanceToGo < _rRampDownSpeed) THEN + rSetpoint := rSetpoint + _rRampDownSpeed; + ELSE + rSetpoint := rTarget; + END_IF +ELSE + rSetpoint := rTarget; +END_IF + +// Check if we are in range of target range +IF ABS(rSetpoint-rTarget) <= 0.001 THEN + xInTarget := TRUE; +ELSE + xInTarget := FALSE; +END_IF ]]> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Utilities/FB_ReleaseSignal.TcPOU b/PLC/POUs/Components/Utilities/FB_ReleaseSignal.TcPOU similarity index 100% rename from PLC/POUs/Utilities/FB_ReleaseSignal.TcPOU rename to PLC/POUs/Components/Utilities/FB_ReleaseSignal.TcPOU diff --git a/PLC/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU b/PLC/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU new file mode 100644 index 0000000..9624e5d --- /dev/null +++ b/PLC/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU @@ -0,0 +1,34 @@ + + + + + + 0 DO + _udiHash := (_udiHash XOR BYTE_TO_UDINT(psKey^[_uiCounter])) * udiPrime; + _uiCounter := _uiCounter + 1; +END_WHILE + +// Return calculated Hash +FC_HashFNV1a_32Bit := _udiHash;]]> + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Valves/FB_Valve.TcPOU b/PLC/POUs/Components/Valves/FB_Valve.TcPOU new file mode 100644 index 0000000..1136261 --- /dev/null +++ b/PLC/POUs/Components/Valves/FB_Valve.TcPOU @@ -0,0 +1,520 @@ + + + + + + stValveConfig.xOpenWhenInterlocksActive) THEN + _xManualOpen := stValveConfig.xOpenWhenInterlocksActive; + END_IF +END_IF + +// Handle open close feedback +_xIsOpen := (stValveConfig.xHasOpenFeedback AND xOpenFeedback AND (NOT xCloseFeedback)) OR ((NOT stValveConfig.xHasOpenFeedback) AND _xOpenValve); +_xIsClosed := (stValveConfig.xHasClosedFeedback AND xCloseFeedback AND (NOT xOpenFeedback)) OR ((NOT stValveConfig.xHasClosedFeedback) AND (NOT _xOpenValve)); + + +// =========================== +// Valve did not open in time +// =========================== + +_fbAlarmDidNotOpen( + xActive:= _xOpenValve AND (NOT _xIsOpen), + xRelease:= xReleaseErrors, + xAcknowledge:= xConfirmAlarms, + timOnDelay:= stValveConfig.timTimeoutOpen, + timOffDelay:= T#0S, + xInUnitTestMode:= xInUnitTestMode); + +// Latch error signal +IF _fbAlarmDidNotOpen.Triggered THEN + _xError := TRUE; +END_IF + + +// =========================== +// Valve did not close in time +// =========================== + +_fbAlarmDidNotClose( + xActive:= (NOT _xOpenValve) AND (NOT _xIsClosed), + xRelease:= xReleaseErrors, + xAcknowledge:= xConfirmAlarms, + timOnDelay:= stValveConfig.timTimeoutClose, + timOffDelay:= T#0S, + xInUnitTestMode:= xInUnitTestMode); + +// Latch error signal +IF _fbAlarmDidNotClose.Triggered THEN + _xError := TRUE; +END_IF + + +// ================ +// Reset error flag +// ================ + +_xAlarmsActive := _fbAlarmDidNotOpen.Active OR _fbAlarmDidNotClose.Active; +_xInputErrorsActive := _fbAlarmDidNotOpen.Triggered OR _fbAlarmDidNotClose.Triggered; + +IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) THEN + _xError := FALSE; +END_IF + + +// ================================ +// Copy internal signals to outputs +// ================================ + +xOpenValve := _xOpenValve; +xCloseValve := (NOT _xOpenValve); + +xError := _xError; + + +// ================== +// Handle HMI outputs +// ================== + +HandleHMIOutput();]]> + + + + + 0 THEN + _xProcessINTLKOk := FALSE; +END_IF + +// Check safety interlocks +// Safety interlocks will not automatically reset +// They need to be reset via the xConfirmAlarms input +IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN + _xSafetyINTLKOk := FALSE; +END_IF]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Valves/FB_ValveAnalog.TcPOU b/PLC/POUs/Components/Valves/FB_ValveAnalog.TcPOU new file mode 100644 index 0000000..208da0f --- /dev/null +++ b/PLC/POUs/Components/Valves/FB_ValveAnalog.TcPOU @@ -0,0 +1,689 @@ + + + + + + iSetpoint, + xError => _xAnalogOutputError, + stHMIInterface:= stHMIInterface.stSetpoint); + +IF _fbAnalogOutput.xError THEN + _xError := TRUE; +END_IF + +// =================== +// Handle analog input +// =================== + +IF stValveConfig.xHasAnalogFeedback THEN + stValveConfig.stAnalogInputConfig.xUsed := TRUE; +ELSE + stValveConfig.stAnalogInputConfig.xUsed := FALSE; +END_IF + +_fbAnalogInput( + iAnalogValue:= iFeedbackValue, + xUnderrange:= _xHasUnderrangeFeedback AND xFeedbackUnderrange, + xOverrange:= _xHasOverrangeFeedback AND xFeedbackOverrange, + xErrorCard:= _xHasCardError AND xErrorCard, + stAnalogIOConfig:= stValveConfig.stAnalogInputConfig, + stAnalogEWConfig:= stValveConfig.stAnalogInputEWConfig, + xReleaseErrors:= xReleaseErrors, + xReleaseLimitErrors:= FALSE, + xReleaseHardwareErrors:= TRUE, + xInUnitTestMode := xInUnitTestMode, + xConfirmAlarms:= xConfirmAlarms, + rScaledValue=> _rCurrentValvePosition, + xError=> _xAnalogInputError, + xWarning=> _xWarningAnalogInput, + xErrorLow=> , + xWarningLow=> , + xWarningHigh=> , + xErrorHigh=> ); + +IF _fbAnalogInput.xError THEN + _xError := TRUE; +END_IF + +IF NOT stValveConfig.xHasAnalogFeedback THEN + _rCurrentValvePosition := _rSetpoint; +END_IF + + +// Handle open close feedback +_xIsOpen := (stValveConfig.xHasOpenFeedback AND xOpenFeedback AND (NOT xCloseFeedback)) OR ((NOT stValveConfig.xHasOpenFeedback) AND (_rCurrentValvePosition >= stValveConfig.rPVIsOpen)); +_xIsClosed := (stValveConfig.xHasClosedFeedback AND xCloseFeedback AND (NOT xOpenFeedback)) OR ((NOT stValveConfig.xHasClosedFeedback) AND (_rCurrentValvePosition <= stValveConfig.rPVIsOpen)); + + +// Calculate target tolerance +_rPVTargetMax := _rSetpoint + stValveConfig.rTargetTolerance; +_rPVTargetMin := _rSetpoint - stValveConfig.rTargetTolerance; + +// Check if valve position is in target +_xNotInRange := stValveConfig.xHasAnalogFeedback AND ((_rCurrentValvePosition < _rPVTargetMin) OR (_rCurrentValvePosition > _rPVTargetMax)); + +// ================== +// Not in range alarm +// ================== + +_fbAlarmNotInRange( + xActive:= _xNotInRange, + xRelease:= xReleaseErrors, + xAcknowledge:= xConfirmAlarms, + timOnDelay:= stValveConfig.timNotInRange, + timOffDelay:= T#0S, + xInUnitTestMode:= xInUnitTestMode); + +// Latch error signal +IF _fbAlarmNotInRange.Triggered THEN + _xError := TRUE; +END_IF + + +// =========================== +// Valve did not open in time +// =========================== + +_fbAlarmDidNotOpen( + xActive:= _xOpenValve AND (NOT _xIsOpen), + xRelease:= xReleaseErrors, + xAcknowledge:= xConfirmAlarms, + timOnDelay:= stValveConfig.timTimeoutOpen, + timOffDelay:= T#0S, + xInUnitTestMode:= xInUnitTestMode); + +// Latch error signal +IF _fbAlarmDidNotOpen.Triggered THEN + _xError := TRUE; +END_IF + + +// =========================== +// Valve did not close in time +// =========================== + +_fbAlarmDidNotClose( + xActive:= (NOT _xOpenValve) AND (NOT _xIsClosed), + xRelease:= xReleaseErrors, + xAcknowledge:= xConfirmAlarms, + timOnDelay:= stValveConfig.timTimeoutClose, + timOffDelay:= T#0S, + xInUnitTestMode:= xInUnitTestMode); + +// Latch error signal +IF _fbAlarmDidNotClose.Triggered THEN + _xError := TRUE; +END_IF + + +// ================ +// Reset error flag +// ================ + +_xAlarmsActive := _fbAlarmDidNotOpen.Active OR _fbAlarmDidNotClose.Active OR _fbAlarmNotInRange.Raised OR _xAnalogInputError OR _xAnalogOutputError; +_xInputErrorsActive := _fbAlarmDidNotOpen.Triggered OR _fbAlarmDidNotClose.Triggered OR _fbAlarmNotInRange.Triggered; + +IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) THEN + _xError := FALSE; +END_IF + + +// ================================ +// Copy internal signals to outputs +// ================================ + +xError := _xError; + + +// ================== +// Handle HMI outputs +// ================== + +HandleHMIOutput();]]> + + + + + 0 THEN + _xProcessINTLKOk := FALSE; +END_IF + +// Check safety interlocks +// Safety interlocks will not automatically reset +// They need to be reset via the xConfirmAlarms input +IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN + _xSafetyINTLKOk := FALSE; +END_IF]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT b/PLC/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT new file mode 100644 index 0000000..6c2d13c --- /dev/null +++ b/PLC/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT @@ -0,0 +1,60 @@ + + + + =5% + {attribute 'OPC.UA.DA' := '1'} + rPVIsOpen : REAL := 5.0; + + // Maximum allowable difference between setpoint and process value + // Defaults to +-5 + {attribute 'OPC.UA.DA' := '1'} + rTargetTolerance : REAL := 5.0; + + // Time for the valve to get to the requested setpoint + {attribute 'OPC.UA.DA' := '1'} + timNotInRange : TIME := T#30S; + + // Config parameters for the analog input + stAnalogInputConfig : ST_ANALOG_IO_CONFIG := (iAIMax := 32767, iAIMin := 0, rPVMax := 100, rPVMin := 0); + stAnalogInputEWConfig : ST_ANALOG_EW_CONFIG; + + // Config parameters for the analog output + stAnalogOutputConfig : ST_ANALOG_IO_CONFIG := (iAIMax := 32767, iAIMin := 0, rPVMax := 100, rPVMin := 0); + + // Timeout for the valve to open + // 0 = deactivated + {attribute 'OPC.UA.DA' := '1'} + timTimeoutOpen : TIME := T#0S; + + // Timeout for the valve to close + // 0 = deactivated + {attribute 'OPC.UA.DA' := '1'} + timTimeoutClose : TIME := T#0S; + + // Valve has open feedback signal + {attribute 'OPC.UA.DA' := '1'} + xHasOpenFeedback : BOOL; + + // Valve has close feedback signal + {attribute 'OPC.UA.DA' := '1'} + xHasClosedFeedback : BOOL; + + // Valve has analog feedback signal + {attribute 'OPC.UA.DA' := '1'} + xHasAnalogFeedback : BOOL; + + // Set setpoint to use if interlocks are active + // defaults to 0 + rSetpointWhenInterlocksActive : REAL := 0; + + // Valve is used + {attribute 'OPC.UA.DA' := '1'} + xUsed : BOOL := TRUE; +END_STRUCT +END_TYPE +]]> + + \ No newline at end of file diff --git a/PLC/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT b/PLC/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT new file mode 100644 index 0000000..36de109 --- /dev/null +++ b/PLC/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT @@ -0,0 +1,35 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Constants/GVL_TYPE_CONST.TcGVL b/PLC/POUs/Constants/GVL_TYPE_CONST.TcGVL new file mode 100644 index 0000000..486713b --- /dev/null +++ b/PLC/POUs/Constants/GVL_TYPE_CONST.TcGVL @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/GVL/GVL_CONFIGS.TcGVL b/PLC/POUs/GVL/GVL_CONFIGS.TcGVL new file mode 100644 index 0000000..0372d33 --- /dev/null +++ b/PLC/POUs/GVL/GVL_CONFIGS.TcGVL @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT new file mode 100644 index 0000000..00fbb33 --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT @@ -0,0 +1,54 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT new file mode 100644 index 0000000..f570dab --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT @@ -0,0 +1,46 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT new file mode 100644 index 0000000..1370b96 --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT @@ -0,0 +1,54 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT new file mode 100644 index 0000000..6666a42 --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT @@ -0,0 +1,26 @@ + + + + PLC + // The HMI writes here to signal the plc + // that it wants to command this button + {attribute 'OPC.UA.DA' := '1'} + xRequest : BOOL; + + // Signals if the Button can be used by the HMI (read only) + {attribute 'OPC.UA.DA' := '1'} + {attribute 'OPC.UA.DA.Access' := '1'} + xRelease : BOOL; + + // Current state of the button (read only) + // 0 = none, 1 = active, 2 = pending, 3 = waring, 4 = error (Type int) + {attribute 'OPC.UA.DA' := '1'} + {attribute 'OPC.UA.DA.Access' := '1'} + eFeedback : E_HMI_BUTTON_FEEDBACK; +END_STRUCT +END_TYPE +]]> + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT new file mode 100644 index 0000000..41150af --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT @@ -0,0 +1,46 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT new file mode 100644 index 0000000..2b6ba3c --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT @@ -0,0 +1,50 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT new file mode 100644 index 0000000..941f421 --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT @@ -0,0 +1,47 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT b/PLC/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT new file mode 100644 index 0000000..6237868 --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT @@ -0,0 +1,49 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT b/PLC/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT new file mode 100644 index 0000000..15d4bad --- /dev/null +++ b/PLC/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT b/PLC/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT new file mode 100644 index 0000000..fb1f1dc --- /dev/null +++ b/PLC/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT b/PLC/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT new file mode 100644 index 0000000..0e731e4 --- /dev/null +++ b/PLC/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Enum/E_HMI_MODE.TcDUT b/PLC/POUs/HMI/Enum/E_HMI_MODE.TcDUT new file mode 100644 index 0000000..ab57951 --- /dev/null +++ b/PLC/POUs/HMI/Enum/E_HMI_MODE.TcDUT @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT b/PLC/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT new file mode 100644 index 0000000..47b13c7 --- /dev/null +++ b/PLC/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT b/PLC/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT new file mode 100644 index 0000000..c1d6d45 --- /dev/null +++ b/PLC/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/PLC/POUs/PRG_MAIN.TcPOU b/PLC/POUs/PRG_MAIN.TcPOU index 786374f..75b1bcd 100644 --- a/PLC/POUs/PRG_MAIN.TcPOU +++ b/PLC/POUs/PRG_MAIN.TcPOU @@ -1,13 +1,31 @@  - diff --git a/PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU b/PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU new file mode 100644 index 0000000..3098565 --- /dev/null +++ b/PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU @@ -0,0 +1,469 @@ + + + + + + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// evaluate Error and result to zero +AssertTrue(_xError, 'There should be an error when trying to divide by zero.'); +AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by zero'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// evaluate Error and result to zero +AssertTrue(_xError, 'There should be an error when trying to divide by zero.'); +AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by negative number.'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// due to only moving real, a delta of 0.01 should be sufficient. +// testing all HMI values +AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMax, Actual := _stHMIInterface.rMax, Delta := rDelta,'rMax was not passed to HMI correctly.'); +AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMin, Actual := _stHMIInterface.rMin, Delta := rDelta,'rMin was not passed to HMI correctly.'); +// rValue from HMI Interface functions as an Input to the FB. If the FB would write it back we would have a loop! +{analysis -140} +//AssertEquals_REAL(Expected := rExpected, Actual := stHMIInterface.rValue, Delta := rDelta,'rValue was not passed to HMI correctly.'); +{analysis +140} +AssertEquals_STRING(Expected := sName, Actual := _stHMIInterface.sName, 'sName was not passed to HMI correctly.'); +AssertEquals_STRING(Expected := sUnit, Actual := _stHMIInterface.sUnit, 'sUnit was not passed to HMI correctly.'); +AssertTrue(_stHMIInterface.xUsed, 'xUsed is not passed to HMI correctly.'); +AssertEquals_INT(Expected := iOk, Actual := _stHMIInterface.iStatus, 'Status is Error when OK was expected.'); + +// testing error passtrough (div by zero) +_stAnalogOutputConfig.rPVMax := 0; +_stAnalogOutputConfig.rPVMin := 0; + +// run analog scaling +_fbAnalogOutput( + rSetpoint := 0, + stAnalogIOConfig := _stAnalogOutputConfig, + xReleaseErrors := , + xConfirmAlarms := , + stHMIInterface := _stHMIInterface, + iAnalogValue => _iAnalogOutput, + xError => _xError); + +// reading error from HMI interface +AssertEquals_INT(Expected := iError, Actual := _stHMIInterface.iStatus, 'Status is OK when Error was expected.'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// and evaluate result +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected1, Actual := _iAnalogOutput,'Result was not calculated correctly.'); + +// run second value +_fbAnalogOutput( + rSetpoint := 87.5, //87,5 * 81,9 - 4095 = 3071 + stAnalogIOConfig := _stAnalogOutputConfig, + xReleaseErrors := , + xConfirmAlarms := , + stHMIInterface := _stHMIInterface, + iAnalogValue => _iAnalogOutput, + xError => _xError); + +// and evaluate result +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected2, Actual := _iAnalogOutput,'Result was not calculated correctly.'); + +// run third value +_fbAnalogOutput( + rSetpoint := 54.321, //54,321 * 81,9 - 4095 = 354 + stAnalogIOConfig := _stAnalogOutputConfig, + xReleaseErrors := , + xConfirmAlarms := , + stHMIInterface := _stHMIInterface, + iAnalogValue => _iAnalogOutput, + xError => _xError); + +// and evaluate result +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected3, Actual := _iAnalogOutput,'Result was not calculated correctly.'); + +// run forth value +_fbAnalogOutput( + rSetpoint := 99, //99 * 81,9 - 4095 = 4013 + stAnalogIOConfig := _stAnalogOutputConfig, + xReleaseErrors := , + xConfirmAlarms := , + stHMIInterface := _stHMIInterface, + iAnalogValue => _iAnalogOutput, + xError => _xError); + +// and evaluate result +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected4, Actual := _iAnalogOutput,'Result was not calculated correctly.'); + +// run fifth value +_fbAnalogOutput( + rSetpoint := 75.12345, // 75,12345 * 81,9 - 4095 = 2058 + stAnalogIOConfig := _stAnalogOutputConfig, + xReleaseErrors := , + xConfirmAlarms := , + stHMIInterface := _stHMIInterface, + iAnalogValue => _iAnalogOutput, + xError => _xError); + +// and evaluate result +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected5, Actual := _iAnalogOutput,'Result was not calculated correctly.'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// evaluate wethere the result is the equivalent of lower cap or not +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// evaluate wethere the result is the equivalent of upper cap or not +AssertFalse(_xError, 'There should not be an error here.'); +AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.'); + +TEST_FINISHED();]]> + + + + + + _iAnalogOutput, + xError => _xError, + xInUnitTestMode := TRUE); + +// test for error and output (should not be present and 0 when unused) +AssertFalse(_xError, 'There should not be an error when unused.'); +AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when unused'); + +TEST_FINISHED();]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU b/PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU new file mode 100644 index 0000000..44cd6fe --- /dev/null +++ b/PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU @@ -0,0 +1,547 @@ + + + + + + + + + + + _xError, xInUnitTestMode := TRUE); + +// assert result +AssertTrue(_xError, 'Expected NotInRangeError, got no error.'); + +TEST_FINISHED();]]> + + + + + + + + + + + + _xError, + xInUnitTestMode := TRUE); + +// assert result +AssertTrue(_xError, 'Expected Overrange error, got no error.'); + +TEST_FINISHED();]]> + + + + + + _xError, + xInUnitTestMode := TRUE); + +// assert result +AssertTrue(_xError, 'Expected Underrange error, got no error.'); + +TEST_FINISHED();]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU b/PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU new file mode 100644 index 0000000..e8afac2 --- /dev/null +++ b/PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU @@ -0,0 +1,188 @@ + + + + + + + + + + + _xReturnValue); + +// Start timer after which the output of the Signal fb will be checked +_fbOffTimer(IN := TRUE, PT := (timOffTime + T#50MS)); + +IF _xSignalForOffTest THEN + _xSignalForOffTest := FALSE; +END_IF + +// Signal must be true at the start of the test +// If not, abort the test +IF _xSignalForOffTest AND (NOT _xReturnValue) THEN + AssertTrue(Condition := _xReturnValue, Message := 'Signal not true at start of test'); + _xTestWithOffTimeFinished := TRUE; +END_IF + +// Check value after a time which is longer than the signal delay time +IF NOT _fbOffTimer.Q THEN + IF (NOT _xReturnValue) THEN + AssertFalse(Condition := _xReturnValue, Message := 'Signal was false before the time was over'); + _fbOnTimer.IN := FALSE; + _xTestWithOffTimeFinished := TRUE; + END_IF +ELSE + AssertFalse(Condition := _xReturnValue, Message := 'Signal was not false after the time elapsed'); + _fbOnTimer.IN := FALSE; + _xTestWithOffTimeFinished := TRUE; +END_IF + +IF _xTestWithOffTimeFinished THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xReturnValue); + +// Start timer after which the output of the Signal fb will be checked +_fbOnTimer(IN := TRUE, PT := (timOnTime + T#50MS)); + +// Check value after a time which is longer than the signal delay time +IF NOT _fbOnTimer.Q THEN + IF _xReturnValue THEN + AssertTrue(Condition := _xReturnValue, Message := 'Signal was true before the time was over'); + _fbOnTimer.IN := FALSE; + _xTestWithOnTimeFinished := TRUE; + END_IF +ELSE + AssertTrue(Condition := _xReturnValue, Message := 'Signal was not true after the time elapsed'); + _fbOnTimer.IN := FALSE; + _xTestWithOnTimeFinished := TRUE; +END_IF + +IF _xTestWithOnTimeFinished THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xReturnValue); + +AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false'); + + +// Test high signal +_xSignal := TRUE; +_xExpected := TRUE; +_fbReleaseSignal( + xSignal:= _xSignal, + xRelease:= _xRelease, + timOnDelay:= T#0MS, + timOffDelay:= T#0MS, + xReleaseSignal=> _xReturnValue); + +AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not true'); + +// Test with inactive release +_xRelease := FALSE; +_xSignal := TRUE; +_xExpected := FALSE; +_fbReleaseSignal( + xSignal:= _xSignal, + xRelease:= _xRelease, + timOnDelay:= T#0MS, + timOffDelay:= T#0MS, + xReleaseSignal=> _xReturnValue); + +AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false with no active release'); + +TEST_FINISHED();]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU b/PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU new file mode 100644 index 0000000..27b6cd0 --- /dev/null +++ b/PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU @@ -0,0 +1,301 @@ + + + + + + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq0_1HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq0_1Hz.Q THEN + _iFreq0_1HzCounter := _iFreq0_1HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq0_1HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq0_5HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq0_5Hz.Q THEN + _iFreq0_5HzCounter := _iFreq0_5HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq0_5HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq1HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq1Hz.Q THEN + _iFreq1HzCounter := _iFreq1HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq1HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq2HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq2Hz.Q THEN + _iFreq2HzCounter := _iFreq2HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq2HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq50HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq50Hz.Q THEN + _iFreq50HzCounter := _iFreq50HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq50HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _xOut); + +// check results for each cycle depending on alternating timers +IF _fbDelayFreq5HzOnTimer.Q THEN + AssertTrue(_xOut, 'xOut is supposed to be true but is false.'); +ELSE + AssertFalse(_xOut, 'xOut is supposed to be false but is true.'); +END_IF + +// increment counter when timer is done +IF _fbRtrigFreq5Hz.Q THEN + _iFreq5HzCounter := _iFreq5HzCounter + 1; +END_IF + +// finish test after 5 blinking cycles +IF _iFreq5HzCounter > 5 THEN + TEST_FINISHED(); +END_IF]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU b/PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU new file mode 100644 index 0000000..691a5f4 --- /dev/null +++ b/PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU b/PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU new file mode 100644 index 0000000..8f9569a --- /dev/null +++ b/PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU @@ -0,0 +1,276 @@ + + + + + + + + + + + 0.0001 THEN + AssertTrue(FALSE, 'Project cycle time not set to 10ms!'); +ELSE + _fbPT1( + lrInput := 0, + timT := T#10MS, + lrOutput => ); + + // Project should be set to 10ms cycle time for this test to work + AssertEquals_LREAL(Expected := 10.0, Actual := _fbPT1.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)'); +END_IF + +TEST_FINISHED();]]> + + + + + + _lrOutput); + +// set error message according to current step +_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_15_2345)); +_sMessage := CONCAT(_sMessage, ' did not return expected value.'); + +// check values of current step +AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_15_2345[_iCounterStepPT1_15_2345], Actual := _lrOutput, Delta := lrDelta, _sMessage); +_iCounterStepPT1_15_2345 := _iCounterStepPT1_15_2345 + 1; + +// finish test after 20 cycles +IF _iCounterStepPT1_15_2345 > 20 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _lrOutput); + +// set error message according to current step +_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_168)); +_sMessage := CONCAT(_sMessage, ' did not return expected value.'); + +// check values of current step +AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_168[_iCounterStepPT1_168], Actual := _lrOutput, Delta := lrDelta, _sMessage); +_iCounterStepPT1_168 := _iCounterStepPT1_168 + 1; + +// finish test after 20 cycles +IF _iCounterStepPT1_168 > 20 THEN + TEST_FINISHED(); +END_IF]]> + + + + + + _lrOutput); + +// set error message according to current step +_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_50)); +_sMessage := CONCAT(_sMessage, ' did not return expected value.'); + +// check values of current step +AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_50[_iCounterStepPT1_50], Actual := _lrOutput, Delta := lrDelta, _sMessage); +_iCounterStepPT1_50 := _iCounterStepPT1_50 + 1; + +// finish test after 20 cycles +IF _iCounterStepPT1_50 > 20 THEN + TEST_FINISHED(); +END_IF]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU b/PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU new file mode 100644 index 0000000..d09b19a --- /dev/null +++ b/PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU @@ -0,0 +1,473 @@ + + + + + + + + + + + 0.001 THEN + AssertTrue(FALSE, 'Project cycle time not set to 10ms!'); +ELSE + _fbRampGen( + rTarget:= 0.0, + rTargetMin:= 0.0, + rTargetMax:= 100.0, + timRampUp:= T#5S, + timRampDown:= T#5S, + rSetpoint=> , + xInTarget=> ); + + // Project should be set to 10ms cycle time for this test to work + AssertEquals_REAL(Expected := 10.0, Actual := _fbRampGen.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)'); +END_IF + +TEST_FINISHED();]]> + + + + + + _rSetpoint, + xInTarget => _xInTarget); + +// check for whether InTarget is reached at the specified time +IF NOT _fbDelayInTargetResultDown.Q THEN + AssertFalse(_xInTarget, 'InTarget reached earlier then expected.'); +ELSE + AssertTrue(_xInTarget, 'InTarget not reached in time.'); + TEST_FINISHED(); +END_IF]]> + + + + + + _rSetpoint, + xInTarget => _xInTarget); + +// check for whether InTarget is reached at the specified time +IF NOT _fbDelayInTargetResultUp.Q THEN + AssertFalse(_xInTarget, 'InTarget reached earlier then expected.'); +ELSE + AssertTrue(_xInTarget, 'InTarget not reached in time.'); + TEST_FINISHED(); +END_IF]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check for clamping +IF NOT _fbDelayMaxClamp.Q THEN + // too early + AssertTrue(_rSetpoint < rExpected,'Clamped value reached before expected time'); +ELSE + // after expected rampTime + IF NOT _fbDelayMaxClampBuffer.Q THEN + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MaxTarget'); + ELSE + TEST_FINISHED(); + END_IF +END_IF]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check for clamping +IF NOT _fbDelayMinClamp.Q THEN + // too early + AssertTrue(_rSetpoint >= (rExpected - rDelta), 'Clamped value reached before expected time'); +ELSE + // after expected rampTime + IF NOT _fbDelayMinClampBuffer.Q THEN + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MinTarget'); + ELSE + TEST_FINISHED(); + END_IF +END_IF]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check for current expected value +IF NOT _fbDelayRampDownContinuity.Q THEN + AssertEquals_REAL(Expected := _rNextExpectedDown, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.'); +ELSE + // check for final value + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.'); + TEST_FINISHED(); +END_IF]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check whether final value is reach on time or before +IF NOT _fbDelayRampDownTime.Q THEN + AssertTrue(_rSetpoint > (rExpected - rDelta),'Value reached before expected time.'); +ELSE + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.'); + TEST_FINISHED(); +END_IF +]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check for current expected value +IF NOT _fbDelayRampUpContinuity.Q THEN + AssertEquals_REAL(Expected := _rNextExpectedUp, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.'); +ELSE + // check for final value + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.'); + TEST_FINISHED(); +END_IF]]> + + + + + + _rSetpoint, + xInTarget =>); + +// check whether final value is reach on time or before +IF NOT _fbDelayRampUpTime.Q THEN + AssertTrue(_rSetpoint < rExpected,'Value reached before expected time.'); +ELSE + AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.'); + TEST_FINISHED(); +END_IF]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU new file mode 100644 index 0000000..356cc0a --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU @@ -0,0 +1,282 @@ + + + + + + + + + + + , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= _stValveConfig, + xOpenValve=> , + xCloseValve=> ); + +// Valve should now be in manual mode and xRequest should have been reset +AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode'); +AssertFalse(Condition := _stHMIValve.stManualButton.xRequest, Message := 'Valve did not reset the manual mode button request'); + + +TEST_FINISHED();]]> + + + + + + , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= _stValveConfig, + xOpenValve=> , + xCloseValve=> ); + +AssertFalse(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was released but should not have been'); + + +// Test release for HMI mode change +_fbValve( + xReleaseManualMode:= TRUE, + wProcessINTLK:= _wInterlocks, + wProcessINTLKUsed:= _wInterlocksUsed, + stHMIInterface:= _stHMIValve, + xError=> , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= , + xOpenValve=> , + xCloseValve=> ); + +AssertTrue(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was not released but should have been'); + +TEST_FINISHED();]]> + + + + + + , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= _stValveConfig, + xOpenValve=> , + xCloseValve=> ); + +// Valve should now be in manual mode +AssertTrue(Condition := _fbValveOC.IsInManualMode, Message := 'Valve did not change to manual mode pre test'); + +// Request open from HMI and call valve block +_stHMIValve.stOpenButton.xRequest := TRUE; +_fbValveOC( + xReleaseManualMode:= TRUE, + wProcessINTLK:= _wInterlocks, + wProcessINTLKUsed:= _wInterlocksUsed, + stHMIInterface:= _stHMIValve, + xError=> , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= , + xOpenValve=> , + xCloseValve=> ); + +// test for valve state and HMI feedback +AssertTrue(Condition := _fbValveOC.xOpenValve, Message := 'Valve did not open as requested by hmi button'); +AssertFalse(Condition := _stHMIValve.stOpenButton.xRequest, Message := 'Valve did not reset open request'); +_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE; +_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE; +AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while open'); +AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while open'); + +// Request close from HMI and call valve block +_stHMIValve.stCloseButton.xRequest := TRUE; +_fbValveOC( + xReleaseManualMode:= TRUE, + wProcessINTLK:= _wInterlocks, + wProcessINTLKUsed:= _wInterlocksUsed, + stHMIInterface:= _stHMIValve, + xError=> , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= , + xOpenValve=> , + xCloseValve=> ); + +// test for valve state and HMI feedback +AssertTrue(Condition := _fbValveOC.xCloseValve, Message := 'Valve did not close as requested by hmi button'); +AssertFalse(Condition := _stHMIValve.stCloseButton.xRequest, Message := 'Valve did not reset close request'); +_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE; +_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE; +AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while closed'); +AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while closed'); + +TEST_FINISHED();]]> + + + + + + , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= _stValveConfig, + xOpenValve=> , + xCloseValve=> ); + +// Valve should now be in manual mode +AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode pre test'); + +// Valve should not realease open button with active interlock +AssertFalse(Condition := _stHMIValve.stOpenButton.xRelease, Message := 'Valve did release open button but should not'); + +// Test if request is denied by valve with active interlocks +_stHMIValve.stOpenButton.xRequest := TRUE; +_fbValve( + xReleaseManualMode:= TRUE, + wProcessINTLK:= wInterlocks, + wProcessINTLKUsed:= wInterlocksUsed, + stHMIInterface:= _stHMIValve, + xError=> , + xOpenFeedback:= , + xCloseFeedback:= , + xReleaseErrors:= , + xConfirmAlarms:= , + stValveConfig:= , + xOpenValve=> , + xCloseValve=> ); + +AssertFalse(Condition := _fbValve.xOpenValve, Message := 'Valve did not block manual open command with active interlock'); + +TEST_FINISHED();]]> + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU new file mode 100644 index 0000000..b0e27bf --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU new file mode 100644 index 0000000..502ee48 --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU new file mode 100644 index 0000000..1ef858b --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU new file mode 100644 index 0000000..2dd502d --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU b/PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU new file mode 100644 index 0000000..0da7afa --- /dev/null +++ b/PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_Config/IO/Gerät 1 (EtherCAT).xti b/_Config/IO/Gerät 1 (EtherCAT).xti new file mode 100644 index 0000000..dda19e7 --- /dev/null +++ b/_Config/IO/Gerät 1 (EtherCAT).xti @@ -0,0 +1,20 @@ + + + + __FILENAME__ + + + + + 000000000000 + + + + Prozessabbild + + + + + + + diff --git a/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti b/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti new file mode 100644 index 0000000..1e153df --- /dev/null +++ b/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti @@ -0,0 +1,71 @@ + + + + 424de6000000000000007600000028000000100000000e000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff0088888888888888888888888888888888fff666ffff6666f8fff6877ff67876fffff7f77ffff67ffffff7f768ff6ffffffff7f78ff67ffffffff7ffff67fffffffff7f78ff67ffffffff7f766fff7fffffff7f77f6fff67fffff6877ff67876ffffffffffffffffffffffffffffffffff + + + __FILENAME__ + 1000 + + 001080003600010001000000800080008000001036010000 + 801080003200010002000000800080008000801032010000 + 00111800740001000300000000000001c800001174010000 + 00142800300001000400000000000001c800001430010000 + 0000000000000000001100020100000001000000000000000000000000000000 + 0000000000000000001400010100000002000000000000000000000000000000 + 00000000000000000d0800010100000003000000000000000000000000000000 + + + UDINT + + + REAL + + + REAL + + + REAL + + + REAL + + + REAL + + + UDINT + + + REAL + + + UDINT + + + UDINT + + + + + UDINT + + + REAL + + + UDINT + + + REAL + + + UDINT + + + UDINT + + + + +