Chapter 5 / 36

Think in conditions

Build clear Boolean decisions and check them with truth tables.

A condition answers one precise question

Before writing a complicated expression, say the question it should answer. “May this carton be released?” is useful. “Is everything okay?” is usually too vague. The first question gives you a decision boundary; the second invites every unrelated status bit into one unreadable expression.

For the teaching cell, release requires a completed fill, an available downstream path, and a filling head confirmed clear. Any one missing condition prevents release. That gives us AND.

ReleasePermitted := FillComplete
                    AND DownstreamReady
                    AND HeadClear;

This expression has no memory. If DownstreamReady changes, the result changes when evaluated again. It does not remember that downstream was ready earlier, or that a release had already begun. Those are separate requirements that may need stored state.

Read AND and OR as sets of allowed situations

AND requires all its operands to be true. OR requires at least one to be true. Ordinary Boolean OR includes the case where both are true; it does not mean “one or the other, but never both.”

Suppose a teaching station may receive a start request from a local button or a supervisory interface. LocalStart OR RemoteStart is true when either source requests and also when both request. Whether both sources should be accepted depends on mode and command ownership, not on the definition of OR.

LocalStartRemoteStartOR resultAND result
FalseFalseFalseFalse
FalseTrueTrueFalse
TrueFalseTrueFalse
TrueTrueTrueTrue

Four rows are cheap to inspect. Use them before guessing. Three Boolean inputs produce eight combinations; four produce sixteen. For larger decisions, split the expression into named concepts and inspect those concepts independently.

Parentheses preserve the sentence you meant

Consider a requirement: local or remote start is allowed, but only with the station ready. Write the grouping explicitly:

StartAllowed := (LocalStart OR RemoteStart) AND StationReady;

Without the intended grouping, a reader may understand the code differently, and operator precedence may produce an unintended expression. Parentheses are inexpensive documentation even when precedence already gives the desired result.

Now add local and remote modes. The requirement becomes: accept the local request in Local mode, or the remote request in Remote mode; either route still requires readiness.

SelectedStart := (LocalMode AND LocalStart)
                 OR (RemoteMode AND RemoteStart);
StartAllowed := SelectedStart AND StationReady;

This makes a further requirement visible: should LocalMode and RemoteMode ever both be true? An enumerated mode can avoid an impossible combination. If separate bits come from external equipment, explicitly diagnose contradictory selection rather than letting both command paths operate accidentally.

Invert meaning carefully

NOT (A AND B) is true whenever at least one required condition is absent. NOT A AND NOT B is true only when both are absent. They are different questions.

For our release conditions, the reasons to block release can be written as:

ReleaseBlocked := NOT FillComplete
                  OR NOT DownstreamReady
                  OR NOT HeadClear;

That is the inverse of the earlier ReleasePermitted. Keeping the individual reasons also lets the interface say what is missing. Do not show only a red “blocked” lamp when the program already knows which conditions are false.

Be careful with names such as NotStopped, NoFaultNotActive, or DisableInhibit. Negation stacked into both the name and the expression makes review slower. Prefer a positive, defined meaning such as PressureAdequate or a clear abnormal condition such as PressureFault.

Boundaries are part of the logic

For a mass target of 2.0 kg, MassKg > 2.0 does not become true at exactly 2.0. MassKg >= 2.0 does. That difference can matter even if the real measurement is noisy. Test below, at, and above each boundary.

Range checking needs the same discipline. If a valid teaching parameter is 1 through 20 inclusive, the invalid condition is “less than 1 OR greater than 20.” Using AND there would require a number to be below 1 and above 20 simultaneously.

ParameterInvalid := (BatchTarget < 1) OR (BatchTarget > 20);

A noisy physical value also needs a policy for repeated threshold crossing. Hysteresis uses different thresholds for turning a request on and off. Filtering changes the signal used by the decision. A delay requires persistence over time. These solve different problems; do not add all three without understanding the delay they introduce.

Separate a permissive from an instruction to act

A release may be permitted while no release has been requested. If ConveyorCmd := ReleasePermitted, the conveyor could run simply because the cell happens to be ready. The command also needs the sequence's intent.

ConveyorCmd := ReleaseRequested AND ReleasePermitted;

For this teaching model, ReleaseRequested comes from the active sequence state. The condition says that requested action is currently allowed. Keeping both names prevents readiness from turning into motion by accident.

The same distinction applies to a reset: “fault can be reset” is not the same as “operator has requested reset.” A good Boolean name tells you whether it represents capability, demand, observation, or result.

The misconception: shorter code is clearer code

An expression can be mathematically correct and still be hard to maintain. Saving three lines by folding mode selection, pressure checks, state checks, and fault checks into one formula creates a difficult diagnostic surface.

Break it at meaningful boundaries, not arbitrary lengths. ModeRequest, ProcessPermissive, and MotionRequest each describe a question somebody may need to answer during a fault. Fifty temporary variables named Condition1 through Condition50 provide no such help.

When reviewing an expression, say a counterexample aloud: “If the head is not clear but everything else is true, can this output turn on?” Then calculate that case. Counterexamples catch errors that a casual reading misses.

Try it

A mixer may run in Auto when an automatic mixing step requests it, or in Manual while a jog button is held. In either case, the lid-closed status and drive-ready status are required operational permissives. Write the expression. Then identify a case that exposes this incorrect version:

MixerCmd := AutoMixRequest
            OR ManualJog AND LidClosed AND DriveReady;

The lid status in this exercise is an ordinary observation. Do not treat this example as a protective safety implementation.

Work through the answer

One clear version first selects the request and then applies the shared conditions:

MixerRequest := (AutoMode AND AutoMixRequest)
                OR (ManualMode AND ManualJog);
MixerPermitted := LidClosed AND DriveReady;
MixerCmd := MixerRequest AND MixerPermitted;

The incorrect expression allows AutoMixRequest to make the result true independently of the lid and drive conditions. Set AutoMixRequest true and LidClosed false to expose it immediately. It also omits explicit mode ownership.

You can now evaluate a decision from present conditions. Remembering with intent adds the missing ingredient when a momentary request must have a lasting effect.

Now make the decision yourself

Use the chapter’s model on a fresh question, then compare your reasoning with the worked decision.

How this becomes a program

Which conditions are AND, and which belong on a branch?

A transfer can be requested by an operator or by the upstream station. In either case the drive must be ready and Stop must be absent.

Operator OR UpstreamDriveReadyQ_Requestrequests → permissives → one output owner

Your first artifact

Bracket the two alternative request sources. Then write the conditions common to both outside that bracket. Check the case where only Upstream is true and DriveReady is false.

Open the worked decision
Request := (OperatorRequest OR UpstreamRequest)
           AND DriveReady AND NOT StopButton;

Why this line belongs here

Without the parentheses, operator precedence can let one source bypass a common permissive. The truth table is the design artifact; the expression and Ladder branches are translations of it.

Change the task

Add a manual-jog source that is allowed only in Manual mode. It must still obey readiness and Stop. Show exactly which branch receives the mode condition.