High Pass Filtering Engine Speed Sensor Signal

Hello Guys,

I am currently working on a project where I am required to high pass filter the signal coming from engine speed sensor.

Upon looking up from online, I found this website to be useful for this project “http://t-filter.engineerjs.com/

I successfully generated the code from the following website. It generated two files named “SampleFilter.h” and “SampleFilter.cpp”. I placed this files in library.

However, I was unable to implement it. So, I referred to the old thread https://forum.arduino.cc/index.php?topic=214294.0. See, reply number 8 in old thread.

When I do that I get the following error.

Arduino: 1.8.8 (Windows 7), TD: 1.45, Board: "Arduino/Genuino Uno"

C:\Users\Documents\Arduino\High_pass_Digital_Filter_-_Example\High_pass_Digital_Filter_-_Example.ino: In function 'void setup()':

High_pass_Digital_Filter_-_Example:12:28: error: cannot convert 'SampleFilter' to 'SampleFilter*' for argument '1' to 'void SampleFilter_init(SampleFilter*)'

   SampleFilter_init(x, data);

                            ^

C:\Users\Piyush\Documents\Arduino\High_pass_Digital_Filter_-_Example\High_pass_Digital_Filter_-_Example.ino: In function 'void loop()':

High_pass_Digital_Filter_-_Example:19:20: error: 'x' was not declared in this scope

   SampleFilter_put(x, data);

                    ^

exit status 1
cannot convert 'SampleFilter' to 'SampleFilter*' for argument '1' to 'void SampleFilter_init(SampleFilter*)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Code I have used:

#include<SampleFilter.h>

float data;
float dataFiltered;


void setup() 
{
  Serial.begin(9600);
  pinMode(A0, INPUT);
  SampleFilter x;
  SampleFilter_init(x, data);
}


void loop() {

  data = analogRead(A0);
  SampleFilter_put(x, data);
  dataFiltered = SampleFilter_get(x);
}

SampleFilter.H Code:

#ifndef SAMPLEFILTER_H_
#define SAMPLEFILTER_H_

/*

FIR filter designed with
 http://t-filter.appspot.com
TFilter - Free online FIR filter design
Free online FIR filter design application
t-filter.appspot.com


sampling frequency: 200 Hz

* 0 Hz - 8 Hz
  gain = 0
  desired attenuation = -40 dB
  actual attenuation = -40.04993485721124 dB

* 10 Hz - 100 Hz
  gain = 1
  desired ripple = 0.1 dB
  actual ripple = 0.07330968816777028 dB

*/

#define SAMPLEFILTER_TAP_NUM 219

typedef struct {
  double history[SAMPLEFILTER_TAP_NUM];
  unsigned int last_index;
} SampleFilter;

void SampleFilter_init(SampleFilter* f);
void SampleFilter_put(SampleFilter* f, double input);
double SampleFilter_get(SampleFilter* f);

#endif

SampleFilter.CPP Code:

#include "SampleFilter.h"

static double filter_taps[SAMPLEFILTER_TAP_NUM] = {
  0.0024719397148325233,
  0.0007517354364036728,
  0.000797432922894658,
  0.0007936830325604661,
  0.0007348026784040049,
  0.0006190382454123439,
    -0.0011938614038273833,
  -0.0012155397917699377,
  -0.0011498941976956628,
  -0.0010060440314786762,
  -0.000802234535218678,
  -0.000555181337439991,
  -0.00028706206887729914,
  -0.00001800050144614273,
  0.00023276934193141558,
  0.00044916920811302656,
  0.0006190382454123439,
  0.0007348026784040049,
  0.0007936830325604661,
  0.000797432922894658,
  0.0007517354364036728,
  0.0024719397148325233
};

void SampleFilter_init(SampleFilter* f) {
  int i;
  for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i)
    f->history[i] = 0;
  f->last_index = 0;
}

void SampleFilter_put(SampleFilter* f, double input) {
  f->history[f->last_index++] = input;
  if(f->last_index == SAMPLEFILTER_TAP_NUM)
    f->last_index = 0;
}

double SampleFilter_get(SampleFilter* f) {
  double acc = 0;
  int index = f->last_index, i;
  for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) {
    index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1;
    acc += f->history[index] * filter_taps[i];
  };
  return acc;
}

Thanks in advance for any criticism you can provide.

Why not design an analog HPF in circuitry? It would be a LOT easier IMHO.

You need to declare your samplefilter at top level, and you need to pass its address to the init function.

Thanks for reply guys. I Appreciate your time and your responses.

@Power_broker Due to space constraints in my PCB board we went with digital filter.

@MarkT I already tried your before posting here. It didn’t work out. I hope I did it right. Please, correct me if I’am wrong.

#include<SampleFilter.h>

float data;
float dataFiltered;
SampleFilter x;


void setup()
{
  Serial.begin(9600);
  pinMode(A0, INPUT);
  SampleFilter_init(*x, data);
}


void loop() {

  data = analogRead(A0);
  SampleFilter_put(x, data);
  dataFiltered = SampleFilter_get(x);
}

I got the following error.

Arduino: 1.8.8 (Windows 7), TD: 1.45, Board: "Arduino Duemilanove or Diecimila, ATmega328P"

C:\Users\Documents\Arduino\High_pass_Digital_Filter_-_Example\High_pass_Digital_Filter_-_Example.ino: In function 'void setup()':

High_pass_Digital_Filter_-_Example:13:21: error: no match for 'operator*' (operand type is 'SampleFilter')

   SampleFilter_init(*x, data);

                     ^

C:\Users\Documents\Arduino\High_pass_Digital_Filter_-_Example\High_pass_Digital_Filter_-_Example.ino: In function 'void loop()':

High_pass_Digital_Filter_-_Example:19:27: error: cannot convert 'SampleFilter' to 'SampleFilter*' for argument '1' to 'void SampleFilter_put(SampleFilter*, double)'

   SampleFilter_put(x, data);

                           ^

High_pass_Digital_Filter_-_Example:20:36: error: cannot convert 'SampleFilter' to 'SampleFilter*' for argument '1' to 'double SampleFilter_get(SampleFilter*)'

   dataFiltered = SampleFilter_get(x);

                                    ^

exit status 1
no match for 'operator*' (operand type is 'SampleFilter')

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

meme:
@Power_broker Due to space constraints in my PCB board we went with digital filter.

Welp, in that case, have fun with signal aliasing :slight_smile:

Solved the issue. I used other FIR library I found online under name "Geophysical LLC by Leeman". He did a great job in making that library flexible.

If anyone is trying to compute FIR filter coefficients I suggest going to Iowa FIR Filter Design, Software and Examples. That is very powerful software than T-filter that everybody has suggested.

@power broker I feel Aliasing isn't issue for me. I am dealing with 6000Hz max frequency for my application.

If there is aliasing issues I would do what you have suggested.

meme:
@power broker I feel Aliasing isn't issue for me. I am dealing with 6000Hz max frequency for my application.

If there is aliasing issues I would do what you have suggested.

If you're trying to measure a 6KHz signal with a 16MHz MCU that is running extra processing (i.e. the digital filter and other things in your code), you will most definitely run into aliasing

Why don't you design an analog HPF in circuitry?