Some PLC faults are easy to understand. A broken sensor stays off. A failed contactor does not pull in. A missing permissive appears clearly in the program.
Race conditions are different.
The machine may run correctly fifty times and fail on the fifty-first attempt. The program looks logical, every individual input works, and the fault disappears when the technician slows the sequence down.
This happens because the result depends not only on which conditions become true, but also on when the PLC receives and processes them.
A race condition occurs when two or more events happen close together and the final outcome changes according to scan order, task timing, communication delay or execution priority.
A Simple PLC Race Condition
Consider a sequence that uses two inputs:
- Input A confirms that a cylinder is extended.
- Input B confirms that a clamp is closed.
The next sequence step begins when both inputs are true.
During normal operation, the clamp closes first and the cylinder reaches its position shortly afterward. The PLC eventually sees both conditions and continues.
Now imagine that both sensors change almost simultaneously.
A possible sequence is:
- Input A becomes true.
- Input B changes physically a fraction of a millisecond later.
- The PLC reads Input A but still sees the old state of Input B.
- The program evaluates the transition condition.
- Another part of the logic interprets the temporary mismatch as a fault.
- Input B becomes true on the following scan.
By the time both signals are visible, the sequence has already entered a fault state.
Nothing is necessarily wrong with either sensor. The problem exists because the program evaluated the machine halfway through a legitimate transition.
Scan Order Can Change the Result
PLC instructions are executed in a defined order.
Suppose one network sets a memory bit and another network resets the same bit later in the scan.
If both conditions are true, the final state usually depends on which instruction is executed last.
For example:
Network 1:
Start condition → Set Motor_Request
Network 8:
Stop condition → Reset Motor_RequestWhen both conditions occur during one scan, the reset wins because it is executed later.
Changing the order of those networks may completely reverse the outcome.
The logic in both networks may be valid when viewed separately. The race appears only when the conditions overlap.
This is one reason why writing to the same output or memory tag from several locations is risky. A single, centralized assignment with clearly defined priorities is much easier to understand.
Remote I/O Makes Timing Less Predictable
Race conditions become more likely when related signals arrive through different paths.
For example:
- Input A is connected directly to the local PLC rack.
- Input B comes from a remote PROFINET station.
- Input C is received from another controller.
- Input D comes from a drive communication telegram.
Although all four conditions may change physically at nearly the same time, they do not necessarily reach the PLC together.
The local input may update first. The remote I/O signal may arrive several milliseconds later. A drive status bit may update according to its own communication cycle.
The PLC can briefly see a combination of states that never existed as a stable physical condition.
Programs should not assume that signals from different devices are perfectly synchronized unless the system is specifically designed to guarantee it.
Startup Sequences Are Especially Vulnerable
Startup logic often contains many conditions that become healthy within a short period:
- Control voltage available
- Safety relay reset
- Drive communication established
- Air pressure healthy
- Valves in home position
- Remote I/O connected
- Overload contacts closed
- Automatic mode selected
If the sequence begins immediately after the first conditions become true, slower signals may arrive too late.
This can produce symptoms such as:
- Startup succeeds on the second attempt.
- A fault appears only after a power cycle.
- One drive is occasionally reported as not ready.
- The machine behaves differently after an emergency stop.
- A sequence skips or enters the wrong step.
A brief startup validation period can help. Instead of starting as soon as all permissives appear true for one scan, require them to remain continuously healthy for a defined time.
That does not hide genuine faults. It prevents harmless communication and initialization differences from being treated as failures.
Restart and Recovery Logic
Restart recovery creates another common race condition.
After power restoration, different devices recover at different speeds:
- The PLC may enter RUN quickly.
- Remote I/O may take longer to reconnect.
- VFDs may still be initializing.
- Smart instruments may not yet have valid process data.
- HMI commands may be restored from retained tags.
- Mechanical equipment may not be in its expected position.
If the program immediately evaluates every interlock, it may store an incorrect fault or sequence state before the devices finish starting.
Good recovery logic should distinguish between:
- Device still initializing
- Device unavailable
- Device connected but not ready
- Device ready for operation
- Device genuinely faulted
These are not the same conditions.
Latches Can Behave Randomly
Set-reset latches are useful, but they frequently expose timing problems.
Imagine a fault latch with:
- A set condition from a sensor
- A reset condition from an operator button
If both are true in the same scan, the result depends on the implementation and instruction order.
Should the active fault remain latched, or should the reset command clear it?
For safety and diagnostics, active fault conditions should generally take priority over reset requests. The reset should only succeed after the original fault has disappeared.
A clearer structure is:
IF Fault_Condition THEN
Fault_Latched := TRUE;
ELSIF Reset_Request THEN
Fault_Latched := FALSE;
END_IF;This gives the fault condition explicit priority.
Without a clear priority, the latch may appear to reset randomly or immediately return.
Online Edits Can Reveal Hidden Timing Problems
Online program changes can alter:
- Block execution order
- Temporary variable values
- Initialization states
- Timer behaviour
- Communication load
- Task duration
The edited logic may be correct, yet the machine can briefly pass through an unexpected state when the change is applied.
This is particularly dangerous when modifying:
- Sequence steps
- State-machine transitions
- Set-reset logic
- Shared data blocks
- Interlocks
- Motion commands
Online edits should be planned around the live operating state. Critical changes may require stopping the process, resetting sequence states and performing a controlled restart.
Asynchronous Tasks and Interrupts
Modern PLCs often run several tasks at different rates.
For example:
- Main cyclic program every 10 ms
- Fast interrupt task every 2 ms
- Communication block every 100 ms
- Slow calculation task every second
If multiple tasks read and write the same tag, the value may change while another task is using it.
A fast task might update a measurement halfway through a slower calculation. The slower task then processes a mixture of old and new data.
Possible solutions include:
- Keeping ownership of each tag within one task
- Copying shared data into a local structure
- Using consistent data-transfer methods
- Handshaking between tasks
- Avoiding multiple writers
- Processing complete records rather than individual changing values
Shared data should have a clearly defined owner.
Common Symptoms
Race conditions often produce recognizable patterns.
The fault cannot be reproduced consistently
The required timing combination occurs only occasionally. Manually forcing signals usually changes too slowly to recreate it.
Startup behaves differently each time
Devices become ready in slightly different orders after each restart.
The logic works in simulation
Offline simulation rarely reproduces real network latency, mechanical response and communication jitter.
A sequence enters an impossible state
Related inputs were received during different scans, creating a temporary combination the programmer did not expect.
A latch appears to set or reset randomly
Both commands may be active during the same scan, with the outcome determined by program order.
Slowing the machine fixes the problem
The additional time allows every sensor and communication value to update before the next transition is evaluated.
How to Prevent Race Conditions
Define Priorities Explicitly
Decide what should happen when conflicting conditions occur together.
For example:
- Fault overrides run
- Stop overrides start
- Safety overrides automatic operation
- Active alarm overrides reset
- Manual mode overrides automatic command only when safely selected
Do not leave priority to accidental network order.
Use One Writer Per Command
Calculate all conditions using intermediate tags, then assign the final output in one place.
Instead of setting and resetting Motor_Run throughout the program, create:
Auto_Run_RequestManual_Run_RequestStop_RequiredSafety_HealthyMotor_Permissive
Then produce one final expression:
Motor_Run :=
Safety_Healthy
AND Motor_Permissive
AND NOT Stop_Required
AND (Auto_Run_Request OR Manual_Run_Request);The priority becomes visible.
Add State Validation
Do not advance a sequence because a condition was true for one scan unless one scan is genuinely sufficient.
Require important conditions to remain stable for a suitable period.
Examples include:
- Drive ready for 200 ms
- Pressure healthy for one second
- Guard closed and locked for 100 ms
- All home sensors valid before enabling automatic mode
The delay should reflect the real process, not merely cover up poor logic.
Use Handshakes
When coordinating with another controller, robot or drive, use a handshake:
- PLC sends request.
- Device acknowledges the request.
- Device performs the action.
- Device sends complete.
- PLC removes the request.
- Device removes acknowledgement.
This is more reliable than expecting both systems to change bits in a particular millisecond.
Separate Transitional and Fault States
A temporary mismatch during movement may be normal.
For example, while a reversing valve changes position, both end sensors may briefly be false. That should not automatically be treated as a fault.
A better sequence distinguishes between:
- Command issued
- Movement in progress
- Expected confirmation received
- Movement timeout expired
Only after the allowed transition time passes should the mismatch generate a fault.
Troubleshooting Race Conditions
Ordinary HMI observation is usually not fast enough.
Use:
- PLC trace recording
- Sequence-step history
- First-out fault capture
- Event counters
- Timestamps
- Maximum scan-time monitoring
- Network diagnostics
- Raw and processed signal comparison
Capture the relevant signals together:
- Raw inputs
- Filtered inputs
- Sequence state
- Transition condition
- Fault condition
- Set command
- Reset command
- Final output
The objective is to identify which condition changed first and which task processed it.
Do not only inspect the final fault state. By then, the event that caused it may have disappeared hundreds of scans earlier.
Why Offline Testing Often Misses the Problem
Simulation typically changes inputs in an orderly way.
The user clicks Sensor A, waits, then clicks Sensor B. Every signal remains active long enough for the program to process it.
A real machine does not behave so politely.
Sensors change during motion. Network messages arrive independently. Mechanical delays vary. Operators press buttons at inconvenient moments. Two faults may clear together.
Testing should therefore include:
- Simultaneous input changes
- Rapid start-stop commands
- Power restoration
- Communication interruptions
- Slow and fast device responses
- Unexpected operator actions
- Signals arriving in the wrong order
A sequence is not fully tested until its timing boundaries have also been tested.
Final Thoughts
A race condition does not necessarily mean the Boolean logic is incorrect.
It means the program’s result depends on timing that has not been controlled clearly enough.
The most reliable PLC programs avoid multiple writers, define command priorities, validate transitional states and use handshakes when coordinating asynchronous equipment.
When a machine fails only occasionally, works in simulation and refuses to reproduce while someone is watching, timing should move near the top of the suspect list.
The important question is not simply:
“Were both conditions true?”
It is:
“Which condition became visible to the PLC first, and what did the program do during that scan?”
