← Articles
Tags/7 min read/ views

Filtering a Noisy Analog Input Without Hiding the Process You Need to See

Smoothing a jittery 4-20 mA reading with first-order and moving-average filters, where the filter belongs, and why the wrong tag delays your alarm.

SCADATagsTroubleshootingHMICommissioning

The reading won't sit still

A vortex flow meter on a pump discharge reads 512, 488, 531, 497, 519 m³/h on consecutive scans. The flow is steady — the operator can hear the pump running flat — but the HMI number flickers ±4% and the trend looks like a seismograph. Someone opens a ticket: "flow meter faulty." It isn't. Vortex meters are noisy at the shedding frequency, the analog input has a bit of pickup, and a 250 ms scan is fast enough to catch every wobble. Nothing is broken. The signal just needs filtering.

Filtering is easy to add and easy to get wrong. Too little and the operator distrusts the number. Too much and you've buried a real process excursion under a smooth line that lags reality by ten seconds. The skill is not "which filter" — it's how hard and where.

First-order filter: one line, one knob

The workhorse is the first-order (exponential) low-pass filter. Discretely:

y = y + α * (x - y)     with   α = dt / (τ + dt)

x is the raw sample, y the filtered output, dt your scan interval, τ the filter time constant. That's it — one multiply, one subtract, one state variable per tag. Set τ, forget it.

The intuition that matters in the field: after a real step change, the filtered value reaches 63% of the way in one τ, 95% in three τ, and is essentially settled at five τ. So a τ of 2 s on a 250 ms scan (α ≈ 0.11) knocks the jitter down hard but means a genuine step in flow takes ~6 s before the trend shows most of it. That delay is not a side effect — it is the filter. You are trading noise rejection for response time, one for one.

I pick τ by asking how fast the real process moves. A tank level that changes over minutes tolerates τ = 10–30 s and looks glassy. A compressor surge signal that develops in under a second cannot take a 2 s filter at all — you'd smooth away the event. When unsure, start light (τ around 1–2 s) and increase only until the operator stops complaining. Over-filtering to make a screenshot look tidy is how excursions get missed.

Moving average vs. first-order

A moving average (boxcar) filter of N samples is the other common choice. It's flatter in some ways — every one of the last N samples counts equally — but it costs N stored samples per tag and has a blunter delay of about N·dt/2. For 20 samples at 250 ms that's a 2.5 s group delay plus the memory of a 20-deep ring buffer per point. Across a few thousand tags that adds up.

First-order wins for most SCADA work: cheaper, tunable with one number, and its exponential weighting means recent samples dominate, so it recovers from a real change faster than a boxcar of similar smoothing. I reach for a moving average only when I specifically want equal weighting — say, averaging a reading over one full pump cycle to report a cycle mean.

Neither of these rejects spikes well. A single wild sample — a 1 ms glitch that reads full-scale — drags both filters. If you're fighting isolated spikes rather than continuous noise, a small median filter (take the middle of the last 3 or 5 samples) throws the outlier out entirely and doesn't smear it into the average. Median first, then a light first-order, is a good combination for a signal that's both spiky and noisy.

Filter once, at the layer that owns the number

The mistake I see most: the same signal filtered three times over. The transmitter has damping set to 4 s, the PLC adds a first-order block, and then someone puts a smoothing filter on the SCADA trend pen because it still looked slightly busy. Each stage adds lag, and they compound. Now the operator is looking at a number that trails the process by fifteen seconds and nobody knows why the control loop hunts.

Decide once where the filter lives. My default is the transmitter's own damping if the value only feeds display and slow control — it's closest to the noise source and every downstream consumer gets the same clean number. Most HART transmitters expose a damping constant (often 0–32 s); set it there and leave the PLC and SCADA alone. If different consumers need different smoothing — a fast raw value for control, a slow one for the trend — filter in the PLC and publish two tags, clearly named, rather than re-filtering per screen. Whatever you choose, write it down. An undocumented filter is the reason a future engineer spends an afternoon chasing a lag that's working exactly as designed.

Don't filter the tag that feeds the trip

This is the one that bites. A first-order filter is a low-pass — it attenuates fast changes. A rate-of-change alarm, a high-high trip that needs to act quickly, and the derivative term of a PID loop all depend on fast changes. Filter the input to any of those and you've weakened the exact thing you built them for. A τ = 5 s filter ahead of a rate-of-change alarm can delay the alarm past the point where it was useful — see the [[rate-of-change-alarm-runaway-detection-notes]] for how much runaway you give away per second of lag.

The clean split: keep an unfiltered (or lightly median-filtered) copy of the signal for protection and rate logic, and filter only the copy that drives the display and the slow trend. For PID specifically, filter the derivative input if noise is making the output chatter — most controllers have a derivative filter parameter for exactly this — rather than filtering the whole PV and slowing your proportional response too.

And before you reach for any filter, check the historian side. If you're storing this tag with a compression deadband (see [[historian-deadband-and-compression-field-notes]]), filter before the deadband test. Feeding raw noise into swinging-door compression makes it store every jitter as a "significant" change — you get a fat archive full of noise and the deadband does nothing. A modest filter ahead of compression cuts stored events dramatically and the trend still tells the truth.

What to check when a filtered signal looks wrong

  • Trend lags the process during a known step (start a pump, watch level): time the delay. If it's near your τ or the boxcar group delay, the filter is fine — that's physics. If it's much longer, you're filtering more than once.
  • Alarm comes in late: confirm the alarm is reading the raw tag, not the display copy.
  • Number still jitters after filtering: the noise may be at your scan rate or slower — a filter can't remove noise slower than it responds. Look at wiring, grounding, and shield termination before turning τ up further.
  • Filtered value plateaus below a real reading: a τ set very high on a ramping signal will always trail; that's steady-state lag on a ramp, not a scaling error.

Filtering is a knob, not a fix. If the underlying signal is genuinely bad — a floating shield, a ground loop, a transmitter fighting VFD noise — a filter just hides the symptom while the real fault stays. Smooth the number after you've earned it, not instead of finding out why it moved.