Boolean Logic and Markers¶
Boolean Logic¶
A FUP network with contacts usually becomes one Boolean assignment.
xboDriveStartAllowed :=
xboOperatorStartRequest
AND xboDriveReady
AND NOT xboEmergencyStopActive
AND NOT xboTripActive;
Use parentheses when the expression mixes AND and OR.
xboAlarmActive :=
(xboHighTemperature OR xboLowOilPressure)
AND xboMachineRunning;
Prefer one clear assignment over many small marker steps when the expression is still readable.
Markers And Reset Logic¶
A marker is simply a Boolean memory. In SCL, the important question is always: when is it set, and when is it reset?
Set Without Reset¶
IF inCounter > 4 THEN
_xboCounterExceeded := TRUE;
END_IF;
This value latches forever after the first time inCounter > 4 becomes true. That may be correct
for an alarm latch, but it is wrong for a normal live condition unless another part of the code
resets it.
Set With Reset¶
IF inCounter > 4 THEN
_xboCounterExceeded := TRUE;
ELSE
_xboCounterExceeded := FALSE;
END_IF;
This follows the condition every cycle. When the counter drops back to 4 or lower, the marker is
reset.
Direct Assignment¶
_xboCounterExceeded := (inCounter > 4);
For simple live conditions, this is usually best. It has an obvious reset condition because the complete value is recalculated every cycle.
Latch With Named Reset¶
Use explicit latch logic when the memory is intentional.
IF xboResetAlarm THEN
_xboAlarmLatched := FALSE;
ELSIF xboAlarmCondition THEN
_xboAlarmLatched := TRUE;
END_IF;
This makes the priority visible. In this example, reset wins over set because it is checked first.
Marker overuse
Too many markers make code hard to reason about, especially when the reset condition is far away from the set condition. If the logic starts to describe steps or modes, use a state machine.
Edge Detection¶
FUP often has rising edge boxes. In SCL, store the previous value and compare it with the current value.
_xboStartRequestRise := xboStartRequest AND NOT _xboStartRequestLast;
_xboStartRequestLast := xboStartRequest;
The order matters. Calculate the edge first, then update the previous value for the next cycle.