Arduino-Filters icon indicating copy to clipboard operation
Arduino-Filters copied to clipboard

Converting Butterworth LPF to HPF

Open MichaelSeaman opened this issue 4 years ago • 1 comments

Hi Pieter and team,

In going through your example code for the Butterworth filter library, I notice there's no example of a HPF, just a low pass. While I know you discuss the conversion of the transfer function in your github io page, I can't seem to understand how to specify those changes to the transfer function while using the library.

To use the same examples from Butterworth.ino, what would the values of f_s, f_c, and f_n have to be in order to implement an equivalent high pass filter with cutoff 25Hz and sample rate 100Hz?

Thanks

MichaelSeaman avatar Mar 10 '22 02:03 MichaelSeaman

I figured that you need to change the butter_coeff function, in particular the b-coefficients in the four make_... functions. Here is a copy of those functions with b-coefficients for a high pass filter:

auto make_sos = [=](uint8_t k) {
    const double gamma2 = gamma * gamma;
    const double alpha = 2 * std::cos(2 * M_PI * (2 * k + N + 1) / (4 * N));
    return BiQuadCoefficients<T>{
        {{T(gamma2 * 1.), T(gamma2 * (-2.)), T(gamma2 * 1.)}}, // b0, b1, b2
        {{
            T(gamma2 - alpha * gamma + 1), // a0
            T(2 * (1 - gamma2)),           // a1
            T(gamma2 + alpha * gamma + 1), // a2
        }},
    };
};
auto make_fos = [=]() {
    return BiQuadCoefficients<T>{
        {{T(gamma * 1.), T(gamma * (-1.))}}, // b0, b1
        {{
            T(gamma + 1), // a0
            T(1 - gamma), // a1
        }},
    };
};

auto make_sos_norm = [=](uint8_t k) {
    const double gamma2 = gamma * gamma;
    const double alpha = 2 * std::cos(2 * M_PI * (2 * k + N + 1) / (4 * N));
    const double a0 = gamma2 - alpha * gamma + 1;
    return BiQuadCoefficients<T>{
        {{T(gamma2 * 1. / a0), T(gamma2 * (-2.) / a0), T(gamma2 * 1. / a0)}}, // b0, b1, b2
        {{
            T(1.),                                // a0
            T(2 * (1 - gamma2) / a0),             // a1
            T((gamma2 + alpha * gamma + 1) / a0), // a2
        }},
    };
};
auto make_fos_norm = [=]() {
    const double a0 = gamma + 1;
    return BiQuadCoefficients<T>{
        {{T(gamma * 1. / a0), T(gamma * (-1.) / a0)}}, // b0, b1
        {{
            T(1.),               // a0
            T((1 - gamma) / a0), // a1
        }},
    };
};

I am not 100% sure this is correct, but at first glance it worked.

matlen avatar Nov 05 '24 22:11 matlen