Free
25 min

Car Wash PLC Ladder Diagram (Run the Program Free Online)

This page covers the full car wash PLC ladder diagram — a timer-driven SOAP → BRUSHES → RINSE → DRYER sequence with a START/STOP interface and a wash-complete lamp. It is grounded in a live scenario you can run directly in your browser: write the ladder, watch the bay step through each stage, and get instant pass/fail feedback — no PLC hardware, no software install. An automatic car wash program is the classic beginner sequencing exercise, and this one is runnable and auto-graded free.

sequencingtimersbeginner
Car Wash scenario preview

Ready to build this?

Sign up free — no credit card required. This scenario is included in the free tier.

Sign up to play this scenario →

Already have an account? Log in

Briefing

An automatic car-wash bay runs a fixed wash sequence. When a car drives into the bay it breaks the CAR_PRESENT photo-eye. The operator then presses START to begin the cycle. The bay must run each stage for three seconds, one stage at a time, in order: SOAP, then BRUSHES, then RINSE, then DRYER. When the dryer finishes, a DONE lamp latches on to tell the driver the wash is complete. Pressing STOP at any point is an emergency abort: every output must drop immediately.

Objectives

  • Do nothing until CAR_PRESENT is true AND START is pressed
  • Run SOAP for 3 seconds, then BRUSHES for 3 seconds, then RINSE for 3 seconds, then DRYER for 3 seconds
  • Energise exactly one wash stage at a time (no overlap)
  • Latch DONE_LAMP on only after the DRYER stage completes
  • STOP aborts the cycle and de-energises every output

Hints

  • Latch a "phase" bit for each stage (PH_SOAP, PH_BRUSH, …). START AND CAR_PRESENT sets the first phase; chain the rest off each timer's .Q output.
  • Give each phase its own TON: T_SOAP(IN := PH_SOAP, PT := 3000). When T_SOAP.Q goes true, RESET PH_SOAP and SET PH_BRUSH. The timer's IN drops with the phase, so it resets itself for next time.
  • Drive each output coil directly from its phase bit: | PH_SOAP | := SOAP ;. Latch DONE_LAMP on T_DRYER.Q. Put a | STOP | R= on every phase + DONE_LAMP so the abort clears the whole machine.

I/O Table

Inputs

START

Start push-button (momentary)

BOOL · %I0.0

STOP

Stop / abort push-button (momentary)

BOOL · %I0.1

CAR_PRESENT

Car-in-bay photo-eye (beam broken by a car)

BOOL · %I0.2

Outputs

SOAP

Soap / pre-soak spray valve

BOOL · %Q0.0

BRUSHES

Scrub brushes motor

BOOL · %Q0.1

RINSE

Rinse spray valve

BOOL · %Q0.2

DRYER

Blower / dryer

BOOL · %Q0.3

DONE_LAMP

Wash-complete indicator lamp

BOOL · %Q0.4

Your program will be tested against:

All test cases run automatically when you submit. Assertions are hidden until you pass.

  1. #1No car in bay -> START does nothing

    With CAR_PRESENT false, pressing START must leave every stage off.

  2. #2Full wash cycle runs each stage in order

    Car present + START -> SOAP, BRUSHES, RINSE, DRYER each 3s, one at a time, then DONE_LAMP latches.

  3. #3STOP mid-cycle aborts the wash

    After the cycle reaches BRUSHES, STOP drops every output.

  4. #4DONE_LAMP stays off until the dryer finishes

    Through SOAP/BRUSHES/RINSE/DRYER the DONE lamp must remain off; it lights only after DRYER completes.

How an automatic car wash PLC program works

An automatic car wash PLC program is a fixed-order, timed sequence — a state machine that walks through one wash stage at a time. The bay does nothing until two conditions are both true: a car has driven in and broken the CAR_PRESENT photo-eye, and the operator has pressed START. Only then does the cycle begin.

The wash runs four stages in strict order, three seconds each: SOAP, then BRUSHES, then RINSE, then DRYER. Exactly one stage may be energised at any moment — there is no overlap. When SOAP's timer finishes, SOAP must turn off the instant BRUSHES turns on, and so on down the chain. After the DRYER stage completes, a DONE_LAMP latches on to tell the driver the wash is finished. Pressing STOP at any point is an emergency abort: every output drops immediately.

The I/O is pre-wired for you. Three inputs: START (%I0.0, momentary push-button), STOP (%I0.1, abort push-button), and CAR_PRESENT (%I0.2, the car-in-bay photo-eye whose beam is broken by a car). Five outputs: SOAP (%Q0.0, the pre-soak spray valve), BRUSHES (%Q0.1, the scrub-brush motor), RINSE (%Q0.2, the rinse spray valve), DRYER (%Q0.3, the blower), and DONE_LAMP (%Q0.4, the wash-complete indicator).

Because the whole program is driven by on-delay timers handing off to one another, the car wash PLC program is a textbook way to learn TON timers and sequence control before moving on to counters, interlocks and analog work.

Sequencing the stages with TON timers — the car wash PLC program structure

The cleanest way to build this car wash control using a PLC is a phase-latch state machine: one latched bit per stage (PH_SOAP, PH_BRUSH, PH_RINSE, PH_DRYER) and one TON timer per stage. The phase bit says which stage is active; the timer measures how long the stage has run; the timer's done bit hands off to the next phase.

Start the chain by latching the first phase only when both gate conditions are met — SET PH_SOAP on START AND CAR_PRESENT. This is the rung that makes the bay ignore a START press when no car is in the bay, which is exactly what the discriminating 'no-car-no-cycle' test case checks: a naive rung that just mirrors START → SOAP fails immediately because it skips CAR_PRESENT and the sequencing.

Give each phase its own on-delay timer: T_SOAP(IN := PH_SOAP, PT := 3000ms). When T_SOAP.Q goes true the three seconds are up, so RESET PH_SOAP and SET PH_BRUSH on the same rung. Because PH_SOAP just dropped, the timer's IN input drops with it and T_SOAP resets itself, ready for the next car. Chain BRUSHES → RINSE → DRYER the same way, each phase set off the previous timer's done bit.

Drive each output coil directly from its phase bit — | PH_SOAP | := SOAP — so only one stage energises at a time by construction. Latch DONE_LAMP on T_DRYER.Q, the moment the final stage completes. This single-active-phase structure is why the 'happy-path' test sees SOAP, BRUSHES, RINSE and DRYER fire in order with no overlap.

STOP abort and the DONE lamp — getting the edge cases right

Two details separate a car wash PLC ladder diagram that merely runs from one that passes every test: the abort and the completion lamp.

The STOP abort must clear the entire machine, not just the stage that happens to be running. The simplest reliable pattern is to put a | STOP | R= reset on every phase bit (PH_SOAP, PH_BRUSH, PH_RINSE, PH_DRYER) and on DONE_LAMP. When STOP is pressed, every phase latch resets, every timer's IN drops because its phase is gone, and every output coil — driven directly from its phase bit — de-energises on the same scan. The 'stop-aborts' test advances the cycle to BRUSHES, presses STOP, and asserts SOAP, BRUSHES, RINSE, DRYER and DONE_LAMP are all off. A partial abort that only stops the current stage fails here.

The DONE_LAMP must stay off through every wash stage and light only after the DRYER finishes. If you accidentally drive it from a phase bit, or latch it too early, the 'done-only-after-dryer' test catches it: it samples DONE_LAMP while DRYER is still running (it must be off) and again after DRYER completes (it must be on). Latch DONE_LAMP from T_DRYER.Q — the dryer timer's done bit — not from PH_DRYER, so the lamp lights at the end of the dryer stage rather than at its start. Include DONE_LAMP in the STOP reset so a new car starts with a clean indicator.

The timer-chain state machine pattern

Step back from the car wash for a moment, because the structure you build here — a timer chain, sometimes called cascading timers — is one of the most reusable patterns in PLC programming. The idea: the process is a sequence of states, each state has a fixed duration, and the event that moves the machine forward is always a timer's done bit. State comes from latched phase bits (PH_SOAP, PH_BRUSH, PH_RINSE, PH_DRYER); time comes from one TON per phase; the .Q output of each timer is the handoff signal that resets the current phase and sets the next.

The elegant detail is that the timers clean up after themselves. Because each TON's IN input is its own phase bit — T_SOAP(IN := PH_SOAP, PT := 3000ms) — the moment T_SOAP.Q resets PH_SOAP, the timer's input drops and the timer zeroes its accumulator. No explicit timer-reset rungs, no stale elapsed time waiting to surprise you when the next car drives in. Each stage's timer is guaranteed fresh every cycle, by construction.

Compare that to the tempting shortcut: one master timer with PT := 12000ms and comparison rungs carving it into windows — SOAP when the accumulator is below 3000, BRUSHES between 3000 and 6000, and so on. It works for the happy path, then falls apart at the edges. A STOP abort mid-cycle leaves you managing a partially-elapsed master timer; changing one stage's duration means re-deriving every window boundary; and the comparison rungs say nothing about which stage is active, so the program gets harder to read as it grows. The phase-latch chain keeps each stage's logic in one place.

The pattern also scales without surgery. Want a WAX stage between RINSE and DRYER on a real machine? One new phase bit, one new TON, and re-pointing two handoff rungs — every other stage is untouched. Traffic lights, batch mixers, kiln cycles, sterilisation sequences: any fixed-order timed process is this same chain with different tag names, which is exactly why the car wash is worth mastering properly.

Why the car wash is a classic beginner PLC project

The car wash is one of the most-assigned first projects in PLC training, and for good reason. It teaches the three skills every PLC programmer needs — sequencing, timing and a clean operator interface — without any of the complications of analog signals, PID loops or communications.

First, it makes the one-stage-at-a-time discipline concrete. A learner who tries to fudge the sequence with overlapping coils sees the simulated bay run two stages at once and the auto-grader reject it. That immediate, visible feedback teaches the value of a single-active-state machine far faster than a lecture does.

Second, it is the natural home for the TON on-delay timer. Each stage is just 'run this output for three seconds, then move on', which is the canonical TON use case. Chaining four of them — each timer's done bit launching the next phase — is the pattern you will reuse for traffic lights, batch processes and any other timed sequence.

Third, it introduces fail-safe operator control: a START that is properly gated (it does nothing without a car present) and a STOP that drops everything immediately. Those are habits worth forming early.

You can build and run the whole thing on this page. Write the ladder, press Run, and watch the bay step SOAP → BRUSHES → RINSE → DRYER → DONE. Four automated test cases grade the start gate, the full cycle, the STOP abort and the completion lamp — no physical PLC, sprayers or blowers required.

Troubleshooting your car wash program

When a car wash PLC program fails the auto-grader, the fault is almost always in the start gate, the phase handoff, or the abort logic. Here are the failure modes learners hit most often in this scenario, and what each one looks like.

The wash starts with no car in the bay. The classic naive rung maps START straight to SOAP, ignoring the photo-eye. The 'no-car-no-cycle' test presses START with CAR_PRESENT false and asserts every output stays off — a direct START → SOAP mapping fails on the first assertion. The fix is to SET PH_SOAP only on START AND CAR_PRESENT, never to drive SOAP from START directly.

Two stages run at the same time. If the handoff rung sets PH_BRUSH but forgets to reset PH_SOAP, both phase bits are latched and the bay runs soap spray and brushes together. The 'happy-path' test asserts the off-stages at every sample point (SOAP must be false while BRUSHES is true), so any overlap fails. Reset the outgoing phase and set the incoming phase on the same rung, off the same timer done bit, and drive each output coil only from its own phase bit.

The sequence stalls after SOAP. Usually one of three causes: the timer's IN is wired to the wrong bit (something that drops before 3 seconds elapse, so the timer never finishes); the next phase is set from the wrong timer's done bit (T_SOAP.Q accidentally referenced where T_BRUSH.Q belongs); or the preset is wrong — 3000 means milliseconds here, and writing T#3000s or 30000 makes the stage appear frozen. Watch the timer's accumulated value while the stage is active: if it is not counting toward 3000, the IN side is the problem; if it completes but nothing advances, the handoff rung is.

DONE_LAMP lights as soon as the dryer starts. Latching the lamp from PH_DRYER instead of T_DRYER.Q lights it at the start of the dryer stage, not the end. The 'done-only-after-dryer' test samples DONE_LAMP while DRYER is still true and fails the program if the lamp is already on. Latch from the timer's done bit.

STOP does not kill everything. A STOP rung that only resets the currently-running phase — or forgets DONE_LAMP — leaves outputs latched. The 'stop-aborts' test advances the cycle to BRUSHES, presses STOP, and asserts all five outputs are false. Put a STOP reset on every phase bit and on DONE_LAMP; because each output is driven from its phase bit and each timer's IN is its phase bit, everything else drops on the same scan.

The second car never gets a wash. If any phase bit or the DONE lamp survives the previous cycle, the next START press meets a machine that is not in its idle state. The phase-latch structure handles this for you — each phase resets itself during the handoff and the timers self-reset when their phase drops — but only if DONE_LAMP is also cleared, either by STOP or when a new cycle begins.

Frequently asked questions

What is a car wash PLC program?

A car wash PLC program is a timed sequence controller that runs an automatic wash bay through a fixed set of stages — typically soap, brushes, rinse and dryer — one stage at a time. It waits for a car to be present and the operator to press START, runs each stage for a set duration using on-delay (TON) timers, lights a wash-complete lamp at the end, and stops everything immediately if STOP is pressed. It is a classic beginner project because it teaches sequencing and timing without analog or communications complexity.

How do you make a car wash PLC ladder diagram?

Build it as a phase-latch state machine. Latch one bit per stage (PH_SOAP, PH_BRUSH, PH_RINSE, PH_DRYER); SET the first phase on START AND CAR_PRESENT. Give each phase a TON timer with a 3-second preset, and when a timer's done bit goes true, RESET its own phase and SET the next one. Drive each output coil (SOAP, BRUSHES, RINSE, DRYER) directly from its phase bit so only one runs at a time, latch DONE_LAMP on the dryer timer's done bit, and put a STOP reset on every phase and the lamp.

What I/O does an automatic car wash PLC program need?

This automatic car wash PLC program uses three inputs — START (%I0.0), STOP (%I0.1) and CAR_PRESENT (%I0.2, a photo-eye broken by the car) — and five outputs: SOAP (%Q0.0), BRUSHES (%Q0.1), RINSE (%Q0.2), DRYER (%Q0.3) and DONE_LAMP (%Q0.4). The bay only begins a cycle when CAR_PRESENT and START are both true, runs each output stage for three seconds in order, then latches DONE_LAMP after the dryer finishes.

How do timers control the car wash sequence?

Each wash stage gets its own TON (on-delay) timer with a 3000 ms preset, enabled by that stage's phase bit. While the phase bit is on, the timer counts; when it reaches the preset its done bit (.Q) goes true. That done bit does two things on the same scan: it resets the current phase (which drops the timer's IN input so the timer resets itself for next time) and it sets the next phase, launching the next timer. Chaining four timers this way carries the SOAP → BRUSHES → RINSE → DRYER sequence with no operator action between stages.

Can I run a car wash control using PLC logic without hardware?

Yes. The Car Wash scenario on this page runs directly in your browser — write the ladder logic, press Run, and watch the simulated bay step through soap, brushes, rinse and dryer before the DONE lamp lights. The auto-grader checks four cases: that START does nothing with no car present, that the full cycle runs each stage in order with no overlap, that STOP aborts and drops every output, and that the DONE lamp stays off until the dryer completes. No physical PLC, sprayers or blowers are needed.

Why do two wash stages run at the same time in my program?

Because the phase handoff is incomplete: the rung that starts the next stage is not resetting the previous one. When T_SOAP.Q goes true you must RESET PH_SOAP and SET PH_BRUSH on the same rung — if PH_SOAP stays latched, both phase bits (and both output coils) are on together, and the happy-path test fails because it asserts SOAP is off while BRUSHES is running. Driving each output only from its own phase bit makes single-stage operation structural rather than accidental.

Why does my car wash sequence stall on one stage and never advance?

Three usual causes. The timer's IN input is wired to a bit that drops before the preset elapses, so the timer never reaches its done state. The next phase is being set from the wrong timer's done bit — for example T_SOAP.Q referenced where T_BRUSH.Q belongs, so the chain has a broken link. Or the preset is in the wrong units: the stages here are 3000 ms, and a preset of T#3000s or 30000 makes the stage look frozen. Watch the active timer's accumulated value: if it is not counting up toward 3000, fix the IN side; if it completes but nothing changes, fix the handoff rung.

Can I use one timer instead of four for the car wash sequence?

You can — a single TON with a 12-second preset and comparison rungs slicing the accumulator into windows (SOAP below 3000 ms, BRUSHES from 3000 to 6000, and so on) — but it is the more fragile design. A STOP abort mid-cycle leaves a partially elapsed master timer to manage, changing one stage's duration forces you to recalculate every window boundary, and the comparisons hide which stage is active. The phase-latch chain with one TON per stage costs a few more rungs and repays them in abort handling, self-resetting timers, and stages you can retime or add independently.

Ready to build this?

Sign up free — no credit card required. This scenario is included in the free tier.

Sign up to play this scenario →

Already have an account? Log in