ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Digital Filter Chain for Signal Smoothing

PLC Function Block Diagram (FBD)

Goal -- WPM

Ready
Exercise Algorithm Area
1PROGRAM Digital_Filter_Chain
2
3VAR
4// Input signal
5InputSignal : REAL;
6// Output signal after filtering
7FilteredOutput : REAL;
8
9// --- Filter 1: Moving Average Filter ---
10// Window size for the moving average
11MA_WindowSize : INT := 5;
12// Array to store past input values for moving average
13MA_History : ARRAY[1..5] OF REAL;
14// Index for the moving average history array
15MA_Index : INT := 1;
16// Sum of values in the moving average history
17MA_Sum : REAL := 0.0;
18// Output of the moving average filter
19MA_Output : REAL;
20// Flag to indicate if moving average filter is initialized
21MA_Initialized : BOOL := FALSE;
22
23// --- Filter 2: Simple Low-Pass Filter (First-Order) ---
24// Time constant for the low-pass filter (tau)
25LPF_Tau : REAL := 0.5; // Seconds
26// Output of the low-pass filter
27LPF_Output : REAL;
28// Previous output of the low-pass filter
29LPF_PrevOutput : REAL;
30// Time step for discrete simulation (seconds)
31CycleTime : REAL := 0.1;
32// Alpha coefficient for the low-pass filter
33LPF_Alpha : REAL;
34// Flag to indicate if low-pass filter is initialized
35LPF_Initialized : BOOL := FALSE;
36
37// --- Filter 3: Median Filter ---
38// Window size for the median filter (must be odd)
39Median_WindowSize : INT := 3;
40// Array to store past input values for median filter
41Median_History : ARRAY[1..3] OF REAL;
42// Index for the median filter history array
43Median_Index : INT := 1;
44// Output of the median filter
45Median_Output : REAL;
46// Temporary array for sorting in median filter
47Median_SortArray : ARRAY[1..3] OF REAL;
48// Flag to indicate if median filter is initialized
49Median_Initialized : BOOL := FALSE;
50
51END_VAR
52
53// --- Main Filter Chain Execution ---
54
55// Initialize filters on first run or when parameters change (simplified here)
56IF NOT MA_Initialized THEN
57// Initialize moving average history with zeros or initial input
58FOR i := 1 TO MA_WindowSize DO
59MA_History[i] := InputSignal; // Or 0.0 if preferred
60END_FOR
61MA_Sum := InputSignal * REAL_FROM_INT(MA_WindowSize);
62MA_Output := InputSignal;
63MA_Initialized := TRUE;
64END_IF
65
66IF NOT LPF_Initialized THEN
67LPF_PrevOutput := InputSignal;
68LPF_Alpha := CycleTime / (LPF_Tau + CycleTime);
69LPF_Output := InputSignal;
70LPF_Initialized := TRUE;
71END_IF
72
73IF NOT Median_Initialized THEN
74// Initialize median filter history with initial input
75FOR i := 1 TO Median_WindowSize DO
76Median_History[i] := InputSignal;
77END_FOR
78Median_Output := InputSignal;
79Median_Initialized := TRUE;
80END_IF
81
82// --- Apply Moving Average Filter ---
83
84// Remove the oldest value from the sum
85MA_Sum := MA_Sum - MA_History[MA_Index];
86
87// Add the new input signal to the sum
88MA_Sum := MA_Sum + InputSignal;
89
90// Store the new input signal in the history array
91MA_History[MA_Index] := InputSignal;
92
93// Update the index, wrapping around if necessary
94MA_Index := MA_Index + 1;
95IF MA_Index > MA_WindowSize THEN
96MA_Index := 1;
97END_IF
98
99// Calculate the moving average output
100MA_Output := MA_Sum / REAL_FROM_INT(MA_WindowSize);
101
102// --- Apply Low-Pass Filter ---
103
104// Calculate the alpha coefficient if it hasn't been done or if parameters changed
105// In a real system, this would be calculated once or when CycleTime/LPF_Tau change.
106IF CycleTime > 0.0 AND LPF_Tau > 0.0 THEN
107LPF_Alpha := CycleTime / (LPF_Tau + CycleTime);
108ELSE
109LPF_Alpha := 0.0; // Prevent division by zero
110END_IF
111
112// Apply the first-order low-pass filter formula
113// LPF_Output = LPF_PrevOutput + LPF_Alpha * (Input - LPF_PrevOutput)
114// Here, 'Input' is the output of the previous filter (MA_Output)
115LPF_Output := LPF_PrevOutput + LPF_Alpha * (MA_Output - LPF_PrevOutput);
116
117// Update the previous output for the next iteration
118LPF_PrevOutput := LPF_Output;
119
120// --- Apply Median Filter ---
121
122// Store the new input signal (output of LPF) in the history array
123Median_History[Median_Index] := LPF_Output;
124
125// Copy history to a temporary array for sorting
126FOR i := 1 TO Median_WindowSize DO
127Median_SortArray[i] := Median_History[i];
128END_FOR
129
130// Sort the temporary array to find the median
131// This is a simplified bubble sort for demonstration. A more efficient sort might be used.
132FOR i := 1 TO Median_WindowSize - 1 DO
133FOR j := i + 1 TO Median_WindowSize DO
134IF Median_SortArray[i] > Median_SortArray[j] THEN
135// Swap elements
136temp := Median_SortArray[i];
137Median_SortArray[i] := Median_SortArray[j];
138Median_SortArray[j] := temp;
139END_IF
140END_FOR
141END_FOR
142
143// The median is the middle element of the sorted array
144Median_Output := Median_SortArray[(Median_WindowSize + 1) / 2];
145
146// Update the index, wrapping around if necessary
147Median_Index := Median_Index + 1;
148IF Median_Index > Median_WindowSize THEN
149Median_Index := 1;
150END_IF
151
152// --- Final Output ---
153
154// The output of the last filter is the final filtered output
155FilteredOutput := Median_Output;
156
157END_PROGRAM
Algorithm description viewbox

Digital Filter Chain for Signal Smoothing

Algorithm description:

This program implements a chain of digital filters to smooth an incoming signal, reducing noise and transient fluctuations. It sequentially applies a Moving Average filter, a Simple Low-Pass Filter, and a Median Filter. The output of each filter stage becomes the input for the next, creating a cascaded effect. The Moving Average filter averages recent samples, the Low-Pass filter attenuates high-frequency components, and the Median filter removes outliers. This combination is effective for cleaning up noisy sensor data in real-time control applications, ensuring more stable and reliable system operation.

Algorithm explanation:

This program chains three common digital filters: Moving Average (MA), Low-Pass Filter (LPF), and Median Filter. The MA filter averages the last `MA_WindowSize` samples, providing smoothing. Its time complexity is O(1) per sample due to efficient sum update. The LPF is a first-order filter `y[n] = y[n-1] + alpha * (x[n] - y[n-1])`, where `alpha = CycleTime / (Tau + CycleTime)`. It attenuates high frequencies. Its complexity is O(1). The Median filter finds the median value within a sliding window of `Median_WindowSize` samples, effectively removing spikes. Its complexity is O(W log W) or O(W^2) depending on the sort algorithm used, where W is the window size; here, it's O(3 log 3) or O(9), effectively constant. Initialization for each filter handles the first few samples to avoid incorrect calculations. Edge cases include zero `CycleTime` or `Tau` for LPF, and ensuring `Median_WindowSize` is odd. The overall complexity is dominated by the median filter's sort, but for small, fixed window sizes, it's effectively O(1) per sample. Space complexity is O(W) for storing filter histories.

Pseudocode:

PROGRAM Digital_Filter_Chain
  INPUTS: InputSignal, MA_WindowSize, LPF_Tau, Median_WindowSize, CycleTime
  OUTPUTS: FilteredOutput

  // Initialize filters if needed
  IF NOT MA_Initialized THEN ... END IF
  IF NOT LPF_Initialized THEN ... END IF
  IF NOT Median_Initialized THEN ... END IF

  // --- Moving Average Filter ---
  MA_Sum = MA_Sum - MA_History[MA_Index]
  MA_Sum = MA_Sum + InputSignal
  MA_History[MA_Index] = InputSignal
  MA_Index = (MA_Index % MA_WindowSize) + 1
  MA_Output = MA_Sum / ConvertToReal(MA_WindowSize)

  // --- Low-Pass Filter ---
  LPF_Alpha = CycleTime / (LPF_Tau + CycleTime) (handle division by zero)
  LPF_Output = LPF_PrevOutput + LPF_Alpha * (MA_Output - LPF_PrevOutput)
  LPF_PrevOutput = LPF_Output

  // --- Median Filter ---
  Median_History[Median_Index] = LPF_Output
  Copy Median_History to Median_SortArray
  Sort Median_SortArray
  Median_Output = Median_SortArray[(Median_WindowSize + 1) / 2]
  Median_Index = (Median_Index % Median_WindowSize) + 1

  // --- Final Output ---
  FilteredOutput = Median_Output

END PROGRAM