Algorithm, Arduino, Signal

[Arduino] Implementation of Basic Filters

Introduction

With the common presence of electronic noise, it is often found that the signal is distorted in ways that completely destroy the signal, or lead to huge inaccuracy of measurements. Therefore, the implementation of filters on system become imperative and indispensable.

In general, if the noise is oscillating or changing rapidly, we apply a low pass filter to remove the high frequency components; conversely, if the signal is distorted in a comparatively long time scale, we apply a high pass filter to remove the low frequency components.

There are multiple ways to implement a simple highpass and lowpass filters on arduino, most commonly – RC circuits (passive), Op-Amp (Active) and Discrete Time Algorithm. However, due to the negative gain for the Op-Amp approach which is usually not suitable for Arduino, only the other two methods will be addressed in this article.

Noted that this article is mainly for those who have no experience and prior knowledge in digital filters. For those who are looking for more advanced techniques, please wait for my other articles.

1. RC Circuits

1.1. High-Pass Filter

Screen Shot 2016-04-18 at 4.26.08 PM
Figure 1. First Order High-Pass Filter

The simplest first order high-pass filter can be implemented by a simple RC circuit, as shown in Figure 1, by connecting the input signal V_{in} across the capacitor C and resistor R, and the output signal V_{out} across the resistor R.

The cutoff frequency f_c can be calculated from the time constant (\tau), which is inversely proportional to the cutoff frequency:
f_c = \dfrac{1}{2\pi\tau} = \dfrac{1}{2\pi RC}

Noted that the output signal is NOT strictly zero or near-zero within cutoff frequency, and is NOT one or near-one beyond the cutoff frequency as this is only a first order filter. The magnitude of frequency response is likely to look like this:

Screen Shot 2016-04-18 at 5.26.57 PM
Figure 2. Magnitude Response of First Order High-Pass Filter

For Arduino, the V_{in} is simply the original analog input and V_{out} is the analog pin of Arduino. An example of schematic is shown below, with LM35 Temperature Sensor as the analog signal input.

high_pass_RC
Figure 3. Arduino Connection Diagram of High Pass RC Filter

1.2. Low-Pass Filter

250px-1st_order_lowpass_filter_rc-svg
Figure 4. First Order Low-Pass Filter

A first order low-pass filter can be implemented similarly with RC circuit, as shown in Figure 4, by connecting the input signal V_{in} across a series of resistor R and capacitor C, and the output signal V_{out} across the capacitor C.

The cutoff frequency of this low-pass filter is identical to that of high-pass filter mentioned previously:
f_c = \dfrac{1}{2\pi\tau} = \dfrac{1}{2\pi RC}

Similarly, this low-pass filter is only first order, not even close to ideal. The magnitude of frequency response will look like this:

Screen Shot 2016-04-18 at 5.38.34 PM
Figure 5. Magnitude Response of First Order Low-Pass Filter

The corresponding connection diagram for the low-pass filter is shown below:

lowpass
Figure 6. Arduino Connection Diagram of Low Pass RC Filter

As you can see from Figure 2 and Figure 5, the value of RC should be carefully chosen in order to achieve the desirable magnitude response, hence filtering effect.

 

2. Discrete Time Algorithm

2.1. High-Pass Filter

From the previous RC circuit, we can write down the following equations by Kirchhoff’s Law and definition of Capacitance:
\begin{cases} V_{out}(t) = I(t)R \\ Q_c(t) = C(V_{in}(t) - V_{out}(t))\\ I(t) = \frac{dQ_c}{dt}\end{cases}

After combining and solving the system of equations, we can derive:
V_{out}(t) = RC(\frac{dV_{in}}{dt} - \frac{dV_{out}}{dt})

Represent the input output signal V_{in}, V_{out} by discrete signals x[n], y[n], and discretize the differentiation, we can get a simple result:
y[n]= \alpha(y[n-1]+(x[n]-x[n-1])) \quad where\ \alpha = \frac{RC}{RC+\Delta t}

By choosing the value of filtering coefficient(\alpha), we can get different response and effect.

The code of the implementation is shown as follows:

const float alpha = 0.5;
double data_filtered[] = {0, 0};
double data[] = {0, 0};
const int n = 1;
const int analog_pin = 0;

void setup(){
    Serial.begin(9600);
}

void loop(){
    // Retrieve Data
    data[0] = analogRead(analog_pin);

    // High Pass Filter
    data_filtered[n] = alpha * (data_filtered[n-1] + data[n] - data[n-1]);

    // Store the previous data in correct index
    data[n-1] = data[n];
    data_filtered[n-1] = data_filtered[n];

    // Print Data
    Serial.println(data_filtered[0]);
    delay(100);
}

2.2. Low-Pass Filter

Similar to High-Pass Filter, we can write down a set of equations as the following:
\begin{cases} V_{in}(t) - V_{out}(t) = I(t)R \\ Q_c(t) = V_{out}(t)\\ I(t) = \frac{dQ_c}{dt}\end{cases}

Resulting in:
y[n] = \alpha x[n] + (1-\alpha)y[n-1] \quad where\ \alpha = \frac{\Delta t}{RC+\Delta t}

The corresponding code is:

const float alpha = 0.5;
double data_filtered[] = {0, 0};
const int n = 1;
const int analog_pin = 0;

void setup(){
    Serial.begin(9600);
}

void loop(){
    // Retrieve Data
    data = analogRead(analog_pin);

    // Low Pass Filter
    data_filtered[n] = alpha * data + (1 - alpha) * data_filtered[n-1];

    // Store the last filtered data in data_filtered[n-1]
    data_filtered[n-1] = data_filtered[n];
    // Print Data
    Serial.println(data_filtered[n]);

    delay(100);
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s