diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..f9a096f --- /dev/null +++ b/readme.md @@ -0,0 +1,381 @@ +# πŸ“‘ 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* \ No newline at end of file