Author Topic: Stabilizing analog read on a potentiometer  (Read 5587 times)

0 Members and 1 Guest are viewing this topic.

Offline EteslaTopic starter

  • Regular Contributor
  • *
  • Posts: 154
  • Country: us
Stabilizing analog read on a potentiometer
« on: July 19, 2019, 05:18:57 pm »
Hi all, I am trying to address an issue that pops up from time to time. When I use an ADC on a microcontroller to read a potentiometer, I find that more often than not, the ADC reading fluctuates a lot. For me, this is problematic. What are some ways to minimize ADC reading flickering? I believe that the solution will be in software, as no amount of filtering or caps across the potentiometer seem to help in the case where I have the pot adjusted right between two ADC steps. Is there a common sort of algorithm designed to deal with this, I imagine, fairly common issue? I'm thinking of some sort of averaging and buffer type stuff, but I don't want it to get too complicated. Thanks in advance!

p.s. I would have gone with an encoder, but the PCB is already made with the potentiometers, and I don't have time to make a new one
 

Offline guenthert

  • Frequent Contributor
  • **
  • Posts: 771
  • Country: de
Re: Stabilizing analog read on a potentiometer
« Reply #1 on: July 19, 2019, 05:55:07 pm »
I see there two distinct issues
i) fluctuations in the value reported by the ADC regardless of the source (typically referred to as "noise")
ii) fluctuations in the voltage when using the potentiometer as a voltage divider.

For i) check your ADC's (or microcontroller in this case) manual for noise specifications.  What you observe might be well within the specs.  The manufacturor might have also recommendations on how to minimize the noise (e.g. seperate analog and digital GND, turning off other facilities of the MCU during conversation, etc.).  And yes, this can be addressed also in software.  Easiest might be to throw away the lowest bits.  If your MCU has a 10b ADC, but you need to distinguish only some 100 potentiometer positions, you can mask the lower three or four bits.  With any luck, that's all you need to do.  Then there's of course averaging and decimation.  Lots of info (and application notes) about that.  Keep in mind that the noise is distributed across a wide spectrum, but the potentiometer is going to be turned only so fast --> digital low pass filter. Google is your friend.

ii) if the potentiometer isn't turned, there shouldn't be any noise (other then Johnson noise of course).  There might be some noise (non-monotonic change of potential at the wiper) when turning.  That can be reduced by connecting a capacity between the wiper and one of the other terminals.
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 15151
  • Country: de
Re: Stabilizing analog read on a potentiometer
« Reply #2 on: July 19, 2019, 06:08:24 pm »
Unless there is something really wrong (like missing decoupling, to high a pot value)  there should not be much noise in reading the potentiometer. How much depends on the µC. Normally the pot should use the same reference as the ADC - so both using VCC or both from an external reference.

The usual way to reduce noise is filtering in software, like averaging over several readings. Usually averaging 4 reading could reduce the noise by a factor of 2.   Averaging over a multiple if a power line period (e.g. 16.6 ms or 20 ms) can give additional suppression of power line related hum - however with just a pot this should normally not be an issue.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7192
  • Country: fi
    • My home page and email address
Re: Stabilizing analog read on a potentiometer
« Reply #3 on: July 19, 2019, 06:58:34 pm »
It is possible the ADC is flipping between two results, because the voltage it measures is between those two values.

Let's say the potentiometer value used is V. Sum N potentiometer samples at regular intervals into S.  If S <= (V-1)×N or S >= (V+1)×N, update V = S/N; otherwise keep V unchanged.

This means that the value you use for each potentiometer only changes every N samples.  You'll need at least a 16-bit variable for each potentiometer, and you might want to use a power of two N (16, 32, 64, 128, or 256) to keep the division simple.  (It also biases zero over 255, as it rounds towards zero.  That is fixable.)
« Last Edit: July 19, 2019, 07:04:43 pm by Nominal Animal »
 

Offline duak

  • Super Contributor
  • ***
  • Posts: 1048
  • Country: ca
Re: Stabilizing analog read on a potentiometer
« Reply #4 on: July 19, 2019, 07:40:00 pm »
What microcontroller or A/D are you using?  How many LS bits of noise are you seeing?

Do some values seem to be sticky or more common?  If the A/D is a successive approximation converter without using a Sample and Hold in front of it will tend to give a more noisy data stream.

Others have  suggested stronger or more effective filters by averaging a number of samples and may be needed to get around noisy data.

A code tragment implementing a simple low pass filter with characteristics similar to that of a first order filter is:

 static int result = 0;
 result = (GetAtoDSample() + result) >> 1;

What this does is take the newest sample and adds the previous value and then divides by two.  The previous value is of course half of the previous sample plus half of its previous value, and so on.  If I remember my constants correctly, an RC network is equivalent to the sum of 63.2 % of  the sample and 36.8 % of the previous value but that's a bit harder to do with simple adding and shifting.  Note that the variable result has to be persistant so that it can keep a running average of the samples.
« Last Edit: July 19, 2019, 07:44:52 pm by duak »
 

Offline patrick1

  • Contributor
  • Posts: 49
  • Country: au
Re: Stabilizing analog read on a potentiometer
« Reply #5 on: July 19, 2019, 07:55:15 pm »
sounds painful too try and solve via software, as pot deterioration over time will just make the problem worse irrespective of software.

really i would recommend, playing around too find a transistor setup, that you are charging a larger cap via resistors / transistor.   the analog guys can hopfully help with this.
 

Offline Sterno

  • Contributor
  • Posts: 20
  • Country: ca
Re: Stabilizing analog read on a potentiometer
« Reply #6 on: July 19, 2019, 08:29:22 pm »
I have had good luck filtering a noisy analog signal by taking 16 sucessive readings on the ADC, storing these in an array, summing the total and then shifting that result 2 bits to the right.

If I recall, method is called "decimate and shift" and is said to preserve accuracy which can be lost through standard averaging.
All depends on your required sample rate

  Code snippet from an Arduino Project below.



void readPressure()
{
  for (int i=0; i<16; i++)
  {
      valA = analogRead(pressureSensor);
      delay (5);
          samplingArray = valA;
  }

  for (int j=0; j<16; j++)
  {
    int x = samplingArray[j];   
    valB = valB + x;
  }
  pressureReading = valB >>2 ;
  valB=0;

}


*edit   Added details
« Last Edit: July 19, 2019, 08:31:31 pm by Sterno »
Electronic Engineering Technologist, Graybeard
Mostly Industrial Controls; PLCs, VFDs along some microcontroller and analog stuff.
 
The following users thanked this post: MagicSmoker, exe

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1950
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #7 on: July 19, 2019, 10:35:13 pm »
Start by eliminating some variables. Remove the pot and connect the A/D input to a fixed voltage source, for example a resistor divider with a cap from the center point to ground. Two equal, reasonably low value resistors will give you a decently low impedance source from which to charge the sample/hold amplifier. Confirm with a scope that the center point isn't too noisy (or all you'll be doing is sampling noise).

Convert that, and see what sort of behavior your A/D gives you. It should be reasonably stable, e.g. not wildly varying values. If this isn't stable, you have a problem in your circuitry, MCU-A/D configuration, or software. Work out those problems before reintroducing the pot.

Once things are stable when you have a stable input voltage, THEN add the pot. Any new issues will be related to the pot because you'll have confidence that the rest of your system is working.

Report back!
 

Offline EteslaTopic starter

  • Regular Contributor
  • *
  • Posts: 154
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #8 on: July 20, 2019, 11:06:24 pm »
Thank you all for your suggestions. I ended up trying averaging in software first since it came up a lot (using the 10 most recent readings, reading every 10 ms or so) and it worked a treat. I now get steady readings, and twisting the pot makes the numerical result have a cool interpolation effect where the number appears to approach and settle out to its final value. The problem I was describing I think only happened when the actual voltage being read was 'between' to ADC values, hence why adding capacitance didn't really do a whole lot. I might add some sort of hysteresis type stuff in software to make it even more robust against changing values, but for now this lightweight averaging solution is working great.
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1950
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #9 on: July 21, 2019, 02:41:34 am »
...twisting the pot makes the numerical result have a cool interpolation effect where the number appears to approach and settle out to its final value.
That's how filtering works. It's not "interpolation", it's settling. Totally predictable and expected behavior.

Quote
The problem I was describing I think only happened when the actual voltage being read was 'between' to ADC values
You're saying the original "ADC reading fluctuates a lot" was a single LSB? C'mon, it would be amazing if it DIDN'T fluctuate at least one LSB. That wasn't cause for concern, or comment, at all.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2785
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #10 on: July 21, 2019, 03:12:30 am »
Two other factors two consider are sampling time and source impedance, especially when the ADC is reading multiple channels in sequence.  Excessive impedance (IE, a high-value pot) and inadequate sampling time will mean that the ADC's sampling capacitor will not have adequate time to charge to the new input value before the ADC conversion is started.  The datasheet should describe the sampling capacitance and from that and the source impedance you can determine the sampling time required for a given resolution.
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 9330
  • Country: fi
Re: Stabilizing analog read on a potentiometer
« Reply #11 on: July 21, 2019, 09:59:16 am »
Two different things, with a common solution:

1) ADC input impedance requirement.  Say you have a 10k pot, acting as a series resistance. The ADC internally has a tiny (say, 20pF) sampling capacitor which is charged during a tiny sampling period (say, microseconds). It cannot charge completely through your high resistance during that time, so it shows some remaining charge left from previous conversions, causing strange fluctuations.

To solve this, you need a low-impedance driver, the options are:
a) A very low-value potentiometer (hundreds of ohms max), drawing power all the time,
b) opamp buffer
c) capacitor (between the ADC input and ground) orders of magnitude larger than the ADC sampling capacitor - say 10nF to 100nF is often just right.

The capacitor solution is obviously the cheapest and simplest (and the way to go), but the gotcha you need to know about is that you need to limit the conversion rate (i.e., don't leave the ADC freerunning at highest sample rate), so that the capacitor has time to replenish. Won't work with high-frequency stuff - works great with things you are going to sample slowly anyway (analog human interface devices, temperature sensors, battery voltages...)

2) filtration, for any reason. Now, if you use the cap for providing low impedance, it doubles as an analog RC filter as well. Two flies with one stone! In this regard, using a larger cap than strictly required due to #1 might make sense. So go for values like 1uF, and so on.

And,

3) if you still have a problem, consider adding software filtration. An analog RC only works on short timescales (otherwise, MASSIVE capacitors would be required), but a software filter can easily work over seconds or minutes if you need to.

A cumulative average (IIR filter) is easy:
static int32_t flt = 0;
flt = (15*flt + (int32_t)newest_val*256)/16;
filtered_value = flt/256;

(This example takes 1/16 (6.25%) of the newest value and 15/16 (93.75%) of the accumulated filtered value each time. Input value is multiplied by 256 and the result again divided by 256 to increase intermediate processing resolution.)


I'm almost sure your actual problem is simply caused by #1. A very typical catch for the young players, and the datasheets won't always mention this low impedance requirement clearly because they assume you know it.
« Last Edit: July 21, 2019, 10:07:40 am by Siwastaja »
 

Offline IconicPCB

  • Super Contributor
  • ***
  • Posts: 1564
  • Country: au
Re: Stabilizing analog read on a potentiometer
« Reply #12 on: July 21, 2019, 10:25:19 am »
In case of AVR ensure thevenin  equivalent resistance is less than 10K.
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 17427
  • Country: us
  • DavidH
Re: Stabilizing analog read on a potentiometer
« Reply #13 on: July 21, 2019, 12:27:31 pm »
You might be expecting too much.  The settability of a common single turn potentiometer is about 1 part in 100 or roughly 7 bits.  The best ones can achieve 1 part in 200 or roughly 8 bits.  So if you are expecting more than about 7 or 8 noise free bits, then forget it.

And this limitation gives a minimum goal for how much noise reduction should be done if you accept 7 or 8 bits at the most.  If I was starting from a 12 bit conversion, then I would average at least 12-7+1=6 bits of resolution away or 2^6=64 samples.  If you still have excessive noise after that, then look for sources in the hardware.

Beyond that, various schemes can be used to "divide" the potentiometer's travel into zones using hysteresis which will prevent quantization noise.  Modern test instruments often get this very wrong because few bother with human factors engineering.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3382
  • Country: gb
Re: Stabilizing analog read on a potentiometer
« Reply #14 on: July 21, 2019, 12:42:59 pm »
I have had good luck filtering a noisy analog signal by taking 16 sucessive readings on the ADC, storing these in an array, summing the total and then shifting that result 2 bits to the right.

If I recall, method is called "decimate and shift" and is said to preserve accuracy which can be lost through standard averaging.

This is using oversampling to generate more bits of resolution e.g. samplinge 16 times and you get 2 more bits of resolution, providing you have more than 0.5 LSB of noise present.  This will not reduce noise in the final value, in fact it will most likely increase it.
 

Offline Neomys Sapiens

  • Super Contributor
  • ***
  • Posts: 3268
  • Country: de
Re: Stabilizing analog read on a potentiometer
« Reply #15 on: July 21, 2019, 04:55:32 pm »
Another function that can help is a 'sliding window'. This would mean that you only use samples (the first, the last or the average) whose difference to each other stays within a certain amount.
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4857
  • Country: dk
Re: Stabilizing analog read on a potentiometer
« Reply #16 on: July 21, 2019, 05:08:40 pm »
I have had good luck filtering a noisy analog signal by taking 16 sucessive readings on the ADC, storing these in an array, summing the total and then shifting that result 2 bits to the right.

If I recall, method is called "decimate and shift" and is said to preserve accuracy which can be lost through standard averaging.

This is using oversampling to generate more bits of resolution e.g. samplinge 16 times and you get 2 more bits of resolution, providing you have more than 0.5 LSB of noise present.  This will not reduce noise in the final value, in fact it will most likely increase it.

with a few assumption on the noise such as a zero mean it can

 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1950
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #17 on: July 22, 2019, 02:19:08 am »
You might be expecting too much.  The settability of a common single turn potentiometer is about 1 part in 100 or roughly 7 bits.  The best ones can achieve 1 part in 200 or roughly 8 bits.  So if you are expecting more than about 7 or 8 noise free bits, then forget it.
Exactly, which is why I said that a toggling LSB isn't unexpected at all. The pot could cause it, noise on the signal from the pot could cause it, his supply rails could cause it... the list is long.

I haven't seen where he tells us the resolution of his A/D but I bet it's more than eight bits.  :palm:
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1950
  • Country: us
Re: Stabilizing analog read on a potentiometer
« Reply #18 on: July 22, 2019, 02:21:40 am »
Thank you all for your suggestions. I ended up trying averaging in software first since it came up a lot (using the 10 most recent readings, reading every 10 ms or so) and it worked a treat.
BTW, think in binary (or hex), not decimal. Unless you have a solid mathematical reason to average ten samples, try sampling eight or 16. The math becomes a matter of bit shifts instead of actual division, and processors are significantly more efficient at the former than the latter.
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 17427
  • Country: us
  • DavidH
Re: Stabilizing analog read on a potentiometer
« Reply #19 on: July 22, 2019, 03:22:03 am »
You might be expecting too much.  The settability of a common single turn potentiometer is about 1 part in 100 or roughly 7 bits.  The best ones can achieve 1 part in 200 or roughly 8 bits.  So if you are expecting more than about 7 or 8 noise free bits, then forget it.

Exactly, which is why I said that a toggling LSB isn't unexpected at all. The pot could cause it, noise on the signal from the pot could cause it, his supply rails could cause it... the list is long.

I haven't seen where he tells us the resolution of his A/D but I bet it's more than eight bits.  :palm:

12 bit microcontroller ADCs toggle a lot more than just the LSB even under ideal conditions.

The potentiometer will be quieter than practically any microcontroller ADC but the potentiometer's limited settability places a limit on precision so there is no reason not to filter the ADC output down to 7 or 8 bits at best removing most or all of the noise.

 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Stabilizing analog read on a potentiometer
« Reply #20 on: July 22, 2019, 08:18:23 am »
c) capacitor (between the ADC input and ground) orders of magnitude larger than the ADC sampling capacitor - say 10nF to 100nF is often just right.

The capacitor solution is obviously the cheapest and simplest (and the way to go)

^^^ This. 10k POT + 0.1uF, 10-20 samples/sec. No software averaging/integration whatsoever.

The potentiometer will be quieter than practically any microcontroller ADC but the potentiometer's limited settability places a limit on precision so there is no reason not to filter the ADC output down to 7 or 8 bits at best removing most or all of the noise.

Right. You just take 8 most significant bits out of ADC and you are done.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3382
  • Country: gb
Re: Stabilizing analog read on a potentiometer
« Reply #21 on: July 22, 2019, 09:08:49 am »
I have had good luck filtering a noisy analog signal by taking 16 sucessive readings on the ADC, storing these in an array, summing the total and then shifting that result 2 bits to the right.

If I recall, method is called "decimate and shift" and is said to preserve accuracy which can be lost through standard averaging.

This is using oversampling to generate more bits of resolution e.g. samplinge 16 times and you get 2 more bits of resolution, providing you have more than 0.5 LSB of noise present.  This will not reduce noise in the final value, in fact it will most likely increase it.

with a few assumption on the noise such as a zero mean it can

If you have zero noise then a) oversampling won't get you any more resolution, and b) you don't need any noise filtering to start with.
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4857
  • Country: dk
Re: Stabilizing analog read on a potentiometer
« Reply #22 on: July 22, 2019, 12:52:51 pm »
I have had good luck filtering a noisy analog signal by taking 16 sucessive readings on the ADC, storing these in an array, summing the total and then shifting that result 2 bits to the right.

If I recall, method is called "decimate and shift" and is said to preserve accuracy which can be lost through standard averaging.

This is using oversampling to generate more bits of resolution e.g. samplinge 16 times and you get 2 more bits of resolution, providing you have more than 0.5 LSB of noise present.  This will not reduce noise in the final value, in fact it will most likely increase it.

with a few assumption on the noise such as a zero mean it can

If you have zero noise then a) oversampling won't get you any more resolution, and b) you don't need any noise filtering to start with.

zero _mean_

 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7192
  • Country: fi
    • My home page and email address
Re: Stabilizing analog read on a potentiometer
« Reply #23 on: July 22, 2019, 02:18:32 pm »
langwadt is correct.

While it might be unintuitive, it is easy to see how this happens if we apply a bit of math here.  (Lemme know if you don't want me to post this kind of posts, BTW.)

To describe the noise, we need to know two of its parameters: its mean (which we assume is zero here), and its standard deviation σ.  The noise distribution does not need to be Gaussian, as we only use σ as a measure of the noise magnitude: by definition, 68.3% of noise samples are within σ of its mean.

When we average samples, zero-mean-noise tends to cancel itself. With an N-sample average, the standard deviation of the noise is σ/N.
To work this out, let xi be the noiseless samples, and yi be the corresponding sampled noise, so that the actual measurement i is (xi + yi).  When you take the average of those N actual measurements, you can split the sum into two, and get the mean of the noiseless samples plus the average mean of the noise samples.  (If you do the same keeping the standard deviation labeling, using any notation you want, you'll see that averaging over N samples, the standard deviation of the noise is indeed σ/N.)

(In fact, if we know both the mean and the standard deviation of the noise, and the original signal is sufficiently stable (low change rate), the noise can be compensated to give a similar result, i.e. 1/N reduction in the magnitude of the noise, if their dependency on the original signal is such that every unique measurement mean corresponds to a specific original signal mean.  But you might get stuff like differential equations that have to be numerically solved to do that.  It is useful with e.g. very sensitive low-temperature sensors, where the thermal noise can we well characterized and thus compensated for.)

My own post above attempted to point out that if you use integer math (and with microcontrollers, you usually prefer integer math, unless your microcontroller has fast hardware floating point capabilities at sufficient precision), you'll want to do hysteresis and other similar analysis in the sum, prior to the division, because although the noise is higher, the added precision allows correspondingly more precise controls.  My example shows that if your noise is ±0.5 bits (-1-0 or 0+1, or something in between) in the averaged value, with a bit of smart hysteresis in the sum you can keep the averaged value stable and noise-free.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf