Low Pass Filter Bessel C / C++ Implementation
Some time ago while working on a vehicle crash simulation system we needed to simulate a Bessel low pass filter.
These hardware Bessel filter are used to “smooth out” signals from a acceleration sensor. Some sensors output a pulse-width modulated signal. After letting it pass through a Bessel filter we get a pseudo integral type signal. You can use these filters with any sample rate you like. The cut off frequency is mentioned below as a factor of the actual sample rate you are using. For example, 0.04.
The below code implements a Bessel 4th order low pass filter in C / C++ with double precision. Note that the so-called cut off frequency is the factor 0.04 of the sampling frequency. For example, if sampled at 10kHz, the cut off is 0.04 * 10000 = 400 Hz
// cuts off at 0.04 * sampling freq
void BesselLowpassFourthOrder004(const double source[], double dest[], int length)
{
double xv[4+1] = {0.0},
yv[4+1] = {0.0};
for (int i = 0; i < length; i++)
{
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = source[i] / double(1.330668083e+03);
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4];
yv[4] = (xv[0] + xv[4]) + 4 * (xv[1] + xv[3]) + 6 * xv[2]
+ ( -0.3041592568 * yv[0]) + ( 1.5960375869 * yv[1])
+ ( -3.1910200543 * yv[2]) + ( 2.8871176889 * yv[3]);
dest[i] = yv[4];
}
}
Below is the same Bessel low pass filter as 3rd order:
// cuts off at 0.04 * sampling freq
void BesselLowpassThirdOrder004(const double src[], double dest[], int size)
{
double xv[3+1] = {0.0};
double yv[3+1] = {0.0};
for (int i=0; i<size; i++)
{
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];
xv[3] = src[i] / double(2.711023309e+02);
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];
yv[3] = (xv[0] + xv[3]) + 3 * (xv[1] + xv[2])
+ ( 0.4226750651 * yv[0]) + ( -1.6550518354 * yv[1])
+ ( 2.2028676179 * yv[2]);
dest[i] = yv[3];
}
}
The same cut off frequency again but 2nd order Bessel low pass:
// cuts off at 0.04 * sampling freq
void BesselLowpassSecondOrder004(const double src[], double dest[], int size)
{
double xv[2+1] = {0.0}, yv[2+1] = {0.0};
for (int i = 0; i < size; i++)
{
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = src[i] / double(5.050469146e+01);
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = (xv[0] + xv[2]) + 2 * xv[1] + ( -0.5731643146 * yv[0]) + ( 1.4939637515 * yv[1]);
dest[i] = yv[2];
}
}
And this code simulates a 0.036 cut off frequency (360Hz at 10kHz sample rate), 2nd order Bessel low pass filter:
// cuts off at 0.036 * sampling freq
void BesselLowpassSecondOrder0036(const double src[], double dest[], int size)
{
double xv[2+1] = {0.0}, yv[2+1] = {0.0};
for (int i = 0; i < size; i++)
{
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = src[i] / double(6.089464560e+01);
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = (xv[0] + xv[2]) + 2 * xv[1] + ( -0.6062613139 * yv[0]) + ( 1.5405740936 * yv[1]);
dest[i] = yv[2];
}
}

sir, can you please explain how this code can be used for filtering a data from ADC in PIC microcontroller
do you have floating point arithmetic in the microcontroller?
If not it won’t work without adaptation…