
The new question is not how to spell a motor command. It is what a capacity signal means after the transfer has begun. If downstream permission can disappear halfway across the gap, somebody must own the reservation and the recovery decision. Mark that question on the machine drawing before touching the state chart.
Start with a decision ledger
| Decision to settle | Why the program needs it | Evidence to keep |
|---|---|---|
| Who reserves the destination? | General capacity can change after acceptance. | Owner and lifetime of the reservation. |
| What proves successful transfer? | A run command only proves intent. | Destination observation during an active transfer. |
| What ends an unfinished transfer? | An endless run conceals missing progress. | Stop, lost permission and travel timeout cases. |
| Who owns a tray after interruption? | Resetting software cannot teleport it. | A physical reconciliation and recovery procedure. |
Compare this ledger with the first chapter. The method still starts with work, evidence and ownership. The answers have become more demanding because another system is involved.
Start with the tray, not the motor
The assignment sounds small: move a tray along a conveyor. Starting with MotorRun := StartButton is tempting. Instead, describe the work being transferred. One identified tray begins at the source, an empty destination agrees to receive it, and the operation either produces confirmed arrival or an explained interruption.
Our training model has one belt, a source sensor, a destination sensor, and a downstream capacity signal. It represents ordinary production control only. The real machine's safety functions, stopping behavior, and operating procedures require their own engineering and validation.
We will design a complete sequence contract, then implement its core in Structured Text. Physical I/O declarations and target-specific diagnostics are intentionally outside the listing. The listing is a model-control example, not a ready-to-download machine project.
The brief becomes seven decisions
Write these decisions before choosing state numbers:
- Accept a fresh start only when a tray is present at the source, the destination is empty, downstream capacity is granted, and production permission is available.
- Acceptance reserves the destination for this transfer. A later withdrawal of general capacity does not cancel the reservation.
- Run until destination presence is confirmed by the model sensor.
- Allow four seconds for arrival; confirmed arrival wins if both arrival and timeout are sampled together.
- Stop or lost production permission interrupts the transfer and requires recovery.
- Completion remains visible until acknowledged; acknowledgement does not move another tray.
- Fault reset requires a declared recovered condition. A fresh start is still required afterward.
In a larger line, reservation needs a transaction handshake. Here the downstream simulator owns that reservation after acceptance. Do not reuse this simplified agreement with an unrelated device without defining its interface.
Signals and responsibilities
| Signal | Meaning | Owner |
|---|---|---|
| SourcePresent | Source sensor detects the waiting tray | Plant model |
| DestinationPresent | Destination sensor detects arrival | Plant model |
| DestinationAvailable | Downstream can reserve capacity | Downstream model |
| ProductionPermission | Ordinary run conditions are satisfied | Supervisory model |
| StartPulse | One evaluation for a fresh start request | Command processing |
| RecoveryConfirmed | Defined model recovery was completed | Recovery workflow |
| MotorRun | Final ordinary belt request | Output arbitration |
Command processing evaluates its edge detector every control evaluation, including faulted operation. Otherwise holding Start through reset might appear to be a fresh edge later. The physical Start input and StartPulse are deliberately different concepts.
Draw the sequence and its exits
Use four states: Idle, Moving, Delivered, and Interrupted. Idle owns no tray transaction. Moving owns an accepted transfer. Delivered preserves completion evidence. Interrupted records work whose physical outcome requires a recovery decision.
The model does not “resume Moving” after interruption. A tray may coast, be manually removed, or already occupy the destination. Recovery must reconcile physical presence and product ownership. The model's recovery control establishes an empty conveyor and explicitly dispositions any interrupted tray before allowing Idle.
The state table is already enough to sketch tests:
| State | Ordinary motor request | Normal exit | Exceptional exit |
|---|---|---|---|
| Idle | Off | Valid fresh start → Moving | None accepted |
| Moving | On | Arrival → Delivered | Stop, permission loss, timeout → Interrupted |
| Delivered | Off | Completion acknowledgement → Idle | Physical conditions still gate future acceptance |
| Interrupted | Off | Authorized model recovery and reset → Idle | Remain interrupted |
Translate decisions in a visible order
The code uses integer states for broad readability: 0 Idle, 10 Moving, 20 Delivered, 90 Interrupted. In a target project, an enumeration is often clearer. TransferTimer is a TON instance called every evaluation; command pulses and model inputs are supplied by their documented owners.
TransferTimer(IN := State = 10, PT := T#4s);
CASE State OF
0:
IF StartPulse AND SourcePresent
AND NOT DestinationPresent
AND DestinationAvailable
AND ProductionPermission AND NOT StopRequest THEN
FaultCode := 0;
State := 10;
END_IF;
10:
IF StopRequest OR NOT ProductionPermission THEN
FaultCode := 1; (* transfer interrupted *)
State := 90;
ELSIF DestinationPresent THEN
State := 20;
ELSIF TransferTimer.Q THEN
FaultCode := 2; (* arrival missing *)
State := 90;
END_IF;
20:
IF CompletionAckPulse THEN
State := 0;
END_IF;
90:
IF ResetPulse AND RecoveryConfirmed
AND ProductionPermission AND NOT StopRequest THEN
FaultCode := 0;
State := 0;
END_IF;
ELSE
FaultCode := 3; (* invalid sequence state *)
State := 90;
END_CASE;
MotorRun := (State = 10)
AND ProductionPermission AND NOT StopRequest;
TransferComplete := State = 20;
TransferInterrupted := State = 90;
The timer sees Moving on the evaluation after the state first enters Moving. Consequently, this example's timing origin is the first active supervision evaluation, not an externally measured instant of motor motion. Include that task-scale offset in the model specification. A project requiring a deadline from the acceptance timestamp should store that timestamp and supervise elapsed time against it.
Output assignment follows the state decision, so arrival or interruption removes the request in that same program evaluation. Only this arbitration section writes MotorRun. Other code requests behavior through the documented interface.
Add explanations without changing ownership
The HMI should show why Idle rejected a start: source empty, destination occupied, no downstream capacity, or missing permission. Compute these reasons from the acceptance conditions. Do not set a timeout alarm when no transfer was accepted.
Record acceptance, arrival, interruption, and reset events with a transfer counter. A timer alarm says what was not observed; it does not prove a jam. The model can distinguish a physically stuck tray from a stuck-false destination sensor. The PLC sees the same missing arrival unless additional instrumentation distinguishes them.
Prove the contract with hostile conditions
Normal testing begins with one tray, an empty destination, and available capacity. Confirm exactly one acceptance and one completion. Then start with the destination occupied: no motion should be requested.
Withdraw DestinationAvailable after acceptance. The reserved transfer should continue. Remove ProductionPermission instead: it must interrupt. These two tests establish that capacity and run permission have different meanings.
Keep arrival false until timeout, then make it true. The sequence must remain interrupted. Hold Start throughout reset and recovery; there must be no new transfer. Enter an invalid state value in the model harness and verify Interrupted with the diagnostic reason. Finally, repeat normal operation after all interventions are removed.
Try it
The customer now wants Stop to pause the transfer and Start to continue it. Change the requirements before changing the code. List at least four questions that determine whether this can be implemented with the existing signals.
Work through the answer
Ask whether a stopped tray remains in a known position, whether downstream reservation remains valid, whether the process permits continuation, and how motion after interruption is authorized. Also ask what happens if the destination becomes occupied, a tray is removed, or power is lost during the pause.
A Pause state is justified only after those questions have answers. It needs defined entry behavior, retained transaction ownership, supervision policy, and continuation conditions. Replacing State := 90 with State := 0 would discard ownership and might accept a second tray into an occupied transfer path.
The important deliverable is the revised contract and its tests. The code change follows from that work. Continue with the batch tank, where the process can continue changing even after an output request becomes false.