3
\$\begingroup\$

I find the following code for a simple implementation of a low pass filter.

#define alpha 0.1

accelX = (acceleration.x * alpha) + (accelX * (1.0 - alpha));

I have been experimenting with the value for alpha. But I want to know how exactly we can find this value for accelerometer data (in Android). I understand that we would need the sampling rate and the cut off frequency. How can I find the cut off frequency for this kind of data(I guess this involves noise modelling and finding its frequency range? If so how should I do it? )

\$\endgroup\$
5
\$\begingroup\$

Y[n]=aX[n]+(1-a)Y[n-1]

It's an autoregressive moving average-- an infinite impulse response filter. Start with the equation above, take the z transform, and that gives the frequency response. It has nothing to do with the noise model.

Here's the freq response for alpha =0.9, the frequency axis is scaled from 0 to your Nyquist frequency (half your sampling freq) generated in Octave by freqz(0.9, [ 1 -0.1])

alpha=0.9

alpha=0.6 freqz(0.6, [ 1 -0.4]) alpha=0.6

\$\endgroup\$
0
\$\begingroup\$

What you have is the equation for a single pole low pass filter. This is the discrete equivalent of the analog R-C filter. While your equation is correct, I like to write it as

FILT <-- FILT + FF(NEW - FILT)

because this is a little more convenient to realize in a microcontroller in most cases.

Usually the time domain view of the filter is more directly usable when implementing one of these in a microcontroller. Most of the time you are more concerned about sample rate and response time than the frequency rolloff. However, the latter does come up, which is why I built some facilities for manipulating this into my PIC preprocessor. The documentation snippet of the two relevant inline functions is:

  FFTC2 tcfilt sfreq

       Computes the filter fraction of a single pole low pass filter.
       TCFILT is the 1/2 decay time of the filter, and SFREQ is the sample
       frequency.  The filter fraction is the weighting fraction of the
       incoming signal each filter iteration.  The result data type is
       floating point.

  FFFREQ ffreq sfreq

       Computes the filter fraction of a single pole low pass filter.
       FFREQ is the desired -3dB rolloff frequency of the filter, and
       SFREQ is the sample frequency.

I worked out the math at the time I wrote the code for those functions, so I'll just refer you to that instead of re-deriving it now:

*   FFTC2 tcfilt sfreq
}
4: begin
  if not term_get (fstr, p, val) then goto arg_missing;
  a1 := val_fp (val);                  {get power of 2 time constant}
  if not term_get (fstr, p, val) then goto arg_missing;
  a2 := val_fp (val);                  {get sampling frequency}

  r := 1.0 - 0.5 ** (1.0 / (a1 * a2)); {make the filter fraction}

ret_r:                                 {common code to return FP value in R}
  str_from_fp (r, tk);                 {make floating point string in TK}
  string_append (lot, tk);             {append floating point string to the output}
  end;
{
********************
*
*   FFFREQ ffreq sfreq
}
5: begin
  if not term_get (fstr, p, val) then goto arg_missing;
  a1 := val_fp (val);                  {get filter rolloff frequency}
  if not term_get (fstr, p, val) then goto arg_missing;
  a2 := val_fp (val);                  {get sampling frequency}

  r := pi2nv / a1;                     {make standard power of E time constant}
  r := 1.0 - env ** (1.0 / (r * a2));  {make the filter fraction}
  goto ret_r;                          {return the value in R}
  end;

The actual math of the FFFREQ function is only two lines of code, so you can figure it out. It looks like this relies on some definitions at the top of the file:

{
*   Physical constants.  Don't mess with these.
}
  pi = 3.14159265358979323846;         {what it sounds like, don't touch}
  e = 2.718281828;                     {ditto}
  pi2 = 2.0 * pi;                      {2 Pi}
  pi2nv = 1.0 / pi2;                   {1 / 2Pi}
  env = 1.0 / e;                       {1 / e}
  ln2 = ln(2.0);                       {natural log of 2}

If you happen to be doing this on a PIC, you might want to use the preprocessor. It is included in the PIC Development Tools release at http://www.embedinc.com/pic/dload.htm. The source code for the preprocessor is included in the Host source code and everything release.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.