Electronic – Using Analog potentiometer as a digital one to SW control

adcmicrocontrollerpotentiometer

I try to read an analog potentiometer that will control specific software functions.
That means that I want 0 fluctuations in its reading.

For this reason, moving average and other techniques do not work. What I want to do is to use this pot as a digital potentiometer with values from 0 to 63 (6bits) even though I am reading a 8bits value.

What is the best technique to achieve this?

Best Answer

What I want to do is to use this pot as a digital potentiometer with values from 0 to 63 (6bits) even though I am reading a 8bits value.

That's a tough problem, and it's probably impossible to solve reliably without exploiting the fact that you can, in fact, change the voltage across the potentiometer.

So, first of all, the 8-bit ADC is probably not the thing you'll want to use to determine the value of your resistance.

Discharge timer approach

Instead, you could implement a much higher-resolution ADC by using a timer/counter to determine the value of the potentiometer:

  1. Set an output (p1) pin to high. Use that to charge a capacitor that goes from that pin to ground and is in parallel to your potentiometer:

schematic

simulate this circuit – Schematic created using CircuitLab

  1. the time it takes to discharge the capacitor through the potentiometer depends on the value of R1 – and thus, by measuring that time, you can easily calculate R1!
    So, after charging the capacitor, reconfigure the output pin to an input pin.
  2. count the time it takes for the output to become low. Since your microcontroller certainly runs at several MHz, and you're free to choose C1 however large you want, this will give you a lot of resolution.

Problems here:

  1. It's hard to get very accurate capacitors
  2. the low/high transition will be temperature-dependent
  3. and so will be R1 even if you don't move it at all.

This is a very common approach – in fact, a lot of systems use this approach to measure a capacitance (in touch sensors), where the capacitor is adjustable but the resistor is fixed. It works.

Dithering for higher resolution

The problem that you have very finite resolution is one very well-understood mathematically. The solution is easy:

  1. You add noise of known probability distribution to the phenomenon you want to observe
  2. You observe the noisy observation and do statistics on the values
  3. you infer the phenomenon you wanted to observe from the statistic.

To illustrate:

  • assume you have a voltage \$V_0=4.2\$ V, but your ADC's decision boundaries are 4V and 5V.
  • You add some noise \$N\$ to your voltage with mean 0 V and some finite variance.
  • You measure the resulting noisy signal \$X=V_0+N\$ a lot of times (\$K\$ times), giving you a sequence of random observations \$X_k,\,k = 1,\ldots K\$.
  • The weak law of large numbers says that the average of a large number (\$K\$) of observations \$X_k\$ of a random variable \$X\$ converges to the actual expected value of \$X\$, i.e. \$\frac 1K \sum\limits_{k=1}^K X_k \rightarrow µ_{X_0}\$.

So, in short, you intentionally noise up your observation, but then average the result to cancel out the noise and get an actual estimate for the underlying value.

The problem here is that adding "some" noise and averaging isn't enough in your case, because your observations \$X_k\$ are quantized, and the amount of noise you need to "cross" a step depends on the position of the actual voltage inside your interval.

You'd basically would want to write a probability-maximizing estimator (maximum likelihood, ML estimator) that given some distribution of observed values gives you the likeliest true value.

However, in the case of low-kurtosis symmmetric zero-mean noise, and because you "only" need to gain a few bits in resolution to get a good measurement: Your average of observed values will be pretty close to your actual value, if you just observe a couple hundred values – and that should really be no problem for a microcontroller with an ADC!

So, add noise to the high-side voltage of your potentiometer. That can happen through a random number generator in your microcontroller firmware used to control a DAC, but it really also is reasonable to just flip a pin high and low randomly, and couple that capacitively into your readout.

Really, get better components

The above are cheap and easy solutions, but honestly: get an optical encoder if you actually want to have an accurate six bit turn knob. Potentiometers really aren't known for their accuracy, so what you'd be measuring would probably really not have enough bits of useful information to begin with, unless it's very expensive – what good is it if you can simulate having a 20 bit ADC, when the actual uncertainty of potentiometer contact and temperature makes for 5% error, easily?