Skip to content

27Industrial patterns

Analogue signal processing: counts to engineering units, NE43 and filtering

The whole analogue input chain: raw counts to engineering units, 4-20 mA scaling, NAMUR NE43 fault bands, an EMA filter, and a rate-of-change limit that catches a failing sensor.

Lesson 27 of 3414 minIEC 61131-3

What arrives is not a value

An analogue input does not hand you "52.3%". It hands you counts: an integer from an ADC. And every vendor counts differently:

Family

0-100% range

Note

Siemens S7

0 … 27648

up to 32511 for over-range

Rockwell / Allen-Bradley

0 … 32767

or a pre-scaled value

Beckhoff / CODESYS

0 … 32767

configurable

12-bit converter

0 … 4095

on simple cards

27648 is not arbitrary: it is 1.25 × 22118, and the headroom up to 32511 exists because a transmitter can legitimately send more than 20 mA.

The 4-20 mA loop

Field zero is 4 mA, not zero. That is the live zero, and the reason is diagnostic: if the wire breaks the current is zero, zero is not a valid reading, so you know you have a fault. With 0-10 V you cannot tell "zero" from "cut".

mA  := 4.0 + Counts * 16.0 / 27648.0;
Eng := (mA - 4.0) * 100.0 / 16.0;

Or straight to a general form for any range:

Eng := EngMin + (Counts - CntMin) * (EngMax - EngMin) / (CntMax - CntMin);

Write the constants with a decimal point (16.0, not 16) or you do integer division and throw the fraction away.

NAMUR NE43: the current tells you its own health

NAMUR NE43 splits the loop into bands, and it is now general industrial practice:

Current

Meaning

below 3.6 mA

fault: broken wire or dead transmitter

3.6 … 3.8 mA

transition band

3.8 … 20.5 mA

valid measurement, including over-range

20.5 … 21.0 mA

transition band

above 21.0 mA

fault: short circuit or failed transmitter

So do not test "is this value plausible?". Test the current, before scaling. And put a short on-delay on the fault, because an electrical transient is not a failed sensor.

The EMA filter

An exponential moving average is one line, and its memory is one variable:

Filt := Filt + Alpha * (Eng - Filt);

Alpha is between 0 and 1. One means no filter, 0.05 is heavy. The relation to a time constant:

Alpha ≈ Ts / (Tau + Ts)

At a 50 ms scan, Alpha = 0.15 gives roughly a 280 ms time constant. Rule of thumb: light filtering on level and pressure, heavier on flow, and almost none on anything feeding safety logic, because a filter delays.

The rate-of-change limit

This is the strongest way to catch a sensor failing inside its valid band. Ask what the process can physically do. In this lab the pump moves the level 6% per second, so a 40%-per-second jump is not process, it is a wire or a loose terminal.

Slope := ABS(Eng - Prev) / Ts;
IF Slope > 40.0 THEN
  (* do not feed the filter; hold the last good value *)
END_IF;

Order matters

Counts, NE43 check, engineering units, rate limit, filter, logic. Never filter before you validate: the filter hides the fault and makes a broken wire look like a dignified slow decline.

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 watch mA, Eng and Filt side by side while the tank cycles between 30 and 85%.
  2. Notice Filt trailing Eng slightly: that is the filter.
  3. Hold STOP: mA drops to 0, Bad raises the alarm, the pump stops safely and Eng holds its last good value.
  4. Change Alpha to 0.5, then to 0.01, and compare.

Terms in this lesson

People find this lesson by searching

4-20mA scaling plc structured textanalog input scaling plcNAMUR NE43 fault bandsraw counts to engineering unitsexponential moving average filter plcsensor fault detection plcrate of change limit plcsiemens 27648 analog scaling

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