1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

digital filter

Discussion in 'Embedded' started by Doug Dotson, Oct 1, 2003.

  1. Doug Dotson

    Doug Dotson Guest

    Hi Group,

    About a year and a half ago someone (several someones actually) replied to a
    request for a simple digital low pass filter. I boiled it down to a single
    line of C, tested it and it worked great. Since then I have lost it. Used it
    to filter A/D readings. Anybody have this design
    handy?

    Thanks!
    Doug
     
    Doug Dotson, Oct 1, 2003
    #1
    1. Advertisements

  2. Doug Dotson

    CBFalconer Guest

    Try executing, at some interval,

    filtered = (filtered + newsample) / 2.
     
    CBFalconer, Oct 1, 2003
    #2
    1. Advertisements

  3. Doug Dotson

    Kelly Hall Guest

    I like having a time constant:
    filtered = (0.9 * filtered + 0.1 * newsample)

    Play around with it, it's not hard to get useful filtering.

    Kelly
     
    Kelly Hall, Oct 1, 2003
    #3
  4. Doug Dotson

    Ville Voipio Guest

    A very slight modification of this may be useful in some cases:

    The equation above is in the form:

    filtered = (1-k) * filtered + k * newsample

    This can be written:

    filtered = filtered + k * (newsample - filtered)

    Mathematically, these are identical. The second one does have some
    practical advantages, though:

    1. with small k (long decay time) and limited calculation
    precision the round-off errors are smaller
    2. with non-constant k there is no need for 1-k

    Computationally, the relative cost of these two ways depends on
    the relative cost of multiplication and addition (2 mult/1 add
    vs. 1 mult/2 add).

    - Ville
     
    Ville Voipio, Oct 1, 2003
    #4
  5. Doug Dotson

    Doug Dotson Guest

    I believe this is the one I remember:
    I picked k to be a power of 2 so that a shift instruction could be
    used for speed. I try these out.

    Thanks to all!
    Doug
     
    Doug Dotson, Oct 1, 2003
    #5
  6. Doug Dotson

    Ben Bradley Guest

    Yes, it's under "advanced search" on this webpage:
    http://groups.google.com
     
    Ben Bradley, Oct 1, 2003
    #6
  7. Doug Dotson

    Doug Dotson Guest

    Hummm. That's where I looked first. I try again.

    Doug
     
    Doug Dotson, Oct 1, 2003
    #7
  8. Spehro Pefhany, Oct 1, 2003
    #8
  9. Doug Dotson

    Doug Dotson Guest

    Doug Dotson, Oct 1, 2003
    #9
  10. Here is the very simplest digital lowpass:

    Y += (X-Y)*k

    X = input, Y = output

    Here is how k is defined:

    k = 1 - exp(-Fc/Fdis))

    where Fc = cutoff frequency, Fdis = sample rate

    Vladimir Vassilevsky

    DSP and Mixed Signal Design Consultant

    http://www.abvolt.com
     
    Vladimir Vassilevsky, Oct 1, 2003
    #10
  11. Doug Dotson

    Doug Dotson Guest

    Right! I picked n to be a power of 2 (8 actually in my application)
    and in C it turns into:

    y += (x - y) >> n;

    Works great!

    Doug
     
    Doug Dotson, Oct 1, 2003
    #11
  12. Doug Dotson

    Dave Hansen Guest

    I presume you mean "y += (x - y) >> p;" where "p" is the power rather
    than n (e.g., 3 rather than 8).

    But beware...
    On your platform. This revision.

    There are no guarantees that right shifting a signed value will yield
    the result you desire. You might get zeros shifted in regardless of
    the actual sign of the value being shifted.

    Most compilers are smart enough to make the "shift to divide by a
    power of two" optimization on their own. The following

    y += (x - y) / n;

    will be guaranteed to work, and should produce nearly identical code
    on your system.

    Regards,

    -=Dave
     
    Dave Hansen, Oct 2, 2003
    #12
  13. Doug Dotson

    CBFalconer Guest

    If it doesn't, and the speed turns out to be critical, he could
    use unsigned ints and a bias, such as INT_MAX. The input y would
    have to first be corrected to INT_MAX + yin, where yin is int and
    y is unsigned. The filtered y would need to be initialized to
    INT_MAX also. This assumes that INT_MAX is roughly 1/2 of
    UINT_MAX.

    So the result would be, more or less:

    #include <limits.h>

    unsigned int avg = INT_MAX;
    unsigned int sig;
    int input;

    #define FACTOR 3

    .....

    sig = (unsigned)input + INT_MAX)
    avg += (sig - avg) >> FACTOR;

    which also avoids triggering UB via integer overflows.
     
    CBFalconer, Oct 2, 2003
    #13
  14. Doug Dotson

    Doug Dotson Guest

    Oops! You ae correct.

    I didn't include all the contect of my application. 12 bit positive values,
    32 bit words.
    I've been doing this programming thing for a while :)

    Doug
     
    Doug Dotson, Oct 2, 2003
    #14
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.