5
\$\begingroup\$

I'm using an ADC (adc081c021) with a pretty noisy input:

There is also a 5-second video here: http://tinypic.com/player.php?v=2ue47cm&s=5

The objective is to detect the two peaks. How could I smooth this input in order to have better ADC readings? Is there a better option than a LC filter? Any recommended values?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You haven't mentioned what sort of signal you are reading but it would be worthwhile investigating whether the noise is expected. If it is unexpected, it may be indicative of a design flaw and the better solution would be to eliminate the source of the noise rather than filter it out. \$\endgroup\$
    – Amoch
    Commented May 22, 2013 at 5:57

3 Answers 3

10
\$\begingroup\$

Since you have an example of the signal on your scope, the best thing to do is capture the data and transfer it to a PC. Then use a tool like Matlab or Octave to simulate the effect of different filters.

You are looking for a filter, just defined in terms of poles (and maybe zeros) that minimizes the noise, without disturbing the desired features of the signal.

When you have a filter definition, then worry about how to build it.

If a single-pole filter is adequate, a simple RC circuit solves your problem.

For a two-pole filter, the Sallen-Key op-amp circuit is known for having relatively good tolerance for changes in the component values. An LC combination is also possible.

For higher-order filters (which I doubt you need), a cascade of Sallen-Key filters is preferable to a ladder of LC stages, because the op-amp provides buffering that prevents component value shifts in one stage from affecting the characteristics of other stages.

Edit In reply to your comment, I'm not a DSP guy, but here's how I'd work out the equivalent continuous time filter:

Your filter function in discrete time is

\$y_n = a x_n + (1-a) y_{n-1}\$

Given an impulse input, the time constant is the time it takes to decay to \$e^{-1}\$ of the value of \$y_0\$.

This is given by

\$(1-0.025)^n = e^{-1}\$

Solving this, n is about 39 samples, or 156 us.

So you want to choose R low enough that the input impedance of the ADC doesn't affect the filter performance much, then choose C to give RC = 156 us.

\$\endgroup\$
2
  • \$\begingroup\$ OK, I have followed your advice. I have imported that graph to Matlab. There are 2500 points over 10ms. I have then analyzed a single-pole filter: filter(a, [1 a-1], noisy_trace). A value of a=0.025 is a good trade-off. How do I translate this value to the frequency cut-off and the RC values? \$\endgroup\$ Commented May 24, 2013 at 2:21
  • \$\begingroup\$ I thought it would be nice to show the result of the RC filter: Before: i.sstatic.net/yBwDq.jpg After: i.sstatic.net/2EwHf.jpg \$\endgroup\$ Commented May 27, 2013 at 2:12
3
\$\begingroup\$

A quick and simple option to investigate is to average the ADC values over a given number of measurements, resulting in a simple low pass filter. Best option would be a ring buffer of a certain size in which you push the most recent value at the end and average across all values in it. This method does come with a maximum delay of the ring buffer length times sample frequency.

\$\endgroup\$
1
  • \$\begingroup\$ Still have to think about aliasing for this approach. If you've already aliased the high freq noise to, say, 0.1 Hz, that won't go away. \$\endgroup\$ Commented May 22, 2013 at 10:36
0
\$\begingroup\$

What I would do would be to only use the ADCs input if the value was higher than x. You can do this by using a comparator to check if the value is above x and then reading the ADC if it is.

\$\endgroup\$
1
  • \$\begingroup\$ This is what I'm currently doing. But, sometimes the noise creates some trouble. It's the reason why I would like to add a filter in the input to help. \$\endgroup\$ Commented May 22, 2013 at 4:32

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