381 lines
12 KiB
Markdown
381 lines
12 KiB
Markdown
|
|
# 📡 S7-1500 Advanced Signal Filtering Library
|
|||
|
|
### SCL Function Blocks for Siemens TIA Portal
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Overview
|
|||
|
|
|
|||
|
|
This library provides a collection of advanced signal filtering Function Blocks (FBs) written in **Structured Control Language (SCL)** for the **Siemens S7-1500 PLC** platform. All blocks share a consistent interface and are designed for real-time analog signal processing in industrial automation environments.
|
|||
|
|
|
|||
|
|
Each filter uses a **circular buffer** architecture — no memory shifting per scan — keeping CPU load minimal and deterministic.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Contents
|
|||
|
|
|
|||
|
|
| FB Name | Filter Type | Best Use Case |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `FB_MovingAverage` | Simple Moving Average (SMA) | General noise reduction |
|
|||
|
|
| `FB_EMA` | Exponential Moving Average | Fast response + smoothing |
|
|||
|
|
| `FB_WMA` | Weighted Moving Average | Emphasize recent samples |
|
|||
|
|
| `FB_MedianFilter` | Median / Order Statistics | Spike & glitch rejection |
|
|||
|
|
| `FB_RateLimiter` | Slew Rate Limiter | Actuator protection |
|
|||
|
|
| `FB_SignalFilter` | Unified wrapper (all above) | Single-block deployment |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Requirements
|
|||
|
|
|
|||
|
|
- **PLC:** Siemens S7-1500 (any CPU)
|
|||
|
|
- **TIA Portal:** V16 or later
|
|||
|
|
- **Language:** SCL (Structured Control Language)
|
|||
|
|
- **OB:** Can be called from any OB (OB1, cyclic OB, etc.)
|
|||
|
|
- **No special libraries required**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Interface — Common Pattern
|
|||
|
|
|
|||
|
|
All FBs follow the same interface convention:
|
|||
|
|
|
|||
|
|
```pascal
|
|||
|
|
VAR_INPUT
|
|||
|
|
xEnable : BOOL; // Enable filtering; FALSE = passthrough + reset
|
|||
|
|
rInput : REAL; // Raw analog input value
|
|||
|
|
iWindowSize : INT; // Buffer/window size (filter-specific)
|
|||
|
|
END_VAR
|
|||
|
|
|
|||
|
|
VAR_OUTPUT
|
|||
|
|
rOutput : REAL; // Filtered output value
|
|||
|
|
xReady : BOOL; // TRUE when buffer is full (SMA/WMA/Median)
|
|||
|
|
END_VAR
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> **Note:** When `xEnable = FALSE`, each FB resets its internal state and passes `rInput` directly to `rOutput`. This allows safe runtime switching between filter modes without output jumps.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Filter Reference
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 1. `FB_MovingAverage` — Simple Moving Average (SMA)
|
|||
|
|
|
|||
|
|
Computes the arithmetic mean of the last *N* samples using a circular buffer and a running sum. No per-scan array iteration — the sum is updated incrementally.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `iWindowSize` | INT | 10 | Window size (1–100) |
|
|||
|
|
| `rOutput` | REAL | — | Filtered output |
|
|||
|
|
| `xReady` | BOOL | — | TRUE when buffer full |
|
|||
|
|
|
|||
|
|
**Formula:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Output(n) = [ Sum of last N samples ] / N
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Characteristics:**
|
|||
|
|
- Equal weight to all samples in window
|
|||
|
|
- Output lags behind input by N/2 samples
|
|||
|
|
- Larger window = more smoothing = more lag
|
|||
|
|
- Very low CPU load (no division per element)
|
|||
|
|
|
|||
|
|
**Typical window sizes:**
|
|||
|
|
|
|||
|
|
| Signal Type | Recommended Window |
|
|||
|
|
|---|---|
|
|||
|
|
| Thermocouple / temperature | 20–50 |
|
|||
|
|
| Pressure sensor | 5–15 |
|
|||
|
|
| Flow meter | 10–20 |
|
|||
|
|
| Current / power | 5–10 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. `FB_EMA` — Exponential Moving Average
|
|||
|
|
|
|||
|
|
Applies exponentially decreasing weights to past samples. No buffer required — only the previous output value is stored. Ideal when fast response with smoothing is needed.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `rAlpha` | REAL | 0.1 | Smoothing factor (0.0–1.0) |
|
|||
|
|
| `rOutput` | REAL | — | Filtered output |
|
|||
|
|
|
|||
|
|
**Formula:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Output(n) = α × Input(n) + (1 − α) × Output(n−1)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Alpha selection guide:**
|
|||
|
|
|
|||
|
|
| Alpha | Effect | Equivalent SMA Window |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 0.05 | Heavy smoothing, slow response | ~39 samples |
|
|||
|
|
| 0.1 | Balanced (default) | ~19 samples |
|
|||
|
|
| 0.2 | Light smoothing, fast response | ~9 samples |
|
|||
|
|
| 0.5 | Minimal smoothing | ~3 samples |
|
|||
|
|
|
|||
|
|
**Characteristics:**
|
|||
|
|
- Minimal memory footprint (no array)
|
|||
|
|
- Infinite impulse response — past samples never fully forgotten
|
|||
|
|
- Best choice when memory is constrained or window must be very large
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. `FB_WMA` — Weighted Moving Average
|
|||
|
|
|
|||
|
|
Similar to SMA but assigns linearly increasing weights to more recent samples. The newest sample gets weight *N*, the oldest gets weight *1*.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `iWindowSize` | INT | 8 | Window size (1–16) |
|
|||
|
|
| `rOutput` | REAL | — | Filtered output |
|
|||
|
|
|
|||
|
|
**Formula:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Output(n) = Σ [ weight(i) × sample(i) ] / Σ weight(i)
|
|||
|
|
weight(i) = N for newest, 1 for oldest
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Characteristics:**
|
|||
|
|
- Responds faster to changes than SMA at same window size
|
|||
|
|
- More computationally intensive than SMA or EMA
|
|||
|
|
- Good compromise between lag and smoothing
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. `FB_MedianFilter` — Median / Order Statistics Filter
|
|||
|
|
|
|||
|
|
Collects the last *N* samples, sorts them using insertion sort, and outputs the middle value. Completely immune to impulse spikes regardless of magnitude.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `iWindowSize` | INT | 7 | Window size, odd recommended (1–15) |
|
|||
|
|
| `rOutput` | REAL | — | Filtered output |
|
|||
|
|
|
|||
|
|
**Characteristics:**
|
|||
|
|
- **Best** filter for rejecting sensor glitches, wire bounce, EMI spikes
|
|||
|
|
- Non-linear filter — does not distort signal shape between spikes
|
|||
|
|
- Use **odd** window sizes (3, 5, 7, 9...) for a clean median value
|
|||
|
|
- Higher CPU load than SMA/EMA due to in-place sort each scan
|
|||
|
|
|
|||
|
|
**Recommended window sizes:**
|
|||
|
|
|
|||
|
|
| Application | Window |
|
|||
|
|
|---|---|
|
|||
|
|
| Remove single-sample spikes | 3 |
|
|||
|
|
| General spike rejection | 5–7 |
|
|||
|
|
| Heavy transient environment | 9–11 |
|
|||
|
|
|
|||
|
|
> **Tip:** Combine Median + EMA for best results: Median removes spikes, EMA smooths residual noise.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 5. `FB_RateLimiter` — Slew Rate Limiter
|
|||
|
|
|
|||
|
|
Limits the maximum rate of change (rise and fall) of a signal per scan cycle. The output tracks the input but cannot change faster than the configured rate. Protects actuators from sudden setpoint jumps.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `rMaxRiseRate` | REAL | 10.0 | Max units/second rising |
|
|||
|
|
| `rMaxFallRate` | REAL | 10.0 | Max units/second falling |
|
|||
|
|
| `rCycleTimeS` | REAL | 0.1 | OB cycle time in seconds |
|
|||
|
|
| `rOutput` | REAL | — | Rate-limited output |
|
|||
|
|
|
|||
|
|
**Formula:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
MaxStep = MaxRate × CycleTime
|
|||
|
|
Output(n) = Output(n-1) + clamp(Input(n) − Output(n-1), −MaxStep, +MaxStep)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Characteristics:**
|
|||
|
|
- Not a noise filter — purely a change-rate constraint
|
|||
|
|
- Asymmetric rise/fall rates supported (e.g. slow open, fast close)
|
|||
|
|
- Must be configured with correct `rCycleTimeS` to function correctly
|
|||
|
|
- Does not affect steady-state accuracy
|
|||
|
|
|
|||
|
|
> **Important:** Set `rCycleTimeS` to match your OB cycle time. For OB1 at 100ms, use `0.1`. You can read this from `OB_CYCL.CYCLE_TIME` if needed.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 6. `FB_SignalFilter` — Unified Wrapper
|
|||
|
|
|
|||
|
|
A single FB that encapsulates all five filters. Select the active filter at runtime via `iMode`. Internally instantiates all FBs; only the selected one processes each scan.
|
|||
|
|
|
|||
|
|
**Parameters:**
|
|||
|
|
|
|||
|
|
| Parameter | Type | Default | Description |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| `xEnable` | BOOL | — | Enable filter |
|
|||
|
|
| `rInput` | REAL | — | Analog input |
|
|||
|
|
| `iMode` | INT | 0 | Filter selection (see below) |
|
|||
|
|
| `iWindowSize` | INT | 10 | Window for SMA / WMA / Median |
|
|||
|
|
| `rAlpha` | REAL | 0.1 | Alpha for EMA |
|
|||
|
|
| `rMaxRate` | REAL | 10.0 | Rate for RateLimiter |
|
|||
|
|
| `rCycleTimeS` | REAL | 0.1 | Cycle time for RateLimiter |
|
|||
|
|
| `rOutput` | REAL | — | Filtered output |
|
|||
|
|
| `xReady` | BOOL | — | Buffer ready flag |
|
|||
|
|
|
|||
|
|
**Mode selection:**
|
|||
|
|
|
|||
|
|
| `iMode` | Filter |
|
|||
|
|
|---|---|
|
|||
|
|
| 0 | Passthrough (no filtering) |
|
|||
|
|
| 1 | Simple Moving Average |
|
|||
|
|
| 2 | Exponential Moving Average |
|
|||
|
|
| 3 | Weighted Moving Average |
|
|||
|
|
| 4 | Median Filter |
|
|||
|
|
| 5 | Rate Limiter |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Performance Comparison
|
|||
|
|
|
|||
|
|
| Filter | Noise Reduction | Spike Rejection | Response Speed | CPU Load | Memory |
|
|||
|
|
|---|---|---|---|---|---|
|
|||
|
|
| SMA | ★★★★☆ | ★★☆☆☆ | ★★☆☆☆ | Low | Medium |
|
|||
|
|
| EMA | ★★★☆☆ | ★★☆☆☆ | ★★★★☆ | Very Low | Minimal |
|
|||
|
|
| WMA | ★★★★☆ | ★★☆☆☆ | ★★★☆☆ | Medium | Medium |
|
|||
|
|
| Median | ★★★☆☆ | ★★★★★ | ★★★☆☆ | Medium-High | Medium |
|
|||
|
|
| Rate Limiter | ★☆☆☆☆ | ★★★☆☆ | ★★★☆☆ | Very Low | Minimal |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Recommended Filter Combinations
|
|||
|
|
|
|||
|
|
For best results in demanding environments, chain two filters:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Raw Signal → Median (spike removal) → EMA (noise smoothing) → Control loop
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```pascal
|
|||
|
|
// Example: Median pre-filter + EMA smoothing
|
|||
|
|
fbMedian(xEnable := TRUE, rInput := rRawAnalog, iWindowSize := 5);
|
|||
|
|
fbEMA(xEnable := TRUE, rInput := fbMedian.rOutput, rAlpha := 0.15);
|
|||
|
|
rCleanSignal := fbEMA.rOutput;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Usage Example
|
|||
|
|
|
|||
|
|
```pascal
|
|||
|
|
// Declarations
|
|||
|
|
VAR
|
|||
|
|
fbFilter : FB_SignalFilter;
|
|||
|
|
rRawAnalog : REAL; // From analog input card (e.g. scaled 0.0–100.0)
|
|||
|
|
rFiltered : REAL;
|
|||
|
|
END_VAR
|
|||
|
|
|
|||
|
|
// In OB1 or cyclic FC
|
|||
|
|
fbFilter(
|
|||
|
|
xEnable := TRUE,
|
|||
|
|
rInput := rRawAnalog,
|
|||
|
|
iMode := 1, // 1 = SMA
|
|||
|
|
iWindowSize := 15,
|
|||
|
|
rCycleTimeS := 0.1 // 100ms OB cycle
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
rFiltered := fbFilter.rOutput;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Circular Buffer Architecture
|
|||
|
|
|
|||
|
|
All array-based filters use a **circular (ring) buffer** pattern:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Buffer: [ 12.4 | 13.1 | 12.8 | 13.0 | 12.6 ]
|
|||
|
|
↑ Index pointer (oldest slot, next to overwrite)
|
|||
|
|
|
|||
|
|
New sample arrives → overwrite oldest → advance index
|
|||
|
|
No shifting, O(1) write per scan
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
This ensures constant, predictable scan-time contribution regardless of window size.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Signal Flow Diagram
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Analog Input Card
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────┐
|
|||
|
|
│ Raw REAL │ e.g. 0.0 – 100.0 (engineering units, already scaled)
|
|||
|
|
└──────┬──────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ FB_SignalFilter │
|
|||
|
|
│ │
|
|||
|
|
│ iMode=1 → FB_MovingAverage │
|
|||
|
|
│ iMode=2 → FB_EMA │
|
|||
|
|
│ iMode=3 → FB_WMA │
|
|||
|
|
│ iMode=4 → FB_MedianFilter │
|
|||
|
|
│ iMode=5 → FB_RateLimiter │
|
|||
|
|
└──────────────────┬──────────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
rOutput (REAL)
|
|||
|
|
│
|
|||
|
|
┌─────────┴──────────┐
|
|||
|
|
▼ ▼
|
|||
|
|
PID Controller HMI / SCADA
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Integration Notes
|
|||
|
|
|
|||
|
|
- **Analog scaling:** All FBs operate on pre-scaled REAL values in engineering units (°C, bar, %, m³/h, etc.). Scale your analog input before passing to any filter FB.
|
|||
|
|
- **First scan:** On the first scan after `xEnable` goes TRUE, output equals input. No startup spike.
|
|||
|
|
- **Mode switching:** Changing `iMode` at runtime resets the newly selected filter on its next call. A brief transient (1–2 scan cycles) may occur.
|
|||
|
|
- **Cycle time:** Only `FB_RateLimiter` is cycle-time sensitive. All other filters are cycle-time agnostic — window size implicitly defines the time constant based on your OB period.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Related Libraries
|
|||
|
|
|
|||
|
|
This library pairs naturally with:
|
|||
|
|
|
|||
|
|
- **`FB_StateAlarmManager`** — State-based alarm management with bitmask suppression, hysteresis, on-delay, and priority. Feed filtered signals into alarm manager for dramatically fewer nuisance alarms.
|
|||
|
|
- **`FB_CUSUM`** *(planned)* — Cumulative sum control chart for slow drift detection
|
|||
|
|
- **`FB_KalmanFilter`** *(planned)* — State estimation and sensor validation
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## License
|
|||
|
|
|
|||
|
|
Internal use. Adapt freely for your project.
|
|||
|
|
Tested on: **S7-1500 CPU 1515-2 PN**, TIA Portal V18.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*Generated for S7-1500 SCL Signal Filtering Library — Advanced Process Control Series*
|