Skip to content

32From the lab to the plant

An ST style guide: naming, comments, constants and version control

Code someone else can read in two years: naming conventions, comments that say why, short POUs, constants instead of magic numbers, Git for PLC code, and where OOP earns its place.

Lesson 32 of 3413 minIEC 61131-3

Who reads your code

Not the compiler. It is another engineer at 3 a.m. with the line down, and it may be you in two years. Everything in this lesson serves that moment.

Naming: a prefix that states the type

The convention usually called PLCopen style puts a short prefix on the name:

Prefix

Meaning

Example

b

BOOL

bPumpRun

i / di

INT / DINT

iStep, diBatchCount

r

REAL

rLevelPct

t

TIME

tFillTimeout

fb

function block instance

fbFillTimer

i_ / q_

field input or output signal

i_bLSH101, q_bPump101

Which convention you pick matters far less than picking one for the whole project and writing it on one page.

The naming that matters more: tags from the drawing

In a real plant the names are not yours, they come from the P&ID. The level on tank 101 is LT-101 on the drawing, on the cable label and on the HMI, so in the code it is LT_101 or LT101_PV. The usual ISA-5.1 pattern is a first letter for the measured variable and following letters for the function:

Tag

Meaning

LT-101

level transmitter

LSH-101

level switch high

LSL-101

level switch low

FT-102

flow transmitter

PT-103

pressure transmitter

P-101

pump

XV-104

on/off shutoff valve

LIC-101

level indicating controller

The payoff is immediate: the technician reads the alarm on the screen, finds the same tag in the field, and opens the same name in the code. No translation, no guessing.

Comments: say why, not what

A comment that repeats the code is a liability you now have to maintain twice:

(* Bad: sets the pump to TRUE *)
Pump := TRUE;

(* Good: the vendor requires 30 s between starts to protect
   the starter coil. Reference: P-101 manual page 14 *)
tRestartDelay := T#30s;

Comment the reason for a number, the document it came from, the decision that looks odd, and the failure that made you write the line. Never comment what the code already says.

Keep a POU short

If you have to scroll to see where an IF started, it is too long. Practical markers:

  • A POU fits in one or two screens.
  • One clear job per POU: FB_Motor runs a motor; it does not also build reports.
  • Repeated logic becomes a function block you instantiate, not a copy-paste.
  • Decisions live in one place: do not set Pump in three different spots.

No magic numbers

An 85.0 in the middle of the code tells nobody anything, and changing it means searching the whole project:

VAR CONSTANT
  LEVEL_FILL_SP   : REAL := 85.0;   (* % fill stop *)
  LEVEL_HI_ALARM  : REAL := 90.0;   (* % high level alarm *)
  FILL_TIMEOUT    : TIME := T#60s;  (* max fill time before fault *)
END_VAR

IF rLevelF >= LEVEL_FILL_SP THEN
  iStep := 2;
END_IF

Anything the operator should change at runtime becomes a setpoint in a RETAIN variable edited from the HMI. Anything that never changes becomes a CONSTANT. A number buried in an expression is neither.

Version control for PLC code

Station_v3_final_FINAL.zip has caused real incidents. What works:

  • A Git repository for the project, with ST exported as text files you can diff. Siemens, CODESYS and TwinCAT all export and import POUs as text.
  • Commit messages that say why: "raise fill timeout to 90 s after the smaller pump was fitted".
  • A tag for every version actually downloaded to a controller, with the date and the site. That is what an incident investigation will ask for.
  • A backup of the whole project, not just the text: hardware, network and module configuration.
  • A printed change log in the panel: who downloaded what, and when.

A word on OOP in IEC 61131-3

The third edition added METHOD, PROPERTY, INTERFACE, EXTENDS and IMPLEMENTS to the function block. CODESYS and TwinCAT support them well; other platforms partly or not at all.

When does it earn its place?

  • It earns it when you are building a library for twenty similar machines: FB_ValveBase with FB_ValveDigital and FB_ValveAnalog extending it, and an I_Device interface offering Start, Stop and GetState so the station logic is written once.
  • It does not on a station with two pumps and a valve. The abstraction costs more reading time than it saves, and the maintenance technician will not follow it.

And the rule that does not bend: if the code is handed to a maintenance team that does not think in objects, you are writing a future problem rather than an engineering solution. Clarity beats elegance every time.

Try it in the lab

The lab runs in your browser: an ST editor, a virtual process that suits the lesson, the same program as a live ladder diagram, a watch table, and export to Siemens SCL.

What to try

  1. Run the program and tap PED BUTTON: the request is held in bRequest, and after the minimum green it goes amber, then red with walk.
  2. Change tWalk to T#8s in its declaration only and download again: the whole program uses the new value.
  3. Notice the prefixes: t for time, b for Boolean, i for integer, fb for a block. Read any line and you know each name's type without scrolling up.

People find this lesson by searching

plc naming conventionsPLCopen naming conventionplc code comments best practiceCONSTANT structured textgit for plc codeOOP IEC 61131-3 METHOD INTERFACEstructured text best practices

Course outline

  1. 01What is Structured Text, and when to use it instead of ladder
  2. 02How a PLC runs your code: the scan cycle and the process image
  3. 03Program structure: POUs, PROGRAM, FUNCTION and FUNCTION_BLOCK
  4. 04Your first program: starting a pump with seal-in logic
  5. 05Data types: BOOL, INT, REAL, TIME and the rest
  6. 06Declaring variables: VAR, VAR_INPUT and RETAIN
  7. 07Literals and constants: 16#FF, 2#1010 and T#5s
  8. 08Type conversion and scaling a 4-20 mA signal
  9. 09Assignment and arithmetic in ST: := and operator precedence
  10. 10Boolean logic, comparisons and bit operations
  11. 11Standard functions: ABS, SQRT, MIN, MAX, LIMIT, SEL, MUX
  12. 12IF, ELSIF and ELSE: the rules and when to avoid them
  13. 13The CASE statement and your first state machine
  14. 14The FOR loop and the watchdog
  15. 15WHILE, REPEAT, EXIT, CONTINUE and RETURN
  16. 16Edge detection: R_TRIG, F_TRIG and the "it fired every scan" bug
  17. 17Timers: TON, TOF and TP
  18. 18Counters: CTU, CTD and CTUD
  19. 19SR and RS flip-flops: which one wins
  20. 20Writing your own function
  21. 21Writing a function block
  22. 22Arrays in Structured Text
  23. 23Structs and enumerations
  24. 24References and pointers
  25. 25The state machine pattern: a batch sequence that cannot get stuck
  26. 26Alarm management to ISA-18.2: delay, deadband, latch, acknowledge, first-out
  27. 27Analogue signal processing: counts to engineering units, NE43 and filtering
  28. 28Closed-loop control in ST: hysteresis first, then a practical PID
  29. 29Motors and valves in practice: permissives, feedback and travel time
  30. 30The same ST on every platform: SCL, Studio 5000, CODESYS, TwinCAT
  31. 31Testing and debugging ST: the watch table, forcing and simulation
  32. 32An ST style guide: naming, comments, constants and version control
  33. 33Final project: a complete tank station with a state machine and alarms
  34. 3420 interview questions on ST and PLC programming, with answers