33. PLC Programming Best Practices: Structure, Tags, Comments, and Troubleshooting ( 33 of 35 )


0
PLC Programming Best Practices

A PLC program should not only make the machine run.

A good PLC program should also be:

Easy to understand
Easy to troubleshoot
Easy to modify
Easy to document
Easy to recover
Safe to maintain
Consistent for the whole automation team

In real industrial automation, the person troubleshooting the machine at 2:00 AM may not be the person who wrote the program.

That is why structure, tag names, comments, documentation, and clear logic matter.

A PLC structure guide explains that before programming, the technician or programmer should understand the machine operation and prepare key information such as I/O lists, alarms, external devices, communication protocols, sequences of operation, and hardware lists. The same guide states that the main objective of program organization is to make a machine easier to troubleshoot and modify.


Why Best Practices Matter

A messy PLC program can technically work.

But when the machine fails, a messy program makes troubleshooting slow and painful.

Bad program symptoms:

No comments
Confusing tag names
Duplicate output coils
No input mapping
No output mapping
Faults scattered everywhere
HMI writes directly to output bits
Manual logic mixed with auto logic
No clear sequence state
No current step display
No clear reset logic
No documentation

Good programming practices reduce downtime because they help the technician find the problem faster.

Simple idea:

Good logic runs the machine.
Great logic helps troubleshoot the machine.

1. Start with Machine Understanding

Before writing logic, understand what the machine is supposed to do.

Ask:

What is the normal cycle?
What are the machine modes?
What starts the cycle?
What stops the cycle?
What are the safety conditions?
What are the permissives?
What are the interlocks?
What are the faults?
What devices need feedback?
What does the HMI need to display?
What communicates with the PLC?

Do not start by creating random rungs.

Start by understanding the machine.


2. Create an I/O List First

An I/O list is one of the most important programming documents.

It should include:

Input name
Output name
PLC address
Module slot
Terminal number
Wire number
Device description
Voltage type
NO/NC behavior
PNP/NPN type
Field location
Drawing reference

Example:

TypeTag NameAddressDescription
DIDI_Box_Present_PELocal:1:I.Data.0Box present photoeye
DIDI_Air_Pressure_OKLocal:1:I.Data.1Air pressure switch healthy
DODO_Conveyor_RunLocal:2:O.Data.0Conveyor motor run command
DODO_Valve_OpenLocal:2:O.Data.1Fill valve open solenoid

A good I/O list connects the physical machine to the PLC program.


3. Use a Clean Program Structure

A professional PLC program should be divided into logical sections.

A common structure:

1. Input Mapping
2. Signal Conditioning / Debounce
3. HMI Commands
4. Mode Selection
5. Permissives
6. Interlocks
7. Fault Logic
8. Alarm Logic
9. Auto Sequence
10. Manual Control
11. Device Control
12. Output Mapping
13. HMI Status

This makes troubleshooting easier because the technician knows where to look.

Example:

Input problem?      Go to Input Mapping.
Output problem?     Go to Output Mapping.
Machine stuck?      Go to Auto Sequence.
Fault active?       Go to Fault Logic.
HMI issue?          Go to HMI Commands or HMI Status.

Industrial automation programming material also describes organizing PLC software with tasks, programs, and subroutines, commonly separating inputs, outputs, sequences, faults, and system or mode control into different routines.


4. Separate Inputs from Logic

Do not use raw physical inputs everywhere in the program.

Better:

Raw Input → Buffered Input Tag → Logic

Example:

Local:1:I.Data.0 → DI_Box_Present_PE

Then use:

DI_Box_Present_PE

throughout the program.

Why?

Because if the input address changes later, you only update the mapping rung.

Bad practice:

Use Local:1:I.Data.0 directly in 20 different routines.

Good practice:

Map Local:1:I.Data.0 once to DI_Box_Present_PE.
Use DI_Box_Present_PE everywhere else.

5. Separate Outputs from Logic

Do not energize physical outputs all over the program.

Better:

Logic Command → Output Mapping → Physical Output

Example:

Conveyor_Run_Command → DO_Conveyor_Run

This gives the technician a clean place to verify:

Is the PLC logic requesting the device?
Is the physical output being mapped?
Is the output module turning ON?

Bad practice:

Multiple rungs write directly to DO_Conveyor_Run.

Good practice:

Only one rung maps Conveyor_Run_Command to DO_Conveyor_Run.

6. Use Clear Tag Names

Tag names should explain what the signal means.

Bad tag names:

B3:0/1
Motor1
Input_3
Sensor_A
Bit_55
Flag1

Better tag names:

DI_Box_Present_PE
DI_Air_Pressure_OK
DI_Conveyor_Motor_FB
DO_Conveyor_Run
DO_Reject_Solenoid
HMI_Start_PB
HMI_Reset_PB
Machine_Auto_Mode
Conveyor_Run_Command
Conveyor_Failed_To_Start_Fault

The source material explains that consistent naming conventions make tags easier to locate in the tag database, especially because tag editors often list names alphabetically. It also recommends grouping related tags by naming pattern, such as hardwired inputs and outputs or by major equipment area.


7. Use Prefixes Consistently

Good prefixes make tags easier to scan.

Example prefix system:

PrefixMeaning
DI_Digital input
DO_Digital output
AI_Analog input
AO_Analog output
HMI_HMI command or setpoint
CMD_Internal command
FB_Feedback
FLT_Fault
ALM_Alarm
SP_Setpoint
PV_Process value
T_Timer
C_Counter

Example:

DI_Guard_Door_Closed
DO_Conveyor_Run
AI_Tank_Level_Raw
PV_Tank_Level_Percent
HMI_Speed_Setpoint
FLT_Valve_Failed_To_Open
ALM_Low_Air_Pressure

This is not the only valid style, but the key is consistency.


8. Comment the Logic

Comments should explain the purpose of the rung.

Bad comment:

Motor logic

Better comment:

Start Conveyor 1 when Auto Mode is active, all permissives are healthy, no conveyor fault is latched, and the current sequence step requires product movement.

Good comments help the next technician understand the intent.

Comment these areas carefully:

Mode selection
Permissives
Interlocks
Fault logic
Reset logic
Auto sequence transitions
Manual controls
HMI commands
Communication logic
Analog scaling
Safety status

A program may work without comments, but it will be harder to maintain.


9. Show Command and Feedback Separately

This is one of the most important real-world concepts.

Command means:

PLC wants the device to operate.

Feedback means:

The device proved it actually operated.

Example:

DeviceCommandFeedback
ConveyorConveyor_Run_CommandDI_Conveyor_Running_FB
ValveValve_Open_CommandDI_Valve_Open_FB
CylinderCylinder_Extend_CommandDI_Cylinder_Extended_LS
VFDVFD_Run_CommandVFD_Running_FB

Do not assume command equals action.

A good program detects:

Command ON
Feedback not received in time
Fault = Device failed to start / move / open

10. Build Fault Logic with Timeouts

Every commanded motion should have feedback or a timeout when practical.

Example:

Command valve open.
Start timer.
If valve open feedback does not turn ON before timer done,
latch Valve_Failed_To_Open_Fault.

This prevents the machine from waiting forever.

Good fault logic should include:

Fault condition
Fault timer
Fault latch
Fault reset condition
HMI alarm message
Device status
Troubleshooting clue

Example tag names:

FLT_Valve_Failed_To_Open
T_Valve_Open_Timeout
DI_Valve_Open_FB
DO_Valve_Open

11. Separate Faults and Alarms

A fault usually affects machine operation.

An alarm is a message to the operator.

Example:

Fault:
Conveyor failed to start.

Alarm:
Conveyor 1 failed to start — check overload, VFD ready, and motor feedback.

Good design:

Fault logic latches the fault.
Alarm logic displays useful message.
Reset logic clears fault only when condition is safe/healthy.

Do not only display “Fault 12” unless the HMI has a clear description.


12. Use Machine States or Steps

For sequences, use a clear state or step number.

Example:

Machine_Step = 0    Idle
Machine_Step = 10   Wait for Product
Machine_Step = 20   Conveyor Run
Machine_Step = 30   Fill
Machine_Step = 40   Reject Check
Machine_Step = 50   Cycle Complete
Machine_Step = 90   Faulted

This helps troubleshooting because the technician can ask:

What step is active?
What output should be ON in this step?
What feedback is missing?
What condition moves it to the next step?

Using step numbers like 10, 20, 30 makes it easier to insert future steps later.


13. Keep Manual and Auto Logic Clear

Manual mode and Auto mode should not be mixed randomly.

Manual mode should allow controlled device operation.

Auto mode should follow sequence logic.

Example:

Manual command:
HMI_Manual_Valve_Open

Auto command:
Auto_Valve_Open_Command

Final command:
Valve_Open_Command = Manual_Allowed_Command OR Auto_Allowed_Command

But both should still respect important interlocks.

Example:

Valve_Open_Command requires:
Air_Pressure_OK
No_EStop
No_Valve_Fault
Not conflicting with Valve_Close_Command

Manual mode should help maintenance, not bypass machine protection carelessly.


14. Validate HMI Commands and Setpoints

The HMI should request actions.

The PLC should validate them.

Bad practice:

HMI writes directly to DO_Motor_Run.

Better practice:

HMI_Start_PB → PLC checks conditions → Motor_Run_Command → DO_Motor_Run

The source material warns against letting both HMI objects and PLC logic write to the same data point because this can create conflicts similar to duplicate coils. It also states that PLC input data points linked to real-world inputs should normally be read-only to the HMI.


15. Avoid Duplicate Coils and Duplicate Writes

A duplicate coil means the same bit or output is written in multiple places.

Example:

Rung 10 controls DO_Pump_Run.
Rung 45 also controls DO_Pump_Run.
Rung 80 unlatches DO_Pump_Run.

This becomes hard to troubleshoot.

Better:

Build Pump_Run_Command from all required conditions.
Map Pump_Run_Command to DO_Pump_Run once.

Good structure:

Requests
Permissives
Interlocks
Faults
Command
Output Mapping

One physical output should have one final mapping location.


16. Use One-Shots Where Needed

Some actions should happen only once.

Examples:

Load recipe
Reset counter
Advance sequence step
Capture fault code
Start batch
Trigger message
Shift register movement

Use one-shots for event-based logic.

Without one-shot logic, one button press or one input may execute for multiple PLC scans.

Example:

HMI_Load_Recipe_PB → One-Shot → Load Recipe Values

This prevents the recipe from being loaded every scan while the button is held.


17. Be Careful with Latches

Latch/unlatch logic is useful, but it must be controlled.

Good use cases:

Fault latch
Mode selection
Cycle active
Alarm active
Manual stop latch

Poor latch logic can cause:

Machine stays stuck
Fault will not reset
Output remains ON unexpectedly
Mode does not change
Hidden condition blocks operation

For every latched bit, ask:

What turns it ON?
What turns it OFF?
Is reset safe?
Is the HMI showing its status?
Is it documented?

18. Make Troubleshooting Visible on the HMI

A good PLC program should send useful status to the HMI.

Useful HMI diagnostic tags:

Machine_State
Machine_Step
Machine_Ready
Permissives_OK
Interlocks_OK
Fault_Active
Alarm_Active
Current_Fault_Code
Current_Fault_Message
Safety_OK
Air_Pressure_OK
VFD_Ready
VFD_Fault_Code

Instead of only showing:

Machine Faulted

show:

Machine Faulted — Conveyor 1 Failed To Start
Check overload, VFD ready, and motor feedback.

This reduces downtime.


19. Keep Analog Scaling Documented

Analog scaling should be easy to understand.

Document:

Raw min
Raw max
Engineering min
Engineering max
Units
Transmitter range
Scaling formula
Alarm setpoints
Signal fault range

Example:

AI_Pressure_Raw
Pressure_PSI
4–20 mA = 0–100 PSI
High alarm = 90 PSI
Low alarm = 10 PSI
Signal fault < 3.5 mA or > 21 mA

Bad analog documentation causes wrong HMI values and bad troubleshooting.


20. Use Consistent Reset Logic

Reset logic should be clear.

A reset should usually:

Clear fault latch if fault condition is gone
Clear alarm acknowledge if needed
Reset timers/counters if appropriate
Return machine to safe idle state if required

A reset should not:

Force outputs ON
Bypass safety
Hide an active fault
Clear root cause without condition being healthy
Unexpectedly restart machine

Important rule:

Reset clears the fault status.
Start command restarts the machine.

Reset and start should not be the same action.


21. Use Routine Order Intentionally

Scan order matters.

Example:

Input Mapping first
Logic in the middle
Output Mapping last

This makes sense because:

First, read what the machine is doing.
Second, decide what should happen.
Third, command the outputs.

A clean main routine may call:

JSR Input_Mapping
JSR HMI_Commands
JSR Mode_Selection
JSR Permissives
JSR Interlocks
JSR Fault_Logic
JSR Auto_Sequence
JSR Manual_Control
JSR Device_Control
JSR Output_Mapping
JSR HMI_Status

This gives the program a predictable flow.


22. Make the Program Easy to Modify

Machines change.

A good program should allow future changes without destroying the structure.

Examples:

Add a new sensor
Add a new fault
Add a new HMI indicator
Add a new product recipe
Add a new sequence step
Replace a VFD
Add remote I/O
Add SCADA data collection

If the program is organized, future changes are safer and faster.

If the program is messy, every change becomes risky.


23. Avoid “Mystery Bits”

A mystery bit is a tag that affects logic but nobody knows why.

Examples:

B3:12/7
Temp_Bit_3
Test_Only
Bypass1
Flag_X
Old_Mode

If a bit is important, give it a meaningful name and comment.

Example:

Manual_Stop_Latched
Recipe_Load_Request
Conveyor_Start_Permissive
Valve_Open_Timeout_Done

Mystery bits are one of the biggest enemies of troubleshooting.


24. Good Tag Examples

Inputs
DI_Start_PB
DI_Stop_PB_OK
DI_EStop_OK
DI_Box_Present_PE
DI_Valve_Open_FB
DI_Conveyor_Running_FB
DI_Air_Pressure_OK
Outputs
DO_Conveyor_Run
DO_Valve_Open
DO_Valve_Close
DO_Reject_Solenoid
DO_Alarm_Horn
DO_Green_StackLight
Commands
Conveyor_Run_Command
Valve_Open_Command
Reject_Solenoid_Command
Cycle_Start_Request
Cycle_Stop_Request
Faults
FLT_Conveyor_Failed_To_Start
FLT_Valve_Failed_To_Open
FLT_Low_Air_Pressure
FLT_Box_Jam
FLT_VFD_Faulted
HMI
HMI_Start_PB
HMI_Stop_PB
HMI_Reset_PB
HMI_Auto_Mode_Select
HMI_Speed_Setpoint
HMI_Recipe_Select

25. Best Practice Troubleshooting Structure

A strong program helps the technician follow this chain:

Input → Condition → Command → Output → Feedback → Fault/Alarm

Example:

DI_Start_PB
AND Machine_Ready
AND Permissives_OK
AND Interlocks_OK
AND NOT Faulted
→ Conveyor_Run_Command
→ DO_Conveyor_Run
→ DI_Conveyor_Running_FB
→ If feedback missing, FLT_Conveyor_Failed_To_Start

That chain is easy to troubleshoot.


Common Programming Mistakes

1. No Input or Output Mapping

Raw I/O addresses are scattered everywhere.

Result:

Harder to modify and troubleshoot.

2. Duplicate Output Coils

Same output is controlled in multiple locations.

Result:

Output behavior becomes confusing.

3. HMI Writes Directly to Outputs

Operator screen bypasses PLC decision logic.

Result:

Unsafe or unpredictable behavior.

4. Poor Tag Names

Technician cannot understand what the bit represents.

Result:

Longer troubleshooting time.

5. No Fault Timeouts

Sequence waits forever.

Result:

Machine stuck with no useful alarm.

6. No Current Step Display

Technician does not know where the sequence stopped.

Result:

Harder to find missing condition.

7. Reset Logic Clears Too Much

Reset clears important diagnostic information before the technician can investigate.

Result:

Root cause gets hidden.

PLC Programming Best Practices Checklist

1. Understand machine operation before programming.
2. Create I/O list.
3. Create device list.
4. Create alarm/fault list.
5. Create sequence description.
6. Use input mapping.
7. Use output mapping.
8. Use clear tag names.
9. Use consistent prefixes.
10. Add useful rung comments.
11. Separate manual and auto logic.
12. Separate commands and feedback.
13. Add feedback timeouts.
14. Use fault latches intentionally.
15. Show current machine step.
16. Validate HMI commands.
17. Protect HMI setpoints with limits.
18. Avoid duplicate coils.
19. Use one-shots for events.
20. Document analog scaling.
21. Keep reset logic clear.
22. Save backups before changes.
23. Update change log after changes.
24. Make troubleshooting visible on HMI.

Automation Technician Notes

For an Automation Technician, programming best practices are not just for engineers.

They help you troubleshoot faster.

When you open a PLC program, look for:

Where are the inputs mapped?
Where are outputs mapped?
What command controls this device?
What feedback proves it worked?
What fault blocks it?
What sequence step is active?
What HMI command is involved?
Is anything forced?
Is anything duplicated?

A well-structured PLC program answers these questions quickly.


Key Terms
TermMeaning
Input MappingCopying raw input addresses into readable internal tags
Output MappingAssigning internal commands to physical output addresses
Tag NameDescriptive name for a PLC memory point
Rung CommentExplanation of what a rung does
CommandPLC request for a device to operate
FeedbackProof that the device actually operated
PermissiveRequired condition before an action is allowed
InterlockCondition that blocks an action
Fault TimeoutTimer used to detect missing feedback
Sequence StepCurrent stage of machine operation
One-ShotSingle-scan pulse for event logic
Duplicate CoilSame output/bit written in more than one place
HMI CommandOperator request from HMI to PLC
Reset LogicLogic used to clear faults or return to ready state

Final Thoughts

A good PLC program is not only about making the machine run.

It is about making the machine understandable.

The best programs help the technician answer:

What does the PLC see?
What does the PLC want?
What is blocking the action?
What output is commanded?
What feedback is missing?
What fault explains the problem?

The professional mindset is:

Write logic for control.
Structure logic for troubleshooting.
Comment logic for the next technician.
Document logic for the future.

A machine that runs is good.

A machine that can be quickly understood, diagnosed, and safely maintained is much better

Leave a Reply

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