68 lines
2.3 KiB
Markdown
68 lines
2.3 KiB
Markdown
|
|
FUNCTION_BLOCK "FB_Cylinder_Adv"
|
||
|
|
{ S7_Optimized_Access := 'TRUE' }
|
||
|
|
VERSION : 0.2
|
||
|
|
VAR_INPUT
|
||
|
|
i_xCmdFwd : Bool; // Output Command Forward
|
||
|
|
i_xCmdBcw : Bool; // Output Command Backward
|
||
|
|
i_xFwdSensor : Bool; // DI: Physical Forward
|
||
|
|
i_xBcwSensor : Bool; // DI: Physical Backward
|
||
|
|
i_xSimMode : Bool; // TRUE = Ignore sensors, use internal simulation
|
||
|
|
i_iSensorConfig : Int; // 0:None, 1:Fwd Only, 2:Bcw Only, 3:Both
|
||
|
|
i_tMoveTime : Time := T#1s; // Expected travel time
|
||
|
|
i_tTimeout : Time := T#2s; // Alarm threshold
|
||
|
|
i_xReset : Bool;
|
||
|
|
END_VAR
|
||
|
|
|
||
|
|
VAR_OUTPUT
|
||
|
|
q_xFwdOut : Bool;
|
||
|
|
q_xBcwOut : Bool;
|
||
|
|
q_xAtFwd : Bool;
|
||
|
|
q_xAtBcw : Bool;
|
||
|
|
q_xError : Bool; // Timeout Alarm
|
||
|
|
END_VAR
|
||
|
|
|
||
|
|
VAR
|
||
|
|
s_tonFwd {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||
|
|
s_tonBcw {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||
|
|
s_tonWatchdog {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||
|
|
END_VAR
|
||
|
|
|
||
|
|
BEGIN
|
||
|
|
// 1. Directional Interlock
|
||
|
|
q_xFwdOut := i_xCmdFwd AND NOT i_xCmdBcw;
|
||
|
|
q_xBcwOut := i_xCmdBcw AND NOT i_xCmdFwd;
|
||
|
|
|
||
|
|
// 2. Simulation vs. Real Logic
|
||
|
|
s_tonFwd(IN := q_xFwdOut, PT := i_tMoveTime);
|
||
|
|
s_tonBcw(IN := q_xBcwOut, PT := i_tMoveTime);
|
||
|
|
|
||
|
|
IF i_xSimMode THEN
|
||
|
|
// In simulation, we only care about the internal timers
|
||
|
|
q_xAtFwd := s_tonFwd.Q;
|
||
|
|
q_xAtBcw := s_tonBcw.Q;
|
||
|
|
ELSE
|
||
|
|
// Real World Logic based on Config
|
||
|
|
CASE i_iSensorConfig OF
|
||
|
|
0: // No Sensors
|
||
|
|
q_xAtFwd := s_tonFwd.Q;
|
||
|
|
q_xAtBcw := s_tonBcw.Q;
|
||
|
|
1: // Fwd Only
|
||
|
|
q_xAtFwd := i_xFwdSensor;
|
||
|
|
q_xAtBcw := s_tonBcw.Q;
|
||
|
|
2: // Bcw Only
|
||
|
|
q_xAtFwd := s_tonFwd.Q;
|
||
|
|
q_xAtBcw := i_xBcwSensor;
|
||
|
|
3: // Both Sensors
|
||
|
|
q_xAtFwd := i_xFwdSensor;
|
||
|
|
q_xAtBcw := i_xBcwSensor;
|
||
|
|
END_CASE;
|
||
|
|
END_IF;
|
||
|
|
|
||
|
|
// 3. Watchdog Alarm (Trip if moving but not arriving)
|
||
|
|
s_tonWatchdog(IN := (q_xFwdOut AND NOT q_xAtFwd) OR (q_xBcwOut AND NOT q_xAtBcw),
|
||
|
|
PT := i_tTimeout);
|
||
|
|
|
||
|
|
IF s_tonWatchdog.Q THEN q_xError := TRUE; END_IF;
|
||
|
|
IF i_xReset THEN q_xError := FALSE; END_IF;
|
||
|
|
|
||
|
|
END_FUNCTION_BLOCK
|