Supported platforms: CODESYS 3.5, CODESYS 3.5 SAFETY
This section describes how to control proportional valves.
|
This example uses the following libraries: SafeProportionalValveControl library
, or alternatively non-safe library SensorsAndActuators library
|
|
Depending on hardware, output group control needs to be activated before controlling outputs. See How to use S series and E series HW diagnostics for more information.
|
|
Currently, the S Series and E Series control unit's code template S_Outputs / Outputs programs provide interface for all output related variables defined in Epec MultiTool Creator. All output related function blocks are implemented by the application. |
|
External voltage detection in output pins is provided by safety control unit's switch startup test. The startup test execution depends on used product:
After startup test the external voltage is monitored by application diagnostics. |
|
Application level detection is required if external voltage needs to be monitored while operational (application functionality specific). External voltage can be monitored using DOS status of the output when PWM control is not active. |
|
Positive and negative attenuation signal statuses are probably non-validated DI signals, i.e. simple S_ADCToVoltageOrCurrent and S_VoltageToDI conversions. |
|
In the following example, the output pin external voltage error is not monitored when control is inactive. See the How to control DO & DO ECO example for more information. |
|
When the following example is used with non-safety I/O, the I/O variables are generated in Inputs and Outputs programs instead of S_Inputs and S_Outputs. |
The following I/O is defined in MultiTool Creator:
BoomUp as PWFM
BoomDown as PWFM
PosDirAttOn as DI
NegDirAttOn as DI
This example covers only proportional valve output control. The joystick control request variable S_JoystickControl is defined but not implemented.
Safe PRG declarations: |
VAR S_BoomCurrentReqUp: EPEC_SPVC.S_CurrentRequest; S_BoomCurrentReqDown: EPEC_SPVC.S_CurrentRequest; S_BoomControlRamp: EPEC_SPVC.S_LinearRamp; S_BoomEndAttenuation: EPEC_SPVC.S_EndAttenuation; S_BoomUpValve: EPEC_SPVC.S_AdaptiveController; S_BoomDownValve: EPEC_SPVC.S_AdaptiveController;
initDone: BOOL; S_JoystickControl: SAFEINT; (*Control signal from joystick, not implemented in this example*) enableControl: SAFEBOOL; (*Control enable conditions*)
(*ec_controlUp can be replaced with Joystick's event code if it exists in same control unit*) ec_controlUp: EPEC_DITF.EventCode; ec_controlDown: EPEC_DITF.EventCode;
(*Current controller parameters *) ccParams:ARRAY [1..S_CURRENT_CONTROLLER_PAR_COUNT] OF UINT := [1359,1307,1231,1172,1137,1113,1103,1093,1088,1076,1075,1075,1075,1078,1076,1075,1034,1014,1014,1014]; ccParamsImpUp: ARRAY [1..S_CURRENT_CONTROLLER_PAR_COUNT] OF UINT := [ 1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,950,950,950,950,950,1000,1000,1000,1000,1000 ]; ccParamsImpDown:ARRAY [1..S_CURRENT_CONTROLLER_PAR_COUNT] OF UINT:= [ 1200,1200,1100,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000]; END_VAR VAR CONSTANT S_CURRENT_CONTROLLER_PAR_COUNT : SAFEBYTE := BYTE#20; S_CURRENT_CONTROLLER_PAR_STEP: SAFEBYTE := BYTE#50; BOOM_VALVE_FREQ: DWORD := 200; END_VAR
|
Init method: |
IF NOT initDone THEN initDone:=TRUE;
(*Application specific parameters*)
(*ec_controlUp can be replaced with Joystick's event code if it exists in same control unit*) S_BoomEndAttenuation.Init( S_i_PosDirAttenuationLimit := UINT#90, S_i_NegDirAttenuationLimit := UINT#90, i_pEventCode := ADR(ec_controlUp), i_pEventCodePosDirAtt := ADR(S_Inputs.o_EventCode_PosDirAttOn), i_pEventCodeNegDirAtt := ADR(S_Inputs.o_EventCode_NegDirAttOn) );
S_BoomControlRamp.Init( S_i_PosDirAscendRampTime := UINT#1000, S_i_PosDirDescendRampTime := UINT#1000, S_i_NegDirAscendRampTime := UINT#1000, S_i_NegDirDescendRampTime := UINT#1000, S_i_EnableCounterControl := FALSE, i_pEventCode := ADR(ec_controlUp) );
S_BoomCurrentReqUp.Init( S_i_MinimumCurrent := UINT#150, S_i_MaximumCurrent := UINT#600, S_i_PositiveControlDir := TRUE, i_pEventCode := ADR(ec_controlUp) );
S_BoomUpValve.Init( S_i_CoilResistance := UDINT#22000, S_i_OverCurrentLimit := UINT#1100, S_i_WireBrokenLimit := UINT#50, S_i_DiagnosticDelay := UINT#100, i_pCorrectionParameters := ADR(ccParams), i_pImpulseUpParameters := ADR(ccParamsImpUp), i_pImpulseDownParameters := ADR(ccParamsImpDown), S_i_ParameterCount := S_CURRENT_CONTROLLER_PAR_COUNT, S_i_ParStep := S_CURRENT_CONTROLLER_PAR_STEP, i_pEventCode := ADR(ec_controlUp) );
S_BoomCurrentReqDown.Init( S_i_MinimumCurrent := UINT#150, S_i_MaximumCurrent := UINT#600, S_i_PositiveControlDir := FALSE, i_pEventCode := ADR(ec_controlDown) );
S_BoomDownValve.Init( S_i_CoilResistance := UDINT#22000, S_i_OverCurrentLimit := UINT#1100, S_i_WireBrokenLimit := UINT#50, S_i_DiagnosticDelay := UINT#100, i_pCorrectionParameters := ADR(ccParams), i_pImpulseUpParameters := ADR(ccParamsImpUp), i_pImpulseDownParameters := ADR(ccParamsImpDown), S_i_ParameterCount := S_CURRENT_CONTROLLER_PAR_COUNT, S_i_ParStep := S_CURRENT_CONTROLLER_PAR_STEP, i_pEventCode := ADR(ec_controlDown) );
END_IF
|
The following code is common for both control directions.
Code at safe PRG: |
|
The following code controls boom up direction.
Code at safe PRG: |
|
The following code controls boom down direction.
Code at safe PRG: |
|
The following code controls non-safe boom with alternative non-safe wrapper POU.
Code at non-safe PRG: |
|
SafeProportionalValveControl library
S_EndAttenuation (FB)
S_LinearRamp (FB)
S_CurrentRequest (FB)
S_AdaptiveController (FB)
SensorsAndActuators library
Source file topic100380.htm
Last updated 21-Feb-2025