Chapter 2 / 36

Write the behaviour contract

Specify priorities, operating limits and acceptance tests that remove guesswork.

Translate the brief without smuggling in assumptions

The first chapter gave us a conveyor request. Now imagine handing that request to two programmers. One stops when Start is released. The other finishes the transfer. Both may say they implemented “press Start to move a carton”. The missing piece is a decision that neither should have had to invent.

A useful contract closes that gap. It describes a history, the decision the controller must make, and what a person can observe afterward. It is small enough to discuss beside the machine. It is precise enough to become a test.

RequirementA tempting interpretationThe question that settles it
Run when readyRestart automatically when a fault clears.Does restored readiness grant permission, or request a new cycle?
Stop on arrivalLabel a stopped carton as successfully delivered.Did arrival occur during an accepted move?
Reset the faultClear the alarm and restart the conveyor.Does reset only clear the interruption? What separate action starts work?
Stop has priorityPut a Stop rung near the top.Can a later assignment turn the same output back on?

For our station, readiness is permission. A fresh Start is the request. Reset clears an eligible interruption; it does not request motion. The final output assignment enforces the agreed priority. These are four different jobs and deserve four different names.

Write one rule all the way to its test

Take the requirement: “Releasing Start must not abandon an accepted transfer.” Write its acceptance conditions, not just its happy outcome.

  1. Arrange IDLE, a carton at pickup, clear arrival, ready drive, and released Start and Stop.
  2. Present a fresh Start press and evaluate the controller. Expect MOVING and a belt request.
  3. Release Start before arrival. Evaluate again. Expect MOVING and the belt request still active.
  4. Present arrival. Expect DELIVERED and no belt request.
  5. Clear arrival without a new accepted cycle. Expect no belt request.

Step 3 catches missing memory. Step 5 catches unwanted restarting. The same requirement needs both. Writing only “press Start and check the belt” would miss them.

A five-step test record: arrange, act, observe, challenge and record, using a transfer with a simultaneous Stop and arrival condition
Turn prose into evidence. Change the challenge to suit the rule you are testing. Keep the starting state and exact input history; otherwise a later programmer cannot reproduce your result.

Decide what wins before two things happen together

Suppose a scan first observes both Stop and arrival. The PLC does not know which physical event happened a fraction of a millisecond earlier. The contract must say how to classify that captured situation. For this exercise, Stop takes priority, so the result is INTERRUPTED. If the process needs physical event ordering, a normal cyclic Boolean image may not contain enough information; the acquisition design has to change.

Write the sentence that decides the code

Keep the one-carton station from chapter one in front of you. Q_Belt is its only ordinary motion command. PE1 observes pickup, PE2 observes arrival, and the drive supplies readiness.

The request “Start the belt and stop at the far end” still leaves several different programs possible. One programmer might stop when Start is released. Another might hold the motor on until PE2 changes. A third might restart whenever the carton is removed. All three could claim they implemented the sentence.

A behaviour contract removes those choices from the programmer's guesswork. It is not a legal document and it does not need impressive wording. Write short, observable promises. Give each promise a name so its code and its test can point back to it.

Give each output four kinds of rule

Put Q_Belt at the top of the page. Under it, make four headings.

Acceptance: what allows a new move to begin? Our station accepts a fresh Start edge only in IDLE, with a carton at pickup, arrival not active, drive readiness present and Stop absent.

Continuation: what must remain true while the accepted job runs? DriveReady remains supervised. StartButton does not need to remain true, because the accepted job remembers the press.

Completion: what observation proves this job is finished? AtDrop, sampled from PE2, ends the move. Five seconds passing is not completion evidence.

Interruption: what ends work without claiming it succeeded? Stop, lost readiness and an expired arrival watchdog lead to INTERRUPTED.

This is a useful way to write a contract for any actuator. A valve, gripper and drive will have different answers, but you still need to distinguish the request, its ongoing permission, its normal result and its exceptional exit.

Decide whether a condition applies once or continuously

“AtPickup must be true” is incomplete. Must it be true to accept the move, or throughout the move?

For our station it is an acceptance condition. The carton necessarily leaves PE1 during travel. If AtPickup is placed in the final run equation, normal progress turns its own motor off.

DriveReady is different. It is both an acceptance condition and a continuous permission. Losing it during travel interrupts the move. We keep that fact available for diagnosis.

ConditionAt acceptanceDuring the moveWhy
New Start edgeRequiredNot requiredA request becomes remembered work
AtPickupRequiredNot requiredThe carton leaves this sensor normally
DriveReadyRequiredRequiredLosing drive availability interrupts the job
NOT AtDropRequiredEnds the move when falseA carton already at arrival is not a new transfer
NOT StopButtonRequiredRequiredStop blocks acceptance and interrupts motion

That table is already telling you where to write conditions. AtPickup belongs in the IDLE-to-MOVING guard. DriveReady belongs there and in continuous supervision. The Start edge belongs in acceptance. It does not belong in the final output equation.

Give conflicts one explicit winner

The PLC may sample several true inputs in the same evaluation. Write the winner before arranging the IF branches.

For this exercise, we choose the following priorities. They are decisions for this teaching station, not rules you can impose on every process.

Inputs or events observed togetherChosen result
Start and Stop in IDLERemain IDLE, Q_Belt off
Stop and arrival in MOVINGEnter INTERRUPTED, Q_Belt off
Lost readiness and arrival in MOVINGEnter INTERRUPTED
Arrival and watchdog expiry in MOVING, with no higher-priority interruptionEnter DELIVERED
Reset and Start in INTERRUPTEDDo not reset while Start is held
Acknowledge while a carton still blocks PE2Remain DELIVERED

Why does arrival win over the timer here? The contract defines completion from the sampled input image and uses the watchdog only when arrival is absent. It does not claim to know which physical event happened first between samples. If that physical ordering matters, this cyclic sample is not sufficient evidence. You may need timestamps, a faster task or different acquisition hardware.

Now translate the Moving rows in their priority order:

IF StopButton OR NOT DriveReady THEN
  NextState := 90;        (* INTERRUPTED *)
ELSIF AtDrop THEN
  NextState := 20;        (* DELIVERED *)
ELSIF TravelWatch.Q THEN
  NextState := 90;        (* missing arrival *)
END_IF;

This excerpt belongs inside the MOVING branch after the travel timer has been evaluated. An unchanged NextState means the move continues. The same contract requires NOT StopButton in the IDLE acceptance guard; a priority rule in the Moving branch alone cannot prevent wrong acceptance.

Write the complete transition table

The state diagram is easy to inspect. The transition table is where you make its arrows precise.

Current stateEvent and guardNext stateWhat it means
IDLEFresh Start, AtPickup, DriveReady, NOT AtDrop, NOT StopMOVINGAccept one carton move
MOVINGStop or lost readinessINTERRUPTEDPreserve an unfinished transaction
MOVINGAtDrop, with no higher-priority interruptionDELIVEREDRecord normal arrival
MOVINGTimeout, with no higher-priority eventINTERRUPTEDRecord missing arrival
DELIVEREDFresh acknowledgement, new carton at pickup, arrival clear, Stop absentIDLEFinish the old delivery record; do not move
INTERRUPTEDFresh reset, recovery conditions satisfiedIDLEClear eligible interruption; do not move

Every unlisted event leaves the state unchanged. That last sentence matters. A sensor clearing in DELIVERED does not start another cycle. A drive becoming ready in INTERRUPTED does not resume the old move. A Start press in MOVING does not create a second accepted transaction.

In a large project you will refine states and interfaces. The table may reveal that recovery needs an assessment state rather than one reset guard. That is useful design work. Do not keep an inadequate state table and compensate with invisible exception flags everywhere else.

Define recovery without disguising it as Start

Our workbench has a declared recovery procedure: release Start and Stop, restore readiness, return the carton to pickup, clear arrival and make a new Reset press. Only that eligible press returns INTERRUPTED to IDLE.

The return to IDLE is not a motor request. A later Start edge is still required. The program must evaluate the Start edge every scan, even while it cannot accept a start. This prevents a held button from becoming a false new event merely because a fault clears.

Physical recovery on real equipment is a separate decision. A partly processed carton may not be eligible for another cycle. It may need removal or a recorded disposition. AtPickup alone does not establish product suitability. Our teaching procedure is deliberately small enough to inspect; the real procedure must account for the actual process and the approved operating conditions.

Compare three operator actions:

  • Acknowledge: the operator has seen an event or a completed delivery.
  • Reset: eligible stored fault or interruption state may be cleared.
  • Start: request new work after the controller is ready to accept it.

The HMI can put these buttons near each other. Their meanings still need to remain separate.

Turn each promise into an input history

“Test Stop” is not enough. Stop from which state? With what other inputs? What should remain recorded after Stop is released?

Write a history with an initial condition, inputs over time and an expected state and output. You should be able to hand it to someone who did not write the code.

R1 — accepted work survives Start release
Initial: IDLE, carton at PE1, PE2 clear, drive ready, Stop clear
Scan A: Start becomes TRUE
Expected: MOVING, Q_Belt TRUE
Scan B: Start becomes FALSE, arrival still FALSE
Expected: MOVING, Q_Belt TRUE
R2 — Stop prevents acceptance
Initial: IDLE, otherwise eligible for a new cycle
Scan A: Start and Stop become TRUE together
Expected: IDLE, Q_Belt FALSE
Scan B: release Stop but keep Start held
Expected with fresh-edge acceptance: still IDLE

The second history is stronger than a single simultaneous-input check. It also probes what happens after the conflict disappears. If the Start edge is consumed while acceptance is blocked, keeping the button held cannot produce a later new edge.

The workbench's held-Start test spans a longer boundary: accept a move, deliver the carton, remove it, load the next carton, acknowledge the old delivery, and keep Start held throughout. The next carton must remain still. This input history distinguishes a level request from a fresh-event request.

Keep numbers in a parameter contract

Our travel watchdog is five seconds. Put it in a parameter list with its units, allowed range and rationale. The number should have one owner.

A commissioning change from five to six seconds changes the expected machine behaviour. It should update the parameter, the test limit and the relevant documentation. It should not require searching for six different literals in output logic.

For timing tests, include the task interval and the observation tolerance. A cyclic timer and input image do not promise arbitrarily exact physical time. The browser workbench advances in declared 100 ms model steps; controller timing must be checked on the actual target.

A coding standard cannot write this contract for you

IEC 61131-3 gives programming-language structure and semantics. A project convention can define naming, output ownership, function-block interfaces and code organization. PLCopen's software construction guidance is useful when agreeing such conventions.

Neither tells you whether this particular carton should be resumed, discarded or inspected after interruption. That answer comes from the machine and process requirements. The professional habit is to connect each code decision to its owner and its evidence, then use a consistent language structure to express it.

For our example, a small project standard is enough to start: one writer for each physical output; meaningful units in parameter names; events evaluated every scan; one state decision per evaluation; and separate acknowledgement, reset and Start. You can now explain why each convention matters.

Try it

The customer changes the requirement: “If the operator presses Stop, wait where you are. When Start is pressed again, continue from that position.”

Do not immediately replace INTERRUPTED with IDLE. Write what this change demands from the state model, which sensor observations might be available between PE1 and PE2, what a new Start may accept, and what must happen if the drive loses readiness instead of receiving an operator Stop.

Write a test that distinguishes “continue the accepted move” from “accept another carton”.

Work through the answer

The controller needs to preserve the accepted transaction and distinguish an agreed operator pause from a fault requiring recovery. A PAUSED state can record that difference. Its outputs remain off.

A resume guard cannot require AtPickup if the valid carton has already left PE1. It needs the agreed resume evidence: transaction still valid, drive ready, Stop absent and a new resume request. The physical stopping and permitted restart conditions must be established for the actual equipment. A timeout or unknown carton condition may still require INTERRUPTED rather than PAUSED.

The distinguishing test starts with a carton between sensors. Press Stop, release it, then make a new Start press. The expected continuation refers to the same accepted carton. No second reservation or second production count should be created. That is a change to the transaction contract, not just a different motor rung.

Next, make sure the hardware can supply the evidence your rules require in the signal map.

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

Start and Stop arrive together. Which sentence settles it?

The same carton station receives a Start edge in the scan that Stop becomes true. Two programmers must produce the same result.

IDLE / no motionMOVING / one cycleINTERRUPTED / recoverevent → state → output

Your first artifact

Write the priority before writing the branch: ‘Stop prevents acceptance and interrupts an active move.’ Then make one test with both inputs true.

Open the worked decision
IF StopButton OR NOT DriveReady THEN
  NextState := 90;
ELSIF AtDrop THEN
  NextState := 20;
END_IF;

Why this line belongs here

The first true branch wins. This is why the Stop condition belongs above completion. The Idle acceptance condition also needs NOT StopButton; fixing only the Moving branch still allows a momentary wrong request.

Change the task

Arrival and timeout appear together. Write the chosen outcome and explain what your sampling interval cannot tell you about their physical order.