ADC input filtering for precision instrument

Thread Starter

M*P

Joined Mar 14, 2017
2
Hi!

I am not a very experienced designer and was wondering if anybody could offer advice on the following issue:

I am designing a length measurement gauge with a high precision linear potentiometer as a sensor.

I am using ADS1115 16-bit ADC to digitise the output which is then fed into Arduino Micro for processing. The potentiometer is a physically large component ( circa 130 mm long) with fairly long leads ( > 200 mm). It seems to pick-up a bit of noise which causes lack of stability in ADC output.

The application is very static. I.e once the gauge reaches its measurement position it will stay there for several seconds. As a result the sensor output will not be varying rapidly. Putting layout, grounding and power supply issues aside, I was wondering if I could use a low pass filter with a very low cut off frequency to clean up the signal and stabilise ADC output. Please see the schematic in the attachment.

Is this circuit a sensible approach or should I try something else?

The overall design goal is to measure sensor voltage as accurately as possible using 16 - bit ADC.

I would welcome any constructive advice.

Thanks!
 

Attachments

OBW0549

Joined Mar 2, 2015
3,566
Is this circuit a sensible approach or should I try something else?
I think the filter would be better placed at the input to your buffer rather than at the output, and would be simpler: just put a 0.022μF capacitor from the buffer input to ground. That, along with the 500kΩ resistor in series with the wiper, will give you a ≈14 Hz rolloff frequency.
 

AnalogKid

Joined Aug 1, 2013
12,126
Agree with OBW. Spend money on the capacitor for low dielectric absorption and low leakage. Another advantage is that some A/D converters, like ones that are capacitor-based, can have a relatively low and non-constant input impedance. The 1K resistor creates a small error term with that impedance.

ak
 
Last edited:

MrAl

Joined Jun 17, 2014
13,702
Hello,

Another idea that is widely used is to average the input using code. The code simply takes the average of a large number of readings, however the implementation varies as to how to do this.

One way is to just sum up a bunch of readings, then divide by the number of readings.
Another way is to use a moving average, where the average is updated with every reading based on the old reading and the new reading. This actually ends up being like a digital low pass filter implementation.
For one example:
old=(old*15+new)/16

This weighs the old reading by 15 and the new reading by 1. The general form is simply:
old=(old*(N-1)+new)/N

where in that case N=16.

N can be varied based on the change from one reading to the next also, which creates an adaptive filter, something that is very hard to do in analog design. Large N makes the filter have a lower cutoff frequency similar to how large RC makes a low cutoff in analog design.

The side benefit is that if you have any noise you might get a little better resolution due to oversampling. When you use a physical low pass filter with R and C you loose that benefit.

That said, i have used both, and went as high as 100uf on the cap value for super filtering, and as high as 4096 on the value of N for the digital filter.

There are other more complicated digital filters also, which come from transforming an analog filter of any kind into a digital filter.
 

crutschow

Joined Mar 14, 2008
38,503
I agree that an analog front-end filter plus digital averaging (I prefer a moving average) is a good technique for your requirements. It should be able to get the noise deviation down to below 1 LSB.
Both are easy to implement.

If you wanted to get fancy to improve the response time to a change in signal level, you could modify the digital averaging, as determined by that change.
Thus, the processor continually looks at the difference between the averaged signal and the unaveraged signal.
If there is a significant difference beyond the noise level, indicating the gauge position has changed, you dump the previous average, replace it by a new (unaveraged) value, and then start averaging again.
That will minimize the long response-time tail in the reading to a change in gauge position.
 
Last edited:

Thread Starter

M*P

Joined Mar 14, 2017
2
First of all I just want to say that as a newcomer I am truly amazed by the the amount and quality of advice. It truly seems that this forum is a great resource!

@joeyd999 In the hindsight a linear encoder would have been better (this is linear not rotary application), you are absolutely right. This is preferred solution for coordinate measurement machines, so certainly is v. accurate. Unfortunately mechanical components have been sent out for manufacturing so I am tied to the potentiometer at this point.

Following your advice I think I will use analog filter on the input (before buffer) and add a rolling-average filtering in the software. This should make the reading nice and steady.

I will report back once I have some results.

Thanks!
 

crutschow

Joined Mar 14, 2008
38,503
......
Following your advice I think I will use analog filter on the input (before buffer) and add a rolling-average filtering in the software. This should make the reading nice and steady.
And if you find the settling time tail is too long for the amount of filtering required to get the desired steady output reading, then you can try adding the average value reset upon a change in signal value technique I suggested.
 

paul510

Joined Mar 11, 2017
6
The potentiometer is a physically large component ( circa 130 mm long) with fairly long leads ( > 200 mm). It seems to pick-up a bit of noise which causes lack of stability in ADC output.
Twisting the leads will help reducing pickup. Also, you can improve the digital averaging technique suggested in other posts if you identify the dominant noise frequency: usually it will be the ac line frequency (50/60Hz) and/or its harmonics. To filter this dominant frequency just set the digitizing frequency to an integer multiple of the double of this frequency. For example, averaging four measurements made every 5ms will remove 50Hz and 100Hz components. The ADS1115 has a programmable digitizing rate so it should be easy to implement this without need to adjust some delays in the Arduino code.
 

MrAl

Joined Jun 17, 2014
13,702
If you wanted to get fancy to improve the response time to a change in signal level, you could modify the digital averaging, as determined by that change.
Thus, the processor continually looks at the difference between the averaged signal and the unaveraged signal.
If there is a significant difference beyond the noise level, indicating the gauge position has changed, you dump the previous average, replace it by a new (unaveraged) value, and then start averaging again.
That will minimize the long response-time tail in the reading to a change in gauge position.
Hi,

Just to note, that's an adaptive filter and rather than just dump any values the value of N can be changed, which is equivalent to lowering the value of RC in an analog filter. See post #7. This allows some filtering to still take place while allowing the readings to update faster.
Ultimately the derivative(s) would tell us more information about how the input is changing but that's another story. For example concave up would tell us the signal is changing fast while concave down would tell us it is starting to level off.
 
Top