The most dangerous PLC problems do not always hide inside complicated motion algorithms, advanced control loops or enormous data blocks.

Quite often, they begin with logic that looks almost too simple to fail:

  • A START push button
  • A STOP push button
  • A seal-in contact
  • A handful of permissives
  • A reset command
  • A maintenance bypass

The ladder network may fit comfortably on one screen. Everyone understands what it is supposed to do, so it receives less scrutiny than the complicated parts of the program.

Then the machine reaches production.

It starts unexpectedly after power returns. It refuses to restart after a harmless interruption. A motor command flickers during startup. An interlock clears for one scan and allows movement. A bypass remains active after maintenance has finished.

The instructions are usually legal. The program compiles without errors.

The real problem is hidden state behaviour.

Why “Simple” Logic Is Often Underestimated

Basic start-stop circuits are familiar to nearly every electrician and PLC programmer.

A typical motor circuit includes:

  • A normally open START command
  • A normally closed STOP condition
  • A holding or seal-in bit
  • Several permissives
  • An output coil

Because the circuit is familiar, programmers may assume its behaviour is obvious.

However, the PLC version of a start-stop circuit is not identical to a hardwired contactor circuit. It may involve:

  • HMI commands
  • Retained memory
  • Remote I/O
  • Automatic requests
  • Manual requests
  • Safety status
  • Communication data
  • Fault latches
  • Multiple program tasks

Each addition creates another state that must be understood during startup, shutdown and recovery.

The logic remains visually simple while its real behaviour becomes much more complicated.

The Basic Seal-In Circuit

A traditional holding circuit can be represented as:

Run_Command :=
    Stop_Healthy
    AND
    (Start_Request OR Run_Command);

When START is pressed, Run_Command becomes true. Its own contact then maintains the command after the momentary START signal disappears.

Pressing STOP opens the condition and removes the command.

This works well when every condition is local, stable and clearly defined.

Problems begin when Run_Command is also affected somewhere else in the program.

For example:

  • Automatic logic sets it.
  • Manual logic sets it.
  • Fault logic resets it.
  • HMI logic writes directly to it.
  • Recovery logic restores it.
  • Maintenance code bypasses its permissives.

Now the output is no longer controlled by one simple circuit. It has several competing owners.

Multiple Writers Create Invisible Priorities

A common PLC mistake is assigning the same command from several locations.

Consider this program structure:

Network 1:
Manual_Start → Motor_Run

Network 15:
Automatic_Sequence → Motor_Run

Network 40:
Fault_Active → NOT Motor_Run

The final result depends on how the PLC instructions are implemented and in which order they execute.

If the automatic network turns the output on and a later fault network turns it off, the fault appears to have priority.

Move the networks during an online modification and that priority may change.

Another network added months later may unintentionally overwrite the result again.

A better approach is to calculate separate requests:

Manual_Run_Request
Automatic_Run_Request
Maintenance_Run_Request
Stop_Required
Fault_Active
Safety_Healthy

Then assign the physical command once:

Motor_Run :=
    Safety_Healthy
    AND NOT Fault_Active
    AND NOT Stop_Required
    AND
    (
        Manual_Run_Request
        OR Automatic_Run_Request
        OR Maintenance_Run_Request
    );

Now the priority is visible. The motor cannot run merely because one section of the program wrote to the output later than another.

Start and Stop Can Be True Together

It is easy to assume that START and STOP are mutually exclusive.

In a real system, they may overlap.

This can happen when:

  • An operator presses both physical buttons.
  • An HMI START command arrives while a remote STOP input changes.
  • Automatic logic requests a start during a shutdown sequence.
  • A communication failure freezes one command in its last state.
  • The START button remains true because of a stuck HMI tag.
  • Two tasks update the commands asynchronously.

The program must define which command wins.

In most industrial applications:

STOP must override START.

That priority should be expressed directly in the logic rather than depending on network order.

For example:

IF Stop_Required THEN
    Run_Command := FALSE;
ELSIF Start_Request AND All_Permissives THEN
    Run_Command := TRUE;
END_IF;

The result remains clear even when both conditions exist during the same scan.

Latches Store More Than the Programmer Expects

A latch introduces memory.

Once set, it remains active until a specific reset condition occurs. That is useful for alarms, sequence steps and start-stop control, but it also means the current output may depend on an event that happened minutes, hours or even days earlier.

A technician monitoring the ladder online may see:

Start_Request = FALSE
Run_Command = TRUE

That behaviour is normal for a holding circuit, but it can become difficult to troubleshoot when the original set event is unknown.

Hidden latch problems include:

  • A command remaining active after changing operating modes
  • A fault staying latched after the cause disappears
  • A retained latch surviving a PLC restart
  • A reset command clearing the latch for one scan
  • Several blocks setting and resetting the same memory bit
  • An HMI writing directly to a latched variable

Every latch should have:

  • One clear owner
  • A documented set condition
  • A documented reset condition
  • Defined priority
  • Known power-up behaviour
  • Appropriate retentive or non-retentive configuration

If nobody can quickly explain why a latch is currently active, the design is already too obscure.

Retentive Logic Can Cause Unexpected Restart

Retained memory allows a PLC to preserve selected values after power loss.

That can be useful for:

  • Production totals
  • Setpoints
  • Recipes
  • Sequence progress
  • Alarm history

Retaining a motor or movement command is far more dangerous.

Suppose the PLC loses power while Motor_Run is true. If that bit is retentive, it may still be true after power returns.

Depending on the rest of the circuit, the motor could restart when:

  • The PLC returns to RUN
  • The safety circuit is reset
  • The contactor supply returns
  • The drive becomes ready
  • Communication is restored

Even when the physical output does not immediately energize, the stored command may remain waiting for its permissives to return.

Safe design normally requires a fresh and deliberate start action after power restoration or control-system recovery.

The exact requirements depend on the machine and its risk assessment, but automatic restart should never occur merely because an old memory bit survived the interruption.

The Difference Between a Request and a Command

Many unstable PLC programs use one tag to represent several different ideas.

For example, Motor_Run might mean:

  • The operator wants the motor to run
  • The automatic sequence wants it to run
  • The PLC has issued an output command
  • The contactor is physically energized
  • The motor is confirmed running

These are not the same state.

A clearer design separates them:

Motor_Start_Request
Motor_Permissive
Motor_Output_Command
Motor_Contactor_Feedback
Motor_Running_Confirmed

This makes troubleshooting much easier.

The HMI can show that a start was requested but blocked by a missing permissive. The PLC can detect when the command is active but feedback does not arrive.

Combining everything into one Motor_Run bit hides the real sequence of events.

Permissives Can Fail in Both Directions

A permissive is a condition that must be healthy before operation is allowed.

Examples include:

  • Safety circuit healthy
  • Overload relay reset
  • Guard closed
  • Air pressure available
  • Drive ready
  • Valve in correct position
  • Communication established
  • Process level acceptable

Permissives create two separate design questions:

  1. What is required before starting?
  2. What should happen if the condition disappears while running?

The answer may not be the same.

A drive-ready signal may be required before startup, but a brief communication disturbance while running may need controlled fault handling rather than an immediate uncontrolled output change.

A low-pressure condition might require two seconds of stability before permitting startup, yet stop the equipment much faster after a genuine pressure loss.

Using one unexamined permissive expression for both startup and operation often produces nuisance trips or unsafe delays.

Permissives Can Be Stale

A permissive is only useful when its data is valid.

Imagine a remote controller sends:

Remote_System_Ready = TRUE

Communication then fails. The PLC retains the last value, so Remote_System_Ready remains true.

The start circuit still appears healthy even though the remote controller is no longer communicating.

A dependable permissive should include validity:

Remote_Permissive :=
    Remote_Communication_Healthy
    AND Remote_Data_Valid
    AND Remote_System_Ready;

The same principle applies to analog permissives.

A temperature of 30°C cannot be trusted merely because the tag contains 30. The program must also know whether the transmitter, input module and communication path are healthy.

Startup Oscillation

A machine may repeatedly enter and leave its ready state during startup.

For example:

  1. The safety circuit becomes healthy.
  2. The PLC enables a contactor.
  3. The contactor causes a short voltage dip.
  4. A remote device temporarily disconnects.
  5. The permissive drops.
  6. The PLC removes the contactor command.
  7. Communication recovers.
  8. The startup sequence tries again.

The machine appears to oscillate.

Programmers sometimes solve this by adding random timers until the symptom disappears. That may make the machine run, but it does not necessarily correct the root cause.

The commissioning process should determine:

  • Which permissive changed first
  • Whether supply voltage dipped
  • Whether communication became invalid
  • Whether the output affected its own enabling condition
  • Whether the startup logic has a stable initialization state

A startup validation timer can be appropriate, but only after the real sequence is understood.

Fault Reset Logic Can Become a Restart Command

A RESET button should normally acknowledge or clear a fault after its cause has disappeared.

Poorly designed logic may also use RESET to:

  • Clear stop latches
  • Restore automatic mode
  • Re-enable outputs
  • Reset sequence steps
  • Restart timers
  • Reissue movement commands

The operator expects to acknowledge an alarm but unintentionally restarts equipment.

A safer structure separates:

  • Fault acknowledgement
  • Fault reset
  • Recovery command
  • Machine start

Clearing the alarm should not automatically create a new run request.

The system should first return to a defined ready state. A separate start action can then begin operation.

Active Faults Must Override Reset

Consider this latch:

Fault_Condition → SET Fault_Latched
Reset_Request   → RESET Fault_Latched

If both conditions are true in the same scan, the final result may depend on instruction order.

The fault may disappear for one scan and allow another part of the program to continue.

A more predictable structure is:

IF Fault_Condition THEN
    Fault_Latched := TRUE;
ELSIF Reset_Request AND Reset_Conditions_Valid THEN
    Fault_Latched := FALSE;
END_IF;

The active fault has priority.

The reset is accepted only when the original condition is gone and the required recovery conditions are healthy.

Bypasses Are More Dangerous Than They Look

Maintenance bypasses are sometimes necessary during commissioning and troubleshooting.

A bypass may temporarily ignore:

  • A failed sensor
  • A missing feedback contact
  • A process permissive
  • A communication condition
  • A sequence confirmation

The danger is not simply that the interlock is bypassed.

The larger problem is that the rest of the program may continue behaving as though the real condition is healthy.

For example, bypassing a valve-open confirmation may allow a pump to start even though the valve is physically closed.

A bypass should not silently convert an unsafe condition into a normal healthy signal.

Better practice includes:

  • Clearly identifying every active bypass
  • Displaying it prominently on the HMI
  • Restricting access
  • Recording who activated it
  • Applying a time limit where appropriate
  • Preventing automatic operation when necessary
  • Generating an alarm
  • Defining what functionality remains permitted

A bypass is an abnormal operating mode, not a convenient way to remove annoying alarms.

Hidden Bypass Logic

Bypasses often become permanent because they are buried inside ordinary permissive logic:

Valve_OK := Valve_Open_Feedback OR Valve_Bypass;

Months later, the machine operates with Valve_Bypass = TRUE, but nobody notices because Valve_OK appears healthy everywhere else.

Preserve the distinction:

Valve_Feedback_Healthy := Valve_Open_Feedback;

Valve_Start_Permitted :=
    Valve_Open_Feedback
    OR
    (
        Valve_Bypass
        AND Maintenance_Mode
        AND Bypass_Authorization
    );

The HMI and alarm system should still show that the physical valve feedback is missing.

The bypass may permit limited operation, but it should not falsify the diagnostic state.

Automatic and Manual Logic Can Fight Each Other

A motor may be controlled from both manual and automatic modes.

A weak design creates separate output coils:

Manual_Mode AND Manual_Start → Motor_Output

Automatic_Mode AND Sequence_Request → Motor_Output

Additional networks then switch the output off.

This makes the command difficult to follow and introduces duplicate writers.

A better structure creates separate requests and selects between them:

Selected_Run_Request :=
    (Manual_Mode AND Manual_Run_Request)
    OR
    (Automatic_Mode AND Automatic_Run_Request);

The final output is assigned once after applying safety, fault and process conditions.

Mode transitions also require careful handling.

When changing from automatic to manual, decide whether the existing command should:

  • Stop immediately
  • Continue until the operator releases it
  • Transfer smoothly to manual control
  • Be blocked until the machine reaches a safe state

Without a defined rule, the output may remain latched from the previous mode.

Duplicate Outputs Hide Faults

Two coils controlling the same physical address are a classic PLC problem.

One network may energize the output, while another later network de-energizes it. Online monitoring can be misleading because the first coil appears true, even though the physical output remains off after the final assignment.

Cross-reference tools should be used to find every write to:

  • Physical outputs
  • Run commands
  • Sequence-state variables
  • Fault latches
  • Mode bits
  • Shared data

Multiple reads are normal. Multiple uncontrolled writes are not.

One output should generally have one clearly defined assignment point.

Why the Machine Refuses to Stop

An output that refuses to stop may be caused by:

  • Another network reissuing the command
  • A retained latch
  • A stuck HMI command
  • Manual and automatic logic overlapping
  • A bypass overriding the stop condition
  • A remote device controlling the actuator locally
  • Incorrect output ownership
  • Stop logic applied to a request but not the final command

Troubleshooting only the visible start-stop network may miss the real command path.

Record:

  • Every run request
  • Selected operating mode
  • Stop request
  • Permissive result
  • Final output command
  • Physical feedback
  • Remote control status

The output may be behaving correctly according to another section of the program.

Why the Machine Fails to Restart

Restart failures often result from a state that was not cleared properly.

Possible causes include:

  • Fault latch still active
  • Sequence step waiting for an event that already occurred
  • Start pulse missed
  • Drive-ready signal arriving after the start request disappears
  • Retained command conflicting with initialization logic
  • Interlock returning asynchronously
  • Reset accepted before data becomes valid
  • HMI start bit not held long enough

A start request from an HMI should usually be captured reliably rather than requiring it to overlap perfectly with every permissive.

One approach is to store the request temporarily:

IF Start_Button THEN
    Start_Request_Latched := TRUE;
END_IF;

IF Start_Accepted OR Stop_Required THEN
    Start_Request_Latched := FALSE;
END_IF;

The program can then accept the command when all required startup conditions are valid.

The exact design depends on the machine, but momentary communication timing should not create random restart behaviour.

Designing a Predictable Start-Stop Function

A robust motor-control function can separate the logic into layers.

Layer 1: Requests

  • Physical start button
  • HMI start command
  • Automatic sequence request
  • Manual request

Layer 2: Stop conditions

  • Physical stop button
  • HMI stop command
  • Sequence stop request
  • Mode change
  • Fault stop
  • Safety stop status

Layer 3: Permissives

  • Device ready
  • Process conditions healthy
  • Communication valid
  • Required positions confirmed

Layer 4: Command memory

The start request is accepted and stored only when valid.

Layer 5: Final output

The physical output is assigned once.

Layer 6: Feedback monitoring

The program confirms that the device actually responded.

This structure is slightly longer than a one-line seal-in circuit, but its behaviour is far easier to predict and troubleshoot.

Test the Abnormal Combinations

A start-stop circuit is not fully tested by pressing START and then STOP once.

Commissioning should include:

  • START and STOP together
  • START while a permissive is missing
  • Permissive loss while running
  • Reset while the fault remains active
  • Power loss while running
  • Communication loss during startup
  • Automatic-to-manual transition
  • Manual-to-automatic transition
  • Bypass activation while running
  • Bypass removal while the interlock remains unhealthy
  • HMI command interruption
  • Remote I/O reconnection
  • PLC restart with retained values

The result should remain defined in every case.

Capture Why the Output Changed

A useful motor-control block should provide diagnostic reasons such as:

  • Start request not present
  • Safety condition unhealthy
  • Overload active
  • Drive not ready
  • Communication invalid
  • Process permissive missing
  • Stop requested
  • Fault latched
  • Maintenance bypass active
  • Waiting for feedback
  • Feedback timeout

A single Motor_Not_Ready bit is not enough for effective commissioning.

The program should make it possible to determine why the output is off—and why it turned off earlier.

Final Thoughts

Simple PLC logic creates real industrial failures because simple-looking circuits often contain hidden memory, unclear priorities and several competing command sources.

A START button is not merely a contact. A seal-in bit stores history. A permissive may contain stale data. A RESET command can accidentally become a restart. A bypass can hide the true condition of the machine.

The strongest start-stop logic is not the shortest ladder network.

It is the one that clearly defines:

  • Who owns the command
  • What has priority
  • What survives a restart
  • What happens when conditions overlap
  • How faults are cleared
  • How the machine returns to a safe state

Simple logic deserves serious engineering because it often controls the most important action in the entire machine:

whether the equipment is allowed to run.


Leave a Reply

Your email address will not be published. Required fields are marked *