PLC Programming SAPLC ProgrammingSOUTH AFRICA
Menu

exercises · South Africa

Car Wash PLC Program Example: Stages, Abort and Restart

Build a car wash PLC program example with four timed stages, completion and abort states, plus restart tests and South African PLC training questions.

Conceptual car wash PLC program example study desk with a miniature wash model, controller and laptop
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

This car wash PLC program example is a virtual sequence with four timed activity states—Soap, Brush, Rinse and Dry—followed by a separate Done state. The main learning task is handling interruption correctly: an abort must prevent further stage progression, even if a timer threshold is reached on the same evaluation.

You will define a fresh-start policy, trace the complete cycle, and test loss of a supplied position or permission value in every active stage. The model uses fictional intervals of 20, 30, 20 and 40 seconds. Those settings teach sequencing; they do not establish an effective washing process or suitable timings for actual equipment.

All outputs are programme indicators. This page supplies no valve wiring, motor circuit, chemical process, gantry control or physical emergency-stop implementation. A command becoming false does not prove that water flow, a brush or a fan has physically stopped. Keep that distinction visible in your test records.

Define the inputs and the cycle contract

Use VehiclePresent true to mean the supplied position value permits the exercise to run. It does not identify a particular sensor technology or prove that a vehicle is correctly located in every physical dimension. Permission is a separate supplied Boolean. Enabled and StopRequest allow the lesson to exercise interruption without pretending to model a complete safety system.

StartButton and ResetButton are virtual requests. A Start event is a raw false-to-true transition. Reset is a separate event that releases the latched Aborted state when the global eligibility conditions are restored. Reset never starts Soap by itself.

StateVirtual active outputDuration or exit
IdleNoneAccept an armed fresh Start with VehiclePresent
SoapSoapCommand20000 ms from entry
BrushBrushCommand30000 ms from entry
RinseRinseCommand20000 ms from entry
DryDryCommand40000 ms from entry
DoneDoneIndicatorWait for VehiclePresent to become false
AbortedNoneWait for an accepted Reset edge

Done is an untimed completion state, not a fifth timed washing activity. It means the virtual programme reached the end of Dry under this contract. It does not prove cleanliness, dryness, successful actuator operation or permission for a driver to move.

Each activity owns a new StageStartedAt timestamp. Use nondecreasing whole-number milliseconds for the worked examples. State and timestamp must remain a consistent pair; changing State manually without assigning its appropriate origin is not a normal programme transition.

The PLC programming examples collection provides related sequences. If basic state memory is unfamiliar, begin with ladder logic basics before implementing the full cycle.

Require release before accepting Start

Initialise State to Idle, StartArmed false and StageStartedAt empty. Initialise PreviousStart and PreviousReset from the current supplied button values. A button already held when the exercise begins is therefore not presented as a new press.

In an eligible Idle evaluation with VehiclePresent true and StartButton false, set StartArmed true. A later Start edge can enter Soap only if StartArmed was already true. Accepting Start clears StartArmed and records the current timestamp as the Soap origin.

If VehiclePresent is false while Idle, clear StartArmed. A button held while the supplied vehicle value changes from false to true cannot start the cycle. The programme must first observe Start released while the start conditions are available, then observe a new edge.

Update PreviousStart and PreviousReset on every evaluation, including during activities, Done and Aborted. Mid-cycle Start presses are ignored as requests, but their raw history is still observed. Do not save them in a hidden queue for the next cycle.

The CODESYS R_TRIG documentation describes rising-edge detection. This lesson separately specifies initial history, arming and acceptance conditions; those are application decisions rather than automatic consequences of using an edge instruction.

Conceptual sensor, controller and conveyor illustration for distinguishing signals from program values
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

Give interruption priority over timing

Define global eligibility as Enabled true, Permission true and StopRequest false. If any of those conditions fails, select Aborted, clear StartArmed and the stage timestamp, and make every output false. This rule applies even while Idle or Done; restoration alone does not release Aborted.

During Soap, Brush, Rinse or Dry, VehiclePresent false also selects Aborted and clears the same memory. Check that condition before testing whether the current stage has reached its duration. If position is lost exactly at the end of Brush, the result is Aborted, not Rinse.

Preserve the distinction between active-cycle interruption and normal departure after completion. In Done, VehiclePresent false selects Idle with StartArmed false. In Idle, absence simply prevents arming. Neither case is treated as an active washing interruption, provided global eligibility remains true.

An unexpected State value selects Aborted and records InvalidState as the reason. For other aborts, use a reason tied to the observation, such as EligibilityLost or PositionLost. Avoid claiming that a particular sensor, motor or cable caused the event solely from these Boolean values.

Aborted remains latched while the global conditions are restored. A fresh Reset edge then selects Idle, clears the reason and leaves StartArmed false. Reset may be accepted with VehiclePresent false, but that does not bypass the later presence and release requirements for Start.

The conveyor restart lesson explores related restart decisions. Compare its contract with this explicit abort-reset cycle rather than assuming every exercise should recover the same way.

Avoid stale active-stage information after an abort

A common sequencing error is calculating ActiveStage from the old state, changing the state to Idle or Aborted, and then still using that old ActiveStage value to call a timer or advance a step number. The variable may have been correct when calculated and still be wrong for the later decision.

For example, suppose a Brush interval reaches its threshold on the same evaluation that VehiclePresent becomes false. An abort branch writes Idle, but a later timer branch still believes an active stage is running. If it increments the step, it can overwrite the abort result with another active state.

The solution in this model is a single priority decision using the old state. An accepted abort excludes every ordinary transition for that evaluation. Only the ordinary active-stage branch may compare elapsed time and select the next stage. Do not run a second, independent “timer done: advance” block afterwards.

This also avoids a different ambiguity: setting Idle during an interruption and immediately evaluating its Start logic in the same pass. One transition per evaluation means reset, departure and abort cannot silently become a new wash on that same evaluation.

After the final state is selected, decode the outputs once. Compute any displayed ActiveStage status from that resulting state. A single state variable is helpful only when its writes and the decisions around it follow the defined priority.

A structured-text-style implementation outline

The following is language-neutral pseudocode. State names, the empty timestamp and the supplied time are model elements, not a declaration of a particular controller’s supported syntax or clock API. Translate them deliberately into your chosen environment.

StartEdge := StartButton AND NOT PreviousStart;
ResetEdge := ResetButton AND NOT PreviousReset;
OldState := State;
Eligible := Enabled AND Permission AND NOT StopRequest;

IF NOT Eligible THEN
    AbortWithReason(EligibilityLost);
ELSIF OldState NOT IN {Idle, Soap, Brush, Rinse, Dry, Done, Aborted} THEN
    AbortWithReason(InvalidState);
ELSIF OldState IN {Soap, Brush, Rinse, Dry} AND NOT VehiclePresent THEN
    AbortWithReason(PositionLost);
ELSIF OldState = Aborted THEN
    IF ResetEdge THEN EnterIdleUnarmed(); END_IF;
ELSIF OldState = Idle THEN
    IF NOT VehiclePresent THEN
        StartArmed := FALSE;
    ELSIF NOT StartButton THEN
        StartArmed := TRUE;
    ELSIF StartArmed AND StartEdge THEN
        EnterStage(Soap, CurrentTimeMs);
    END_IF;
ELSIF OldState = Done THEN
    IF NOT VehiclePresent THEN EnterIdleUnarmed(); END_IF;
ELSE
    IF CurrentTimeMs - StageStartedAt >= DurationOf(OldState) THEN
        EnterNextStageOrDone(OldState, CurrentTimeMs);
    END_IF;
END_IF;

PreviousStart := StartButton;
PreviousReset := ResetButton;

AbortWithReason selects Aborted and clears arming and the timestamp. EnterIdleUnarmed selects Idle, clears the reason and timestamp and leaves arming false. EnterStage selects the requested activity, clears arming and records its entry time. EnterNextStageOrDone follows Soap → Brush → Rinse → Dry → Done; entry into Done clears the timestamp.

Each of the four activity commands is true only when Eligible, VehiclePresent and the final State equals that activity. DoneIndicator requires Eligible, VehiclePresent and State Done. All five outputs are false in Idle and Aborted.

Illustrated learning desk with a notebook and laptop for planning Boolean logic test cases
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

Trace a complete cycle and departure

Start with the supplied vehicle present and global eligibility true. ResetButton remains false. The trace includes observations immediately before the duration thresholds and shows a held Start after completion.

Time msStartPresentState after evaluationMeaning
001IdleArm Start
1011SoapStart accepted
2001SoapRelease does not cancel the activity
2000901SoapSoap interval incomplete
2001001BrushNew stage origin 20010
5000901BrushBrush interval incomplete
5001001RinseNew stage origin 50010
7000901RinseRinse interval incomplete
7001001DryNew stage origin 70010
11000901DryDry interval incomplete
11001001DoneComplete; activity commands false
12000011DoneIgnore Start while complete
12100010IdleDeparture clears Done
12200011IdleHeld Start cannot restart
12300001IdleObserve release and arm
12400011SoapAccept a new cycle

The first cycle begins at 10 and reaches Done at 110010, a supplied elapsed interval of 110000 ms. That is 110 seconds because this trace includes evaluations at each exact stage threshold. Done persists until departure or a global interruption under the stated rules.

The programme does not count the departure as an abort. Nor does the Start held during departure become a fresh request when VehiclePresent returns. Those are separate behaviours and both deserve explicit rows in your test record.

Distinguish nominal duration from observed duration

The four configured intervals total 110 seconds. A different evaluation schedule can observe later transitions. For example, accept Start at 10, enter Brush at 20200, Rinse at 50500, Dry at 70800 and Done at 111000. Those observations give a cycle of 110990 ms from accepted Start to Done.

Each stage’s origin is its actual entry evaluation in this model. Rinse does not inherit time accumulated in Brush, and Dry does not use the original cycle-start timestamp. A long gap between evaluations advances only one stage, then starts that stage’s own interval.

A native timer-based implementation may have additional behaviour to consider. Schneider Electric’s TON documentation describes input, elapsed time and output conditions. The exact library and invocation pattern matter when resetting a shared timer between stages.

If a self-resetting timer is called with its previous done value in the input condition, the reset and subsequent start occur through separate evaluations. Do not simply add presets and promise an identical observed cycle without checking the resulting trace.

Use the traffic-light timing lesson for a related comparison of nominal intervals and late observations. Keep browser rendering time, supplied model time and physical response time distinct when reporting results.

Two illustrated learners reviewing a controller example beside a guarded training conveyor
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

Test every active-stage abort at its threshold

For each of Soap, Brush, Rinse and Dry, test VehiclePresent false just before, exactly at and just after its configured duration. The result must be Aborted with all outputs false. The elapsed-time comparison must never override that result.

Repeat the tests with Permission false, StopRequest true and Enabled false. These global conditions have the same high-priority interruption result. A combined input failure does not require several independent output-reset rungs in this model, but you still need to test the combined case.

Restore every condition while keeping Start held. The sequence remains Aborted. Supply a fresh Reset edge: it becomes Idle but remains unarmed. Keep Start held for another evaluation to confirm no restart, then release it while the vehicle is present and press again. Only that new edge enters Soap.

Test Reset while the global conditions are still unavailable. It must not clear Aborted. Since raw reset history is updated, holding Reset while permission returns is not a new reset edge. Release and press Reset again after eligibility is restored.

Finally test position loss in Done and Idle. Done should become Idle without entering an active stage. Idle should remain Idle and clear arming. This prevents a broad “not present: abort” rule from accidentally changing the specified completion and waiting behaviour.

Keep completion evidence separate from an output request

DoneIndicator means the state sequence reached Done. Without independent feedback, it does not show that soap flowed, brushes turned, rinse coverage was adequate or a fan delivered a particular drying result. A stopped animation is likewise not evidence that a physical mechanism has stopped.

If you add a completed-cycle counter, increment it on the transition into Done, not on every evaluation while Done remains true. Specify what happens when an abort occurs at the Dry threshold: under this model it must not count as completion.

Keep aborted attempts in a separate record if you want to study reliability of the exercise. Count the event once, and decide whether multiple unavailable inputs belong to one interruption or several categories. Do not infer an equipment failure rate or commercial throughput from supplied test cases.

The bottle-counting exercise helps with edge-based counting. The fault-finding workflow guide can help phrase an observation before proposing causes.

Illustrated learner comparing program observations with a guarded conveyor training model
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

Extend the model with a revised contract

A quick-wash option could omit Brush, but record the selected route when a cycle starts. Otherwise an option changed halfway through can alter the current process unexpectedly. Define the next-state mapping for each route and test abort priority on every permitted transition.

A pause option is different from abort. Pausing might retain the current stage and remaining time, while abort in this lesson discards both. Specify whether commands become false during pause, which event resumes it and whether lost position is still an abort. Do not silently change the existing abort into an automatic resume.

For example, a virtual Rinse paused after 7000 ms of its 20000 ms interval has 13000 ms remaining under a retained-elapsed-time policy. If the programme instead resets the stage timer on resume, it requests a full additional 20000 ms. Those are different behaviours, not alternative descriptions of the same test result.

A token or payment extension introduces transaction ownership as well as sequencing. Define when a token is accepted, consumed, retained or returned in the model. A Boolean wash-start example does not implement payment security, refunds or a commercial billing system.

South African course and portfolio questions

When comparing PLC courses in Midrand, Johannesburg, Pretoria, Durban, Cape Town or online, ask whether the exercise includes learner-controlled input changes and visible internal state. A polished wash animation does not establish that you can inspect an abort at a timer threshold.

Ask the provider to demonstrate a held Start during permission restoration, and to explain whether Done represents timed programme completion or measured process feedback. Also ask which native timers or simulated clock are used. The answers should describe the actual course environment rather than a generic promise about all PLCs.

Use the online PLC training guide for delivery questions and the engineering-student guide for portfolio planning. Keep the state table, one complete trace and one corrected failure case. Describe the result as a virtual timed-sequence exercise, not a commissioned wash system or a registered qualification.

Common questions about a car-wash PLC sequence

Is this a five-stage or four-stage programme?

It has four timed activity states followed by an untimed Done state. Idle and Aborted handle waiting and interruption. Calling Done a timed washing stage would misdescribe this contract.

Why is a reset not enough to restart?

Reset releases the latched abort and returns to Idle. The separate arming rule then requires Start to be observed released while the start conditions are available, followed by a fresh edge. This prevents a held request from being reused unintentionally.

Can I resume at Rinse after a position interruption?

This version aborts and restarts from Soap after the reset and fresh-start procedure. Resuming from a saved stage requires a different recovery specification and evidence that the process state remains suitable. It is not implied by retaining a step number.

Does a 110-second cycle establish production capacity?

No. The number is the sum of fictional activity intervals. It excludes loading, departure, interruptions and physical process validation. Even the virtual observed duration depends on the evaluation schedule used for the trace.

Conceptual PLC learning portfolio with a process sketch, test notes and a laptop showing logic
Conceptual learning illustration; not a validated circuit, program screenshot or physical test result.

Continue with timing and scan-order practice

Inspect the PLC timer learning page in PLC Simulation Software for a related timing entry point. Use its scan-cycle highlighting feature when studying the relationship between conditions, state changes and output assignments.

These links do not claim that this exact car-wash model is a supplied or graded project on a particular plan. Compare the product’s current scope with the exercise you want to implement. The strongest learning result is being able to explain why an abort wins, why Done persists and why a restored input cannot reuse an old Start request.

By PLC Programming SA · Last updated 2026-09-11