s7-SCL-scripts/realcaces.md
2026-02-20 13:07:12 +01:00

762 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🏭 Real Industrial Case Scenarios
## S7-1500 Advanced Signal Filtering — Where Theory Meets the Shop Floor
> *"Every filter exists because someone, somewhere, had a bad day with a noisy sensor."*
---
## 📋 Quick Navigation
| Filter | Industry Focus | Go To |
|--------|---------------|-------|
| 🔵 Simple Moving Average | Food, Steel, Energy, Packaging | [→ Jump](#-simple-moving-average-sma) |
| 🟢 Exponential Moving Average | Pharma, Chemicals, Robotics | [→ Jump](#-exponential-moving-average-ema) |
| 🟡 Weighted Moving Average | Automotive, AGV, Batch | [→ Jump](#-weighted-moving-average-wma) |
| 🔴 Median Filter | Mining, Oil & Gas, Filling Lines | [→ Jump](#-median-filter) |
| ⚪ Rate Limiter | Valves, Drives, HVAC, Robotics | [→ Jump](#-rate-limiter) |
| 🔗 Stacked Combinations | Advanced multi-filter chains | [→ Jump](#-stacking-filters--real-combinations) |
---
## 🔵 Simple Moving Average (SMA)
> **Best when:** Response speed is not critical, noise is continuous and random, and accuracy over time matters more than tracking every fluctuation.
---
### Case 1 — Agitated Chemical Reactor | Tank Level
**Industry:** Chemical / Pharma
**Signal:** Ultrasonic level sensor, 0100%
```
Plant: 10,000L reactor vessel, bottom-mounted agitator, 60 RPM
Problem: Agitator creates surface turbulence → level signal bouncing ±35%
The level is used for batch recipe decisions, NOT fast control
Decision threshold: "Add ingredient B when level < 40%"
```
**Without filter:**
```
Raw signal: 38.2 → 42.7 → 37.9 → 43.1 → 38.5 → 41.9 → 37.4
Result: Ingredient B added and stopped repeatedly every few seconds
→ Recipe out of spec, batch rejected, €12,000 loss
```
**With SMA (window = 30):**
```
Filtered: 40.1 → 40.0 → 39.9 → 39.8 → 39.7 → 39.6 → 39.5
Result: One clean crossing of 40% threshold, ingredient added once
→ Batch in spec ✓
```
**Configuration:**
```pascal
arAlarmDefs[0].iWindowSize := 30; // 30 × 100ms = 3 second averaging window
// At 100ms cycle, window of 30 covers 3 full agitator revolutions (60RPM)
// One revolution = 1 second → three full cycles averaged out
```
---
### Case 2 — Multi-Zone Furnace | Temperature Averaging
**Industry:** Steel / Heat Treatment
**Signal:** 8× Type-K thermocouples, 01200°C
```
Plant: Roller hearth furnace, 12 meters long, 8 thermocouples in roof
Problem: Natural hot/cold spots exist between burner zones
Single sensor reading causes burner to hunt unnecessarily
Parts exit furnace under-soaked (hardness out of spec)
```
**Signal architecture with SMA:**
```
TC_1 (820°C) ──→ SMA(20) ──→ 819.4°C ──┐
TC_2 (835°C) ──→ SMA(20) ──→ 834.1°C ──┤
TC_3 (811°C) ──→ SMA(20) ──→ 812.3°C ──┤→ AVERAGE → 822.1°C → PID
TC_4 (828°C) ──→ SMA(20) ──→ 827.8°C ──┤
... ┘
```
**Result:** PID controls to true chamber average, not a single sensor's local reading. Part hardness variation dropped from ±4 HRC to ±1.2 HRC.
---
### Case 3 — Energy Metering | Power Consumption Dashboard
**Industry:** Automotive Assembly
**Signal:** Power transducer, 0500 kW
```
Plant: Body shop production line, 47 servo drives, 12 robots
Problem: Motor inrush currents cause 50200ms spikes on power reading
Every robot start = false spike in energy log
Monthly energy report showing 15% higher consumption than reality
Triggering false demand charge penalties from utility
```
**Raw vs filtered at robot start:**
```
Time(ms): 0 50 100 150 200 250 300 350
Raw (kW): 120 340 280 380 150 125 122 121 ← inrush spikes
SMA (kW): 120 128 138 152 158 154 148 140 ← smooth energy trend
```
**SMA window sizing:**
```pascal
// Robot start inrush lasts ~200ms
// At 50ms OB cycle → window of 10 covers 500ms (absorbs full inrush + settle)
iWindowSize := 10;
// Result: SCADA energy logging uses SMA value
// Inrush events invisible to billing system
// Annual saving: €18,000 in false demand charges
```
---
### Case 4 — Dynamic Checkweigher | Food Packaging Line
**Industry:** Food & Beverage
**Signal:** Load cell, 0500g
```
Plant: Biscuit packaging line, 120 packs/minute
Problem: Belt vibration, product impact, conveyor joints all corrupt load cell
Products weigh ~250g, tolerance ±5g (legal requirement)
False rejects running at 8% — should be <1%
Each false reject = wasted product + manual check labor
```
**Timing-matched window:**
```
Belt speed: 0.8 m/s
Product length: 160mm
Transit time: 160mm / 800mm/s = 200ms
OB cycle: 10ms
Window size: 200ms / 10ms = 20 samples
→ SMA window of 20 averages exactly one product transit
→ Output at end of transit = stable weight of that product
→ False reject rate dropped from 8.1% to 0.7%
```
---
## 🟢 Exponential Moving Average (EMA)
> **Best when:** You need noise reduction AND fast response, memory is constrained, or you need to track a slowly drifting baseline.
---
### Case 1 — Pneumatic Pressure Control | Fast PID Loop
**Industry:** Semiconductor / Precision Manufacturing
**Signal:** Pressure transducer, 010 bar
```
Plant: Nitrogen blanket pressure control on lithography chamber
PID loop sample time: 50ms
Required response to setpoint change: < 300ms
Problem: High-frequency noise from N₂ flow turbulence = ±0.08 bar peak
SMA with any useful window adds 150400ms of lag → PID unstable
Bare signal used directly → PID output oscillates at 8Hz
```
**EMA vs SMA lag comparison at alpha=0.2:**
```
Signal step at t=0:
Time (scans): 1 2 3 4 5 6 7 8 9 10
True signal: 100 100 100 100 100 100 100 100 100 100
SMA (N=10): 10 20 30 40 50 60 70 80 90 100 ← 10 scan lag
EMA (α=0.2): 20 36 49 59 67 74 79 83 87 89 ← tracks faster
```
**Result:** EMA with α=0.2 reduces noise by 73% while adding only ~2 scan lag vs SMA's 5 scan lag. PID loop stable, pressure held to ±0.015 bar.
---
### Case 2 — Adaptive Motor Current Baseline | Predictive Maintenance
**Industry:** Pulp & Paper
**Signal:** Current transformer on main drive, 0500A
```
Plant: Paper machine main drive, 315kW motor, running 24/7
Problem: Fixed overcurrent alarm at 420A generates 35 false alarms/week
Actual load varies with paper grade: 280A (light) to 380A (heavy)
Maintenance ignores alarms → real fault missed → €240,000 motor burnout
```
**EMA-based adaptive alarm:**
```pascal
// Slow EMA tracks normal operating baseline (τ ≈ 10 minutes)
rAlpha_baseline := 0.0003; // Very slow: tracks grade changes, not transients
fbEMA_baseline(rInput := rMotorCurrent, rAlpha := rAlpha_baseline);
// Alarm threshold = 20% above current baseline
rAdaptiveAlarmLimit := fbEMA_baseline.rOutput * 1.20;
// Result:
// Light paper grade: baseline=285A → alarm at 342A
// Heavy paper grade: baseline=372A → alarm at 446A
// Genuine bearing fault: current rises 35% over 2 hours → caught at 20% mark
// False alarms: reduced from 4/week to 0.2/week
```
---
### Case 3 — Spray Dryer Outlet Humidity | Moisture Control
**Industry:** Dairy / Food Processing
**Signal:** Capacitive humidity sensor, 0100% RH
```
Plant: Milk powder spray dryer, 8-meter drying chamber
Problem: Humidity sensor has two noise sources:
1. Electrical: High-frequency noise from steam injection solenoids (50Hz)
2. Physical: Sensor membrane response is naturally slow (τ = 8 seconds)
Goal: Filter electrical noise without making control slower than sensor itself
```
**Matching EMA to sensor physics:**
```pascal
// Sensor time constant τ = 8 seconds, OB cycle = 500ms
// EMA equivalent time constant: τ_EMA = CycleTime × (1-α)/α
// Solve for α: α = CycleTime / (τ + CycleTime) = 0.5 / (8 + 0.5) = 0.059
rAlpha := 0.06; // Matches sensor's own response — adds no extra lag
// Removes electrical noise completely
// Moisture controller now operates at sensor's natural limit
```
**Outcome:** Powder moisture content variation reduced from ±0.8% to ±0.3%. Shelf life of product increased. No additional hardware needed.
---
### Case 4 — HMI Live OEE Display | Operator Feedback
**Industry:** Automotive / Discrete Manufacturing
**Signal:** Calculated OEE%, updated every 60 seconds
```
Plant: Engine assembly line, 3 shifts, OEE target 85%
Problem: OEE calculated per minute swings wildly: 91%, 68%, 95%, 72%, 88%...
Operators cannot read trend from bouncing number
Shift supervisors arguing about whether line is improving or declining
HMI trending chart looks like noise, not a signal
```
**EMA on the HMI trend calculation:**
```pascal
// Every 60-second OEE update feeds into EMA
// α = 0.15 → approximately 12-minute smoothing window
// Fast enough to show real shifts within 30 minutes
// Slow enough to remove single-cycle statistical noise
fbOEE_EMA(rInput := rOEE_Raw, rAlpha := 0.15);
rHMI_OEE_Trend := fbOEE_EMA.rOutput;
// HMI shows both: raw minute value (small) and EMA trend (large bold number)
// Operators now clearly see: "We've been declining for 45 minutes" vs noise
```
---
## 🟡 Weighted Moving Average (WMA)
> **Best when:** Recent measurements are more physically relevant than older ones — acceleration, reaction peaks, or directional motion.
---
### Case 1 — Robotic Laser Seam Tracker | Welding
**Industry:** Heavy Equipment / Off-Highway Vehicles
**Signal:** Laser line sensor position offset, ±15mm
```
Plant: Robotic MIG welding of excavator boom arms
Weld speed: 600mm/min, joint can change direction every 80mm
Problem: Laser speckle noise = ±0.3mm random error each scan
SMA(6) at 50ms cycle = 300ms averaging → robot lags 3mm behind joint
WMA(6) at 50ms cycle → recent samples dominate → lag reduced to 1mm
```
**Weight distribution comparison:**
| Sample Age | SMA Weight | WMA Weight | Effect |
|------------|-----------|-----------|--------|
| Current (n) | 16.7% | 28.6% | WMA reacts faster |
| n-1 | 16.7% | 23.8% | |
| n-2 | 16.7% | 19.0% | |
| n-3 | 16.7% | 14.3% | |
| n-4 | 16.7% | 9.5% | |
| n-5 (oldest) | 16.7% | 4.8% | WMA forgets faster |
**Result:** Seam tracking error reduced from ±1.8mm (SMA) to ±0.9mm (WMA). Weld quality went from requiring 60% repair rate to 8% repair rate.
---
### Case 2 — AGV Speed Estimation | Intralogistics
**Industry:** Warehouse / E-Commerce Fulfillment
**Signal:** Encoder pulse interval → calculated speed, 02.5 m/s
```
Plant: 48 AGVs in a fulfilment centre, path includes tight 90° turns
Problem: AGV decelerates from 2.5 m/s to 0.3 m/s for turns
Speed estimated from encoder interval averaging
SMA reports average of deceleration journey → thinks AGV is faster than reality
Collision avoidance allows insufficient braking distance
Result: 3 AGV collisions in 6 months, €85,000 in damage
```
**Why WMA solves this:**
```
Decelerating: 2.5 → 2.1 → 1.7 → 1.2 → 0.8 → 0.5 m/s
SMA(6) estimate: (2.5+2.1+1.7+1.2+0.8+0.5)/6 = 1.47 m/s ← overestimates!
WMA(6) estimate: weighted toward recent 0.5, 0.8, 1.2 m/s = 0.92 m/s ← accurate
Stopping distance at 1.47 m/s → collision
Stopping distance at 0.92 m/s → safe stop ✓
```
---
### Case 3 — Exothermic Batch Reactor | Reaction Peak Detection
**Industry:** Specialty Chemicals
**Signal:** Reactor core temperature, 20180°C
```
Plant: Polymerisation reactor, batch cycle 4 hours
Critical event: Exothermic peak at ~120 minutes into batch
Temperature rises 24°C/minute near peak
Cooling water must be added within 2 minutes of peak detection
Problem: SMA lags behind rising temperature → peak detection delayed → runaway risk
Raw signal → too noisy for reliable derivative calculation
```
**WMA tracking the peak better:**
```
At peak approach (rising fast):
Raw temps: 148, 151, 154, 158, 162°C
SMA(5) output: 154.6°C (reports average, underestimates current)
WMA(5) output: 157.1°C (weights recent high values → closer to true current)
Rate of change from WMA: (157.1-153.2)/scan = higher rate → earlier alarm
Cooling water triggered 90 seconds earlier than SMA-based system
Runaway prevented ✓
```
---
### Case 4 — Port Crane Wind Safety | Gust Detection
**Industry:** Port / Logistics
**Signal:** Anemometer, 040 m/s wind speed
```
Plant: Ship-to-shore gantry crane, 65-meter height, 50-ton SWL
Safety rule: Suspend operations above 15 m/s sustained wind
Problem with SMA: A 20 m/s gust brings 10-sample SMA to only 13.5 m/s
Crane keeps operating → safety violation
Problem with raw signal: Brief 16 m/s spike stops crane unnecessarily mid-lift
Dangerous suspended load situation
```
**WMA asymmetric behavior:**
```
Gust event — wind 8→22 m/s over 5 samples:
Samples: 8, 10, 14, 19, 22
SMA(5): 14.6 m/s → misses danger threshold
WMA(5): 17.4 m/s → correctly triggers stop ✓
Lull event — wind 18→12 m/s over 5 samples:
Samples: 18, 16, 15, 13, 12
SMA(5): 14.8 m/s → keeps crane stopped unnecessarily
WMA(5): 13.3 m/s → allows restart sooner (recent calm dominant) ✓
```
**Result:** WMA naturally creates faster response to danger (rising winds dominate quickly) and faster recovery from false stops (falling winds dominate quickly). 23% reduction in unnecessary crane stoppages.
---
## 🔴 Median Filter
> **Best when:** Noise is not random but impulsive — single-scan or multi-scan spikes of large magnitude. Median is the only filter immune to outliers regardless of their size.
---
### Case 1 — Cement Silo Radar Level | Bulk Solids
**Industry:** Building Materials / Cement
**Signal:** Radar level transmitter, 0100%
```
Plant: 4 × 500-tonne cement silos, radar mounted in silo roof
Problem: Bulk loading — cement dropped from 8-meter height
Falling dust cloud reflects radar → false reading of 05% (apparent empty)
Each false event lasts 24 scans (200400ms at 100ms cycle)
False empty alarm triggers emergency fill order
Cost of unnecessary delivery: €2,800 per incident
Incidents per month: 1218 before filter installed
```
**Why only median works here:**
```
Spike magnitude: 95% → 3% → 4% → 97% (two false samples in 4-sample window)
SMA(7): (95+95+95+3+4+97+97)/7 = 69.4% ← pulled dramatically toward zero
EMA: Previous 95% → α×3% + (1-α)×95% = still dragged toward false value
Median(7): Sort [3, 4, 95, 95, 95, 97, 97] → middle value = 95% ✓
The false readings cannot become median of 7 values.
They just don't matter, regardless of magnitude.
```
**Annual saving after installation:** €480,000 in avoided false deliveries.
---
### Case 2 — Engine Exhaust Thermocouple | Vibration Environment
**Industry:** Power Generation / Diesel Gensets
**Signal:** Type-K thermocouple, 0900°C
```
Plant: 2MW standby diesel generator, data centre backup power
Problem: Engine vibration causes intermittent micro-disconnect in TC extension cable
Disconnected thermocouple reads 1372°C (open-circuit limit value)
These spikes last 12 scans (50100ms at 50ms cycle)
Before filter: High-temp alarm fires → generator shuts down
Data centre loses power for 8 seconds until UPS takes over
Estimated cost per incident: €45,000 (SLA penalties)
```
**Median neutralises open-circuit spikes perfectly:**
```
Window = 5 samples, OB cycle = 50ms:
Reading sequence: 520, 522, 1372, 521, 523°C
Sorted: [520, 521, 522, 523, 1372]
Median (pos 3): 522°C ← correct exhaust temperature
The 1372°C spike ends up in position 5 every time.
Alarm system never sees it.
Generator stays online ✓
```
---
### Case 3 — Bottle Presence Sensor | Filling Line
**Industry:** Beverage / Bottling
**Signal:** Ultrasonic proximity, BOOL-level thresholded from REAL, 0500mm
```
Plant: Beer bottling line, 36,000 bottles/hour (10 bottles/second)
Problem: Label on bottle creates bad angle reflection → false absence reading
Duration of false absence: exactly 1 scan (10ms at 10ms cycle)
Without filter: False absence during filling → nozzle lifts → beer spray
Line stop, cleanup, 15 minutes lost = 9,000 bottles lost
```
**Minimum median window for 1-scan rejection:**
```pascal
// Median(3) requires false reading to appear in ≥2 of 3 consecutive scans
// A genuine absence appears in ALL scans
// A 1-scan label reflection appears in 1 of 3 scans → median = present ✓
iWindowSize := 3; // Smallest effective window, lowest latency
// Genuine absence detection latency: 2 scans = 20ms
// 1-scan false absence: completely invisible ✓
// Line stops due to false absence sensor: 3/month → 0/month
```
---
### Case 4 — Wastewater pH Control | Biological Treatment
**Industry:** Municipal Wastewater Treatment
**Signal:** pH electrode, 014 pH
```
Plant: Activated sludge aeration tank, 2.5 million litre capacity
Problem: Biological process produces CO₂ bubbles
Bubbles contact pH membrane → 13 second false readings (±23 pH units)
Acid/base dosing pump reacts to false readings
Over-dosing of H₂SO₄ kills biological culture → treatment failure
Rebuilding biological culture: 3 weeks, €95,000 in penalties
```
**Bubble immunity via median:**
```
OB cycle: 500ms
Bubble duration: 13 seconds → 26 false samples
pH readings over 10 scans:
[7.1, 7.1, 7.2, 4.3, 4.1, 7.1, 4.8, 7.2, 7.1, 7.2]
↑ ↑ ↑
3 bubble-affected readings (30% of window)
Median(9): Sort → [4.1, 4.3, 4.8, 7.1, 7.1, 7.1, 7.2, 7.2, 7.2]
Median = 7.1 ← correct pH ✓
For median to fail, bubbles must corrupt >50% of window samples
At current bubble frequency: essentially impossible
```
**Dosing pump overdose events:** 8/month → 0/month. Biological culture preserved continuously for 14 months.
---
## ⚪ Rate Limiter
> **Best when:** The problem is not sensor noise but command discontinuities — sudden jumps in setpoints, references, or outputs that would mechanically shock the equipment downstream.
---
### Case 1 — DN200 Steam Control Valve | Water Hammer
**Industry:** Petrochemical / Refining
**Signal:** PID output → valve position command, 0100%
```
Plant: Steam supply to distillation column reboiler, 12 bar saturated steam
Valve: Pneumatic butterfly, DN200 (200mm bore), actuated in 4 seconds full stroke
Problem: PID integral windup during startup → output jumps from 15% to 90% in one scan
Valve opens full in 4 seconds
Steam condensate slug accelerated to 40 m/s in main header
Water hammer peak pressure: 28 bar (design pressure: 16 bar)
Result: 3 pipe flange failures in 18 months, 2 injuries
```
**Rate limiter configuration:**
```pascal
// Valve full stroke = 4 seconds for 100% travel = 25%/second max mechanical
// Safety margin: limit to 5%/second for steam service (industry standard)
// Asymmetric: allow faster close (emergency) than open (process safety)
rMaxRiseRate := 5.0; // %/second opening — slow, controlled steam admission
rMaxFallRate := 15.0; // %/second closing — faster emergency closure allowed
rCycleTimeS := 0.1; // 100ms OB cycle
// PID can demand whatever it wants — valve command never exceeds 0.5%/scan
// Water hammer peak pressure: 28 bar → 13.2 bar (within design limit) ✓
// Zero flange failures in 30 months since installation
```
---
### Case 2 — Frequency Inverter Speed Reference | Conveyor Anti-Jerk
**Industry:** Logistics / Distribution Centre
**Signal:** Speed reference from master PLC → drive, 050 Hz
```
Plant: 800-metre main sortation conveyor, 23 drive sections
Problem: PROFINET communication glitch every 23 weeks causes reference reset
Drive section receives 0 Hz command → reapplies last valid setpoint next scan
Effective command: 45 Hz → 0 Hz → 45 Hz in two scan cycles (4ms)
Conveyor belt jerks violently
Result: Parcels thrown off belt, belt tracking lost, 4-hour shutdown per event
```
**Rate limiter as communication fault protection:**
```pascal
rMaxRiseRate := 8.0; // Hz/second — matches drive's own acceleration ramp
rMaxFallRate := 12.0; // Hz/second — matched to deceleration ramp
rCycleTimeS := 0.004; // 4ms PROFINET cycle time
// Communication glitch: reference drops to 0 Hz for 1-2 cycles
// Rate limiter maximum drop in 2 cycles:
// MaxDrop = 12.0 Hz/s × 0.004s × 2 cycles = 0.096 Hz
// Belt barely notices a 0.096 Hz dip ✓
// Recovery: rises back at 8 Hz/s — smooth, no jerk
// Sortation conveyor uptime improved from 97.1% to 99.6%
```
---
### Case 3 — Plastic Extruder Barrel Heating | Element Life
**Industry:** Plastics / Injection Moulding
**Signal:** Temperature setpoint to PID, 0300°C
```
Plant: 80-tonne injection moulding machine, 5-zone barrel heating
Heater bands: Ceramic band heaters, 3kW each, €280 each, 12 on machine
Problem: Cold start — operator sets all zones to 220°C immediately
PID demands 100% heater output from cold (20°C)
Thermal shock: 20°C → 220°C at maximum power in 8 minutes
Ceramic elements crack from thermal gradient (centre hot, shell cool)
Heater replacement frequency: 2.3 elements/week = €840/week
Downtime per replacement: 45 minutes (barrel must cool to 60°C first)
```
**Setpoint ramping via rate limiter:**
```pascal
// Industry standard for ceramic heater protection: max 2°C/second warmup
rMaxRiseRate := 2.0; // °C/second — controlled warmup
rMaxFallRate := 99.0; // °C/second — allow fast setpoint drops (unrestricted)
rCycleTimeS := 0.1; // 100ms OB
// Cold start: PID sees 20°C → 220°C ramp over 100 seconds (not 8 minutes!)
// Heater operates at 6070% output during warmup instead of 100%
// Thermal gradient across ceramic: reduced by 65%
// After installation:
// Heater replacement: 0.2 elements/week (from 2.3/week)
// Annual saving: €88,000 in parts + €210,000 in avoided downtime
```
---
### Case 4 — Collaborative Robot Joint Command | Safety Fault Prevention
**Industry:** Automotive Final Assembly
**Signal:** Path planner position command → joint controller, degrees
```
Plant: Human-robot collaboration cell, door panel installation
Robot: KUKA LBR iiwa 7 R800, 7-axis
Problem: Path planning software occasionally produces waypoint calculation error
Error causes instantaneous jump of 35° in joint 3 command
Drive detects commanded velocity exceeds dynamic limit → E-STOP triggers
Robot in middle of panel installation → panel dropped, damage €2,200/incident
E-STOP recovery: 8 minutes (safety system reset + manual verification)
Incidents per month: 46 (software team cannot reproduce reliably)
```
**Rate limiter as hardware-level protection:**
```pascal
// Joint 3 mechanical limit: 85°/second at rated payload
// Software path planner should never command faster than 60°/second
// Rate limiter set to 60°/second → software fault cannot reach drive
rMaxRiseRate := 60.0; // °/second
rMaxFallRate := 60.0; // °/second
rCycleTimeS := 0.004; // 4ms robot controller cycle (250Hz)
// 35° jump in one 4ms cycle would require 8,750°/s
// Rate limiter allows maximum 0.24° per cycle
// Fault appears as smooth 0.24°/cycle motion → safe, imperceptible deviation
// Drive never sees over-speed command → E-STOP never triggered
// E-STOP events: 5/month → 0/month
// Software team still investigating root cause at their own pace
```
---
## 🔗 Stacking Filters — Real Combinations
The most demanding applications chain multiple filters. Each handles a different type of signal corruption.
---
### Combination 1 — Pump Pressure Signal for PID
```
Application: Centrifugal pump discharge pressure, variable speed drive
Environment: High vibration, nearby VFD causes EMI spikes
Chain: Raw → Median(5) → EMA(α=0.2) → PID
Median removes: EMI-induced single-scan spikes (±15 bar magnitude, 1 scan)
EMA removes: Residual vibration noise (±0.3 bar, high frequency)
PID receives: Clean, responsive pressure signal
Without chain: PID oscillates at 4Hz, cavitation risk
With chain: PID stable, pressure held ±0.08 bar
```
---
### Combination 2 — Operator Setpoint to Large Actuator
```
Application: District heating control valve, DN400, 16 bar hot water
Source of problems: Operator makes sudden large setpoint changes on SCADA
Chain: SCADA setpoint → SMA(5) → RateLimiter(3%/s) → PID setpoint
SMA removes: SCADA communication glitches and double-click entries
RateLimiter: Prevents any mechanical shock regardless of SMA output
PID setpoint: Always smooth, physically achievable trajectory
Result: Valve seal lifetime: 3 years → 8+ years
Pipe stress incidents: 4/year → 0/year
```
---
### Combination 3 — Quality Inspection on High-Speed Line
```
Application: Inline optical thickness measurement, steel strip rolling mill
Line speed: 25 m/s, sensor samples every 2mm = 12,500 samples/second
Reported to control system: Every 100ms (subsampled)
Chain: Raw(12500Hz) → Median(3) → WMA(8) → Thickness controller
Median removes: Optical speckle, oil droplet occlusions (12 sample spikes)
WMA emphasizes: Most recent measurements (strip just left the roll gap)
Controller sees: True current thickness weighted toward exit, not entry
Thickness tolerance: ±12μm achieved vs ±28μm before filter chain
Customer rejection rate: 0.8% → 0.1%
```
---
## 📊 Filter Selection Decision Tree
```
Signal has SPIKES (single-scan large jumps)?
├─ YES → Use MEDIAN first
│ Then add EMA/SMA for residual noise
└─ NO → Signal changes too FAST for your filter?
├─ YES (fast process, tight PID) → Use EMA (tune α carefully)
└─ NO → Response speed flexible?
├─ Recent samples more RELEVANT? → Use WMA
├─ All samples EQUAL importance? → Use SMA
└─ Problem is COMMAND JUMPS not noise? → Use RATE LIMITER
```
---
## 💡 Engineering Rules of Thumb
| Situation | Rule |
|-----------|------|
| Noise frequency >> process frequency | SMA or EMA work equally well |
| Noise duration = 13 scans, any magnitude | Always use Median first |
| PID loop with noise issues | EMA preferred over SMA (less lag) |
| Actuator protection | Rate Limiter on output, not input |
| Unknown noise character | Start with Median(5) + EMA(0.15) chain |
| Very large window needed (>50) | Use EMA — no array cost |
| Safety-critical setpoint path | Rate Limiter is mandatory, not optional |
---
*S7-1500 Advanced Signal Filtering Library — Real Industrial Case Studies*
*Companion document to `README.md` and SCL source code*