PLC Programming Best Practices: Structure, Naming, Reusable Blocks, Interlocks, Diagnostics and Code Review

On this page

A PLC program is read far more often than it is written: by maintenance technicians at 3 a.m., by the next engineer who has to change it, and by auditors after an incident. Good PLC code is therefore not the cleverest code but the most predictable: structured the same way everywhere, named consistently, built from tested blocks, and clear about why each output does what it does.

PLC Programming Best Practices: Structure, Naming, Safety & interlocks, Diagnostics, Version control, Testing
Good structure and documentation make PLC programs maintainable.

Many companies write these rules into a programming standard; PLCopen also publishes coding guidelines for IEC 61131-3. The practices below are a practical starting point.

1. Structure the program by equipment

Level Example Contents
Machine or area Filler, Mixer_Area Mode handling, sequences, area interlocks
Unit or station Infeed_Conveyor Coordination of devices
Device M101 (motor), V205 (valve) Instance of a standard function block

This follows the physical plant, so a technician looking for pump P-101 finds it in one place. In batch processes, the same idea is formalised by the ISA-88 physical model (equipment modules and control modules); see ISA-88.

Structuring a PLC Program by Equipment: Machine / area, Unit / station, Device
A structure that follows the plant makes every device easy to find.

2. Name things consistently

Element Convention example
Devices Plant tag numbers from the P&ID or electrical drawings: P101, FV205, LT310
Inputs and outputs Device plus signal: P101_Running, P101_Start_Cmd, LT310_Raw
Interlocks P101_Intlk_LowLevel
Alarms P101_Alm_Overload
Function blocks Type prefix: FB_Motor, FB_Valve, FB_AnalogIn

Pick one convention, document it, and use it everywhere. Mixed styles make searching and cross-referencing unreliable.

3. Build from reusable function blocks

A standard motor block used for every motor makes behaviour, HMI faceplates and diagnostics consistent. An illustrative interface:

FUNCTION_BLOCK FB_Motor
VAR_INPUT
    Auto_Start    : BOOL;   (* request from sequence *)
    Man_Start     : BOOL;   (* operator start in manual *)
    Man_Stop      : BOOL;
    Auto_Mode     : BOOL;
    Permissive    : BOOL;   (* conditions required to start *)
    Interlock_OK  : BOOL;   (* conditions that force a stop *)
    Running_FB    : BOOL;   (* running feedback from contactor *)
    Overload_OK   : BOOL;
END_VAR
VAR_OUTPUT
    Run_Cmd       : BOOL;
    Fault         : BOOL;
    Fault_NoFB    : BOOL;   (* commanded but no feedback *)
END_VAR
VAR
    FB_Timer      : TON;    (* feedback supervision *)
END_VAR

Inside, the block handles modes, start/stop latching, interlocks, feedback supervision (a start command with no running feedback after a set time raises a fault) and reset. Test the block thoroughly once, then use instances everywhere.

4. Separate permissives from interlocks

Type Meaning Example
Permissive Must be true to start Suction valve open before the pump starts
Interlock Forces a stop when false Low suction level stops the pump

Keep interlocks in the PLC (never only in the HMI or SCADA), make them visible on the HMI faceplate, and implement safety functions in safety-rated systems rather than standard logic. See Functional Safety.

5. Write sequences as state machines

Sequences written with scattered latches become impossible to debug. Use an explicit step number or SFC:

CASE Step OF
    0:  (* Idle *)
        IF Start_Req AND All_Permissives THEN Step := 10; END_IF;
    10: (* Open inlet valve *)
        V101.Auto_Open := TRUE;
        IF V101.Opened THEN Step := 20; END_IF;
    20: (* Fill until high level *)
        P101.Auto_Start := TRUE;
        IF LSH THEN Step := 30; END_IF;
    30: (* Stop and close *)
        P101.Auto_Start := FALSE; V101.Auto_Open := FALSE;
        IF V101.Closed THEN Step := 0; END_IF;
END_CASE;

Add a step timeout for each step, a defined response to faults (hold or abort), and show the current step on the HMI. See PLC Programming Languages for SFC.

A Sequence as a State Machine (Illustrative): Step 0: Idle, Step 10, Step 20, Step 30
Explicit steps with timeouts make sequences easy to follow and debug.

6. Alarms and diagnostics

  • Every device block produces specific faults (no feedback, overload, discrepancy), not just “fault”.
  • Alarms have a clear cause and operator response; avoid alarms nobody acts on. See SCADA Alarm Management.
  • Show interlock and permissive status so operators know why something does not start.
  • Use the PLC’s system diagnostics (module and network faults) in the HMI.

7. Handle analog values carefully

  • Scale in one place, in a standard analog input block.
  • Detect out-of-range and wire break (for example 4–20 mA below 3.6 mA or above 21 mA per NAMUR NE 43) and set a quality flag.
  • Apply alarm deadbands and delays to avoid chattering.
  • Put PID loops in periodic tasks; see How PLCs Work and PID Control.

8. Design for failure and restart

  • Define output states for CPU stop, communication loss and power return.
  • Machines must not restart automatically after a power failure unless designed and assessed for it.
  • Use normally closed wiring for stop and overload signals.
  • Supervise communication with remote I/O, drives and other PLCs, and stop safely on loss.

9. Comment the why, not the what

(* Start pump *) above a start rung adds nothing. (* Pump must stop on low suction level to prevent dry running; see HAZOP item 12 *) explains a design decision. Comment every block interface, every interlock and every unusual piece of logic.

Common mistakes

Mistake Consequence Better practice
Writing the same output in several places Last write wins; confusing behaviour One place per output
Copy-pasted logic per device Inconsistent fixes, hidden bugs Standard function blocks
Magic numbers in logic Nobody knows what 1375 means Named constants and parameters
Interlocks only in the HMI Bypassed by other command sources Interlocks in the PLC
Forces left in place Interlocks silently defeated Remove forces; alarm on active forces
No timeouts in sequences Sequence hangs without explanation Step timeouts and fault steps
Unused and dead code left in Confusion during troubleshooting Remove or clearly disable it

Code review checklist

  • Program structured by equipment; naming convention followed
  • Standard blocks used for motors, valves and analog inputs
  • Each output written in one place
  • Permissives and interlocks implemented in the PLC and shown on the HMI
  • Safety functions in safety-rated systems
  • Sequences with step numbers, timeouts and fault handling
  • Analog inputs with range and wire-break detection
  • Fail-safe behaviour on stop, communication loss and power return defined and tested
  • No active forces; no debug code left
  • Comments explain design decisions
  • Program compared with the previous version; change recorded

Frequently asked questions

What makes a good PLC program?

Consistent structure and naming, reusable tested function blocks, clear interlocks and sequences, useful diagnostics, defined behaviour on failure, and comments that explain the reasons behind the logic.

Why should interlocks be in the PLC rather than the HMI?

Because commands can come from several places (HMI, SCADA, local panels, other PLCs). Only interlocks in the controller protect the equipment regardless of where the command comes from or whether the HMI is running.

How should PLC sequences be programmed?

As explicit state machines, with a step number or SFC, step timeouts, defined fault responses and the current step shown to the operator.

Key takeaways

  • Structure programs by equipment and name everything consistently.
  • Build and test standard function blocks once, then reuse them.
  • Keep interlocks in the PLC, write sequences as state machines and design for failure.
  • Review code against a checklist and record every change.

Before you apply this in a plant: this article is for education. Always check the current edition of the relevant standards, the manufacturer's documentation for your exact product and version, and your site's procedures. Safety-related work needs qualified personnel. See our editorial policy.

Written by Bhargava Reddy Kapireddy

Bhargava has 16 years of hands-on experience with MES, SCADA, DCS, PLC and industrial data systems across power generation, oil and gas, pharmaceuticals and process manufacturing. He founded MFG Tech Hub to share practical, vendor-neutral automation knowledge.

More about the author → How we write and review articles