# πŸ“‘ 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*