Overview: What a Door Control Rung Actually Has to Do
An automatic door controller is a reversing motor control problem wrapped in a safety problem. The PLC reads push buttons, presence/proximity sensors, end-of-travel limit switches and safety interlocks, then drives two mutually exclusive outputs: OPEN and CLOSE. Everything else - auto-close timers, obstruction reversal, jam detection, manual/auto mode - is layered on top of that core.
The failure modes that bite in the field are almost always one of four things:
- Both direction outputs energized simultaneously (contactor short circuit).
- Motor driving into a hard stop because the stop limit was wired or scanned wrong.
- A momentary push button with no seal-in, so the door only moves while the operator holds the button.
- Safety devices routed through PLC logic only, with no hardwired path to the contactor coils.
I/O Definition and Signal Types
Define the I/O list before writing a single rung. The addresses below are examples - substitute your platform's addressing (Allen-Bradley tags, Siemens %I0.0, Mitsubishi X000, etc.).
| Symbol | Example Addr | Type | Contact Used | Purpose |
|---|---|---|---|---|
| PB_OPEN | I0.0 | NO push button | NO | Manual open request |
| PB_CLOSE | I0.1 | NO push button | NO | Manual close request |
| PB_STOP | I0.2 | NC push button | NO in logic | Stop / drop seal-in |
| LS_OPEN | I0.3 | Limit switch, fully open | NC preferred | Stops OPEN output |
| LS_CLOSE | I0.4 | Limit switch, fully closed | NC preferred | Stops CLOSE output |
| PROX_APPR | I0.5 | Proximity / motion sensor | NO | Auto-open request |
| SAFETY_EDGE | I0.6 | Safety edge / photo-eye | NC (closed = clear) | Reverse or inhibit close |
| INTERLOCK_OK | I0.7 | Door interlock / permissive | NC | Blocks all motion when open |
| OUT_OPEN | Q0.0 | Relay/transistor out | - | Open contactor coil |
| OUT_CLOSE | Q0.1 | Relay/transistor out | - | Close contactor coil |
Wire Stop and Limit Devices Normally Closed
Stop buttons, end limits and safety contacts must be wired as normally-closed field contacts so that a broken wire, a loose ferrule or a lost 24 V supply produces the safe state (input goes false, motion stops). In the ladder you then use an examine-if-closed / NO contact for those signals. Mixing this up - wiring an NO limit and testing it with an NO contact - is the classic reason a door runs into the frame after a cable pull.
Core Ladder Logic: Interlocked Seal-In Rungs
The pattern is two latched rungs, each broken by its own end limit and by the opposite output. Written in structured pseudo-ladder:
RUNG 1 - OPEN
( PB_OPEN OR PROX_APPR OR OUT_OPEN ) // start or seal-in
AND PB_STOP // NC field wiring, true = not pressed
AND LS_OPEN // NC field wiring, true = not at open limit
AND INTERLOCK_OK
AND NOT OUT_CLOSE // software interlock
---> OUT_OPEN
RUNG 2 - CLOSE
( PB_CLOSE OR CLOSE_REQ OR OUT_CLOSE )
AND PB_STOP
AND LS_CLOSE // NC, true = not at closed limit
AND SAFETY_EDGE // NC, true = path clear
AND INTERLOCK_OK
AND NOT PROX_APPR // presence in doorway blocks close
AND NOT OUT_OPEN // software interlock
---> OUT_CLOSE
Three details make this rung set reliable:
- Seal-in branch: paralleling the output's own contact with the start condition latches motion from a momentary button. Without it, the door creeps only while the button is held.
-
Cross-interlock:
NOT OUT_CLOSEin the open rung andNOT OUT_OPENin the close rung guarantee the two coils are mutually exclusive in software. Because the PLC solves rungs sequentially in one scan, this alone can still allow a one-scan overlap on some sequences - back it up in hardware. - Limit switch in series with the coil, not just as a latch reset: the end limit must be a permissive on the rung so the output drops immediately in the same scan the limit is made.
Direction Change Dead Time
Do not let the door reverse instantaneously. Add a transition delay so the motor and contactors settle:
REVERSE_INHIBIT:
ON-DELAY timer TON_DIR, PT = 0.5 s // set per motor/drive data
Started when either OUT_OPEN or OUT_CLOSE drops
Both direction rungs require TON_DIR.DN before re-energizing
Choose the preset from the motor, gearbox and contactor manufacturer's data - a plugging reversal on an unloaded contactor set is not the same problem as reversing a high-inertia rolling shutter. If a VFD drives the door, use the drive's own ramp and direction-change parameters and give the PLC only a run/direction command; do not switch drive output contactors under load.
Sequencing Layer: Auto-Close, Obstruction Reversal, Jam Detection
Auto-Close Dwell Timer
DWELL:
TON_DWELL enabled by ( AT_OPEN AND NOT PROX_APPR AND NOT SAFETY_EDGE_TRIPPED )
Any presence detection resets TON_DWELL to 0
CLOSE_REQ = TON_DWELL.DN
The timer must be reset - not paused - by presence detection, otherwise a person standing in the doorway consumes the dwell time and the door closes the instant they clear the sensor field.
Obstruction Reversal
IF OUT_CLOSE AND (NOT SAFETY_EDGE) THEN
OUT_CLOSE := 0
REOPEN_LATCH := 1 // held until AT_OPEN
OUT_OPEN start condition includes REOPEN_LATCH (after dead time)
Latch the reopen command. If you drive OUT_OPEN directly from the safety-edge state, the door stops as soon as the obstruction clears and parks mid-travel.
Travel-Time Watchdog
A jam, a slipping clutch or a failed limit switch all look the same to the logic: motion commanded, target limit never reached. Add a watchdog per direction:
TON_TRAVEL_OPEN enabled by OUT_OPEN, PT = measured_open_time * 1.5
TON_TRAVEL_CLOSE enabled by OUT_CLOSE, PT = measured_close_time * 1.5
IF TON_TRAVEL_x.DN THEN FAULT_JAM := 1 ; drop both outputs
Measure the actual travel time during commissioning and set the preset from that measurement rather than a guessed number. Require a manual fault reset so a jammed door does not retry indefinitely into an obstruction.
Commissioning and Verification
- Power off, prove the wiring. Ring out each limit switch and verify NC devices show continuity in the un-actuated state. Confirm reversing contactor mechanical interlock physically blocks simultaneous pull-in.
- Inputs only. Force outputs disabled or pull the motor branch fuses. Actuate every input by hand and confirm the corresponding bit toggles in the correct sense in the PLC monitor. Verify LS_OPEN/LS_CLOSE bits are TRUE when the door is off the limit.
- Interlock proof. With outputs still isolated, drive OPEN then command CLOSE. Confirm OUT_CLOSE never energizes while OUT_OPEN is on, and vice versa.
- Slow first motion. Restore power. Jog OPEN in short bursts with a hand on the stop, confirming the door moves in the labeled direction. If it runs backwards, swap two motor leads - do not swap the PLC outputs, or your limit switches will end up on the wrong rungs.
- Limit stop test. Run to each end limit and verify the output drops before the mechanical stop, with adequate coast distance. Adjust limit cam or sensor position, not the software.
- Safety function test. Obstruct the safety edge/photo-eye mid-close. Confirm the door stops and reverses, and confirm the hardwired path also stops motion with the PLC in STOP/program mode.
- E-Stop test. Press E-Stop during travel. Motion must stop regardless of PLC state, and restart must require a deliberate reset - never restart on release.
- Dwell and watchdog. Time the auto-close dwell with a stopwatch, then break the beam during dwell and confirm the timer resets to full value. Block the door mechanically (safely) to confirm the travel watchdog raises FAULT_JAM.
Troubleshooting Table
| Symptom | Likely Cause | Check |
|---|---|---|
| Door moves only while button held | Missing seal-in branch | Verify output contact paralleled with start condition |
| Door runs into frame | Limit wired NO but tested as NC, or limit only resets a latch | Force limit by hand, watch input bit; put limit in series on the rung |
| Contactor chatter on reversal | No direction dead time; both rungs true in adjacent scans | Add TON_DIR inhibit; verify contactor aux interlocks |
| Door closes on a person standing in doorway | Dwell timer paused instead of reset by presence input | Confirm presence input resets timer accumulator to 0 |
| Door stops mid-travel after obstruction clears | Reopen driven directly from safety input, not latched | Add REOPEN_LATCH held until AT_OPEN |
| Random stops, no fault | Broken conductor on NC stop/limit string, loose ferrule | Trend the input bits; wiggle-test the festoon/flexible cable |
| Both contactors trip main breaker | Software-only interlock; welded contact | Install mechanical + electrical contactor interlock |
Design Notes That Save Rework
- One output, one owner. Never write OUT_OPEN from more than one rung. Build a single request word (manual, auto, reopen) and OR the requests into one rung.
- Separate mode from motion. Keep AUTO/MANUAL selection in a mode rung that produces permissives; do not scatter mode contacts through every motion rung.
- Debounce mechanical contacts. A 20-50 ms on-delay on limit and push button inputs (or the input module's hardware filter) removes chatter-induced double transitions. Set the filter from the module's configuration, and keep it well below your travel times.
- Diagnostics bits are cheap. Publish AT_OPEN, AT_CLOSE, IN_TRAVEL, FAULT_JAM, SAFETY_TRIPPED to the HMI. Field techs troubleshoot from those bits far faster than from a laptop.
- Retentive vs. non-retentive latches. Do not use retentive latches for motion outputs. A power cycle must land the door in a known de-energized state requiring an operator command.
Why does my PLC-controlled door only move while I hold the button?
The open/close rung has no seal-in branch. Parallel a normally-open contact of the output coil with the momentary push button contact, and break the branch with the stop button, the end-of-travel limit and the opposite-direction interlock.
Should door limit switches be wired normally open or normally closed?
Wire end-of-travel limits, stop buttons and safety contacts normally closed so a broken wire or lost 24 V supply drops the input and stops motion. In the ladder, test them with normally-open (examine-if-closed) contacts placed in series on the motion rung.
Is a software interlock enough to stop both door contactors energizing?
No. Keep the software cross-interlock (NOT OUT_CLOSE in the open rung and vice versa), but also use mechanically and electrically interlocked reversing contactors with auxiliary NC contacts in series with the opposite coil, so a welded contact or forced output cannot create a phase-to-phase fault.
How do I make the door reverse when the safety edge is blocked?
On the close-direction rung, drop OUT_CLOSE when the safety edge input goes false and set a latched REOPEN bit. Feed that latch into the open rung after the direction dead-time timer expires, and clear it only when the fully-open limit is reached.
How do I detect a jammed door in ladder logic?
Run an on-delay timer for each direction, enabled by that direction's output, with a preset around 1.5x the travel time you measured during commissioning. If the timer completes before the target limit switch is made, set a jam fault, drop both outputs and require a manual reset.