Skip to content

20Structured programs

Writing your own function

How to declare your own FUNCTION such as Scale4to20, what purity means, and why one declaration replaces twenty copies of the same equation.

Lesson 20 of 3410 minIEC 61131-3

The problem: the same equation in twenty places

On a station with twenty analogue transmitters you copy this line twenty times with different numbers:

Flow := (RawFlow - 4.0) / 16.0 * 250.0;
Pres := (RawPres - 4.0) / 16.0 * 10.0;

In one of them you type 16.0 where 4.0 belonged, a reading is wrong, and you spend three days finding it. The fix is to write the equation once, in a function.

Declaring one

FUNCTION Scale4to20 : REAL
VAR_INPUT
  Raw   : REAL;   (* 4.0 .. 20.0 mA *)
  EngLo : REAL;
  EngHi : REAL;
END_VAR

Scale4to20 := EngLo + (Raw - 4.0) / 16.0 * (EngHi - EngLo);

END_FUNCTION

Three things to notice:

  1. The type follows the name: FUNCTION Scale4to20 : REAL means it returns a REAL.
  2. Inputs live in VAR_INPUT: read-only inside the body.
  3. You return by assigning to the function's own name: Scale4to20 := .... That is the standard syntax; there is no return keyword.

Calling it

Flow := Scale4to20(RawFlow, 0.0, 250.0);
Pres := Scale4to20(RawPres, 0.0, 10.0);
Temp := Scale4to20(RawTemp, -50.0, 200.0);

Or by name, which reads better in review:

Flow := Scale4to20(Raw := RawFlow, EngLo := 0.0, EngHi := 250.0);

Purity: no memory, no side effects

A function is pure: the same inputs always give the same result, and nothing is remembered between calls. That means:

  • No timers and no counters inside it. A TON needs memory, so it belongs in a FUNCTION_BLOCK.
  • Local VAR values inside a function are undefined at the start of each call. Never rely on them.
  • Do not write to a global from inside a function. Some platforms let you, but it makes the result depend on the program's history, which is exactly what you were avoiding.

When do you need a FUNCTION_BLOCK instead? When the answer to "does it need to remember anything from the previous scan?" is yes.

Functions worth writing

  • Scale4to20 and ScaleRaw: engineering-unit conversion.
  • DeadbandPct: a deadband around a setpoint.
  • CelsiusToF, BarToPsi: unit conversion.
  • ClampPct: hold a value between 0 and 100 and flag the overshoot.

Each is reviewed once, tested once, and correct everywhere after that.

Not runnable in the lab

The lab on this site runs a single PROGRAM and does not support declaring a FUNCTION. The examples above are code to read, not to run. The lab program below does the same maths inline so you can watch the numbers move.

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, press START and watch Percent, DegC and Bar follow the level.
  2. Notice the same formula written three times; on a real PLC it becomes FUNCTION Scale, called three times.
  3. Change the temperature span 120.0 to 200.0 in the second line only, and notice you edited one place out of three: that is the mistake a function prevents.

People find this lesson by searching

user defined function structured textFUNCTION declaration plcscale 4-20mA structured textVAR_INPUT functionstructured text function return valuepure function plcreusable plc code

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