Automation Systems · ASP ENGINEERING LIBRARY

PLC Programming Best Practices

In this article 11 sections

Writing reliable, maintainable PLC code is critical for industrial automation systems that must operate 24/7 in harsh environments. This guide covers established best practices for PLC programming using the IEC 61131-3 standard, with practical examples applicable to platforms from Siemens, Rockwell, Schneider Electric, and CODESYS-based controllers.

Conceptual control-system layers. Safety functions, communication paths, and redundancy must be designed for the application; the diagram is not a wiring or safety design.
Conceptual control-system layers. Safety functions, communication paths, and redundancy must be designed for the application; the diagram is not a wiring or safety design. View full size

IEC 61131-3 Programming Languages

The IEC 61131-3 standard defines five programming languages for industrial controllers. Choosing the right language for each task is the first step toward clean, maintainable code:

  • Ladder Logic (LD) — Best for discrete logic, interlocks, and sequences that mirror relay circuits. Widely understood by electricians and maintenance staff.
  • Function Block Diagram (FBD) — Ideal for continuous process control, PID loops, and signal processing. Visual representation of data flow between blocks.
  • Structured Text (ST) — A Pascal-like text language best suited for complex algorithms, data manipulation, calculations, and state machines.
  • Instruction List (IL) — Assembly-like language, now deprecated in IEC 61131-3 Ed. 4. Avoid for new projects.
  • Sequential Function Chart (SFC) — Excellent for batch sequences, step-based processes, and recipe management. Provides clear visualization of process phases.

Code Organization

Well-organized PLC code follows a modular architecture that separates concerns and enables independent testing:

  1. Organize by Function — Group related logic into Program Organization Units (POUs): one POU per motor, valve, or control loop.
  2. Use a Main Task Dispatcher — The main program should only call subroutines, never contain control logic directly.
  3. Separate Safety from Standard — Safety-related logic must reside in dedicated safety programs with clear boundaries.
  4. Layer Your Architecture — Field I/O to Signal Conditioning to Control Logic to Supervisory Setpoints to HMI Interface.

Naming Conventions

Consistent naming makes code self-documenting and searchable. Follow these conventions:

ElementConventionExample
VariablesPrefix + Area + Equipment + SuffixxP100_Motor01_Run
Prefix: BOOLx (input), y (output), b (internal)xSensor01, yValve01
Prefix: Analogi (input), q (output), r (real/internal)iTT101_PV, rSetpoint
ProgramsP_ + Area + FunctionP_Area01_Motors
Function BlocksFB_ + Equipment TypeFB_MotorControl
Constantsc_ + descriptive namec_MAX_SPEED

Error Handling Strategies

Robust PLC programs must handle faults gracefully. Implement these patterns:

  • Watchdog Timers — Monitor communication timeouts with field devices. If no response within the configured window, set a fault flag and revert to a safe state.
  • Range Checking — Validate all analog inputs against instrument range limits. Per NAMUR NE43, values below 3.6 mA or above 21.0 mA on a 4–20 mA signal indicate wiring faults or sensor failures. Values in the 3.6–3.8 mA and 20.5–21.0 mA ranges indicate cautionary zones requiring attention.
  • Interlock Prioritization — Safety interlocks must override operator commands. Implement as normally-closed (fail-safe) where possible.
  • State Machine Recovery — Every state machine must include an explicit ERROR state with diagnostic information and a defined recovery path.

Structured Text Example: Motor Control

The following Structured Text example demonstrates a reusable motor control function block with fault handling:

FUNCTION_BLOCK FB_MotorControl
VAR_INPUT
    xStart       : BOOL;       // Start command from HMI
    xStop        : BOOL;       // Stop command from HMI
    xFeedback    : BOOL;       // Running feedback from field
    xFaultReset  : BOOL;       // Fault reset command
    tStartDelay  : TIME := T#5S;  // Max time to wait for feedback
END_VAR
VAR_OUTPUT
    yRun         : BOOL;       // Output to motor starter
    xRunning     : BOOL;       // Confirmed running status
    xFault       : BOOL;       // Fault flag
    sFaultMsg    : STRING;     // Fault description
END_VAR
VAR
    xStartPrev   : BOOL;
    tonStart     : TON;
END_VAR

// Detect start command rising edge
xRisingEdge := xStart AND NOT xStartPrev;
xStartPrev := xStart;

// Start delay timer (watchdog)
tonStart(IN := xStartPrev AND NOT xFeedback, PT := tStartDelay);

// Motor output logic
IF xFault THEN
    yRun := FALSE;
ELSIF xStop THEN
    yRun := FALSE;
ELSIF xStartPrev THEN
    yRun := TRUE;
END_IF;

// Fault detection
IF tonStart.Q THEN
    xFault := TRUE;
    sFaultMsg := "Motor failed to start within timeout";
END_IF;

// Fault reset
IF xFaultReset AND xFault THEN
    tonStart(IN := FALSE);  // Reset the watchdog timer
    xFault := FALSE;
    sFaultMsg := "";
END_IF;

// Status output
xRunning := yRun AND xFeedback;

Testing and Debugging

Testing PLC code requires a different approach than software testing:

  1. Simulate First — Use the PLC vendor simulation environment to test logic before connecting to real hardware.
  2. Force I/O Carefully — Document all forced signals and remove them before commissioning. Use a force-register log.
  3. Test Fault Paths — Deliberately trigger each fault condition to verify alarm messages, safe-state behavior, and recovery procedures.
  4. Use Trend Recording — Record critical variables during testing to analyze timing, ramp rates, and loop performance.
  5. Peer Review — Have another engineer review control logic before deployment. ASP OTOMASYON enforces peer review on all safety-related code.

Commissioning Checklist

StepTaskStatus
1Verify all I/O point-to-point wiringPending
2Confirm signal conditioning and scalingPending
3Test all interlocks and safety functionsPending
4Validate alarm messages and prioritiesPending
5Tune PID loops (start with conservative gains)Pending
6Remove all forced I/O signalsPending
7Backup final program and document versionPending
8Train operators on new functionalityPending

Clean PLC code is not just about making it work — it is about making it maintainable for the next engineer who will modify it at 3 AM during a production outage.


References & Further Reading

  1. IEC 61131-3: Programmable Controllers — Programming Languages — International standard defining Ladder Diagram, Structured Text, Function Block Diagram, Sequential Function Chart, and Instruction List for PLC programming.
  2. Siemens TIA Portal Documentation — Official Siemens engineering framework for S7-1200/S7-1500 PLC programming with IEC 61131-3 language support.
  3. Rockwell Automation Studio 5000 Logix Designer — Official Rockwell Software for ControlLogix/CompactLogix PLC programming, configuration, and diagnostics.
  4. CODESYS Development System — Official IEC 61131-3 integrated development environment used by ABB AC500, Schneider Electric, and WAGO controllers.
  5. Schneider Electric EcoStruxure — PLC and SCADA Platform — Official documentation for Schneider Electric's PLC programming environment and industrial software ecosystem.

Make changes reviewable and recoverable

Keep the source project, controller firmware, library versions, and test evidence under a controlled release identifier. Define startup values, retained-state behavior, and recovery after interrupted communications. Test changes against both normal sequences and abnormal inputs in an approved environment. An online comparison is useful, but it does not replace a documented backup and a proven recovery procedure.

Continue with the related practical guide.

Apply this to your project

  • Define the process states, timing requirements, and permitted behavior after a controller or communication failure.
  • List controller, I/O, network, software, and license dependencies before choosing an architecture.
  • Record acceptance results and prove that the delivered configuration can be restored from the handover package.

Follow an ASP project guide to connect the fundamentals with implementation and acceptance.

Engineering review sequence: Requirements → Engineering → Acceptance → Handover. Keep the recorded evidence with the accepted configuration.
Engineering review sequence: Requirements → Engineering → Acceptance → Handover. Keep the recorded evidence with the accepted configuration. View full size

Primary references and further reading

Use the original specifications and product documentation for implementation details. The examples in this guide are illustrative engineering scenarios, not published project results.

Use this guide in context. Examples are engineering starting points. Confirm device documentation, site requirements, and acceptance criteria before implementation. How this library is maintained · Suggest a correction

FROM REFERENCE TO REAL PROJECT

Bring your next automation challenge.

PLC and DCS engineering, OPC connectivity, and digital transformation. Start with your installed systems, your constraints, and what you need to achieve.

Talk to ASP OTOMASYON