1
\$\begingroup\$

A recurring problem with analogue potentiometers is to get a stable output that only changes when the pot is actually moved (i.e. it doesn't output a lot of extremely similar values due to noise or jitter). What is the best approach to account for this?

I can think of a couple of approaches:

  1. Timeout: enable a deadzone after a second or two if the knob isn't moved by a certain amount.
  2. Moving deadzone: every time the read value leaves the deadzone, recenter it on the new value.

Note that pure filtering doesn't solve the problem - when you quantise the filtered value it can always be half-way between two quantisation levels and flutter between them.

Does anyone have any more solutions?

Edit: To be clear, this is why averaging, filtering, a better potentiometer, ignoring the LSB etc won't work:

Suppose we have this voltage after filtering/averaging whatever:

noisy

Then suppose we quantise to the nearest 0.1. We'll get an output that jitters around:

jittery

Hopefully you can see that no matter how good your filtering, or how coarse your quantisation, there will always be the possibility of jittering. That is why you need something other than really good filtering or really coarse quantisation.

Edit 2: To be doubly clear, because it seems some people aren't getting this. I would like some method to completely eliminate this kind of jitter (which is caused by unavoidable noise in the system), while still responding 'nicely' to a user physically turning the pot (it's for a brightness knob).

Edit 3: To be triply clear (come on guys), I only want the value to change when the pot has been physically moved because acting on these changes is costly (the display flickers when the brightness is changed; I don't want it flickering continuously).

\$\endgroup\$

closed as unclear what you're asking by Scott Seidman, Andy aka, Voltage Spike, Daniel Grillo, Dave Tweed Oct 31 '16 at 20:59

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ And how does this proposed technique work for the volume control in your old fashioned radio? \$\endgroup\$ – Andy aka Oct 30 '16 at 21:02
  • 1
    \$\begingroup\$ @EM Fields: Ignoring the LSB is just quantising, and that won't work if the true value is half-way between two quantisations values because the noise will be enough to flitter between the two values. \$\endgroup\$ – Timmmm Oct 31 '16 at 9:06
  • 3
    \$\begingroup\$ I'm thinking a hysterisis based solution here. So that your up and down transition levels are different. Toy example: a 2 bit ADC with transition levels 0, 1, 2, 3 volts rising and 0, 0.9, 1.9, 2.9 falling. The difference would have to be greater than your expected noise level of course. \$\endgroup\$ – Ian Bland Oct 31 '16 at 11:29
  • 2
    \$\begingroup\$ You haven't explained why a bit of jitter is bad. You've alluded to it in your comment to Olin Lathrop, but not explained it. You are controlling the brightness by reading the pot, then you are sending this to some other system that is "a bit broken." Explain what is broken, what the effect is, and why small variations are a problem. \$\endgroup\$ – JRE Oct 31 '16 at 12:43
  • 2
    \$\begingroup\$ That last comment to me was the first I've heard that comes anywhere near the constraints of the question. Still not there yet, though. What hardware are you using to sample the pot? We're not all asking you for more details and telling you there might be something wrong with your approach because we like to waste our own time -- we're doing that because if you had provided the info 20 hours ago you could have had very meaningful answers. \$\endgroup\$ – Scott Seidman Oct 31 '16 at 17:57
3
\$\begingroup\$

You can make it sticky electronically.

Take many filtered (analog and digital domain filtered) readings and then simulate mechanical stickiness. Something like stick-slip where it requires a lot of motion (relatively speaking) to get it to move from a given position once it has settled.

\$\endgroup\$
  • 1
    \$\begingroup\$ Yes, this is the kind of answer I was looking for! \$\endgroup\$ – Timmmm Oct 31 '16 at 20:11
1
\$\begingroup\$

If this is for brightness control, you are vastly over-thinking the problem. Put a capacitor across the wiper of the pot and get on with your life.

\$\endgroup\$
  • 1
    \$\begingroup\$ It's for brightness control of a desktop monitor that flickers every time you change the brightness. \$\endgroup\$ – Timmmm Oct 31 '16 at 16:35
  • 1
    \$\begingroup\$ @Timmmm, perhaps a cold solder joint in the pot connection? \$\endgroup\$ – George Herold Oct 31 '16 at 16:48
  • 1
    \$\begingroup\$ @GeorgeHerold No it's a Dell monitor. It seems like they have some funky code to handle brightness changes 'smoothly' but if you send to many too quickly it flickers like mad. \$\endgroup\$ – Timmmm Oct 31 '16 at 16:50
  • 1
    \$\begingroup\$ @GeorgeHerold or a dirty pot, or a bad wiper... \$\endgroup\$ – Ian Bland Oct 31 '16 at 16:50
  • \$\begingroup\$ Reading this again I think you assumed that the pot directly controls the monitor brightness. I have no idea how you would do that but it doesn't. It's read via a microcontroller and sent to the computer over USB which then uses DDC/CI to tell the monitor to change brightness. \$\endgroup\$ – Timmmm Mar 27 '18 at 10:50
1
\$\begingroup\$

Ignore the jitter, and scale the effect of turning he knob appropriately. I can't imagine this would have any real effect on a brightness control if an LSB is 1/2^10 of full scale. If it does, your error is in your scaling method, possibly a numerical faux pas. Perhaps you are dividing before you multiply, and are amplifying your round off error. Show your code, as opposed to describing your problem, as you probably have XY issues.

If you do show code, kindly reduce to a minimal chunk that demonstrates your issue.

Now that you've explained your issue a little more, you still need to sample the pot with some service level. Keep track of the last value that caused an adjustment. Only call your API when you've deviated maybe 10% from that value, and whenever you call the API, store the new value. If you can't tolerate that, then I recommend changing the pot to an encoder and the problem might go away.

\$\endgroup\$
0
\$\begingroup\$

The overall solution is to do the filtering in the right place and use appropriate A/D resolution.

You are filtering in analog, then quantizing. A little filtering in analog is good, but most of the filtering should be on the digital samples. That filters the quantization noise too, which is what your problem is, although you haven't said it outright.

Run the A/D as fast as you can without being a burden on the rest of the system, then apply a couple of:

  FILT <-- FILT + FF(NEW - FILT)

This is easy to compute in a microcontroller, especially when FF is 1/2N. The multiply by FF is then just a right shift by N bits. To not lose any information, FILT must be maintained with N additional fraction bits compared to the incoming samples (the NEW values in this algorithm).

For example, two of these filters with FF = 1/16 and keeping one byte of fraction bits yields a 90% settling time in 60 iterations. This is the advantage of running the A/D faster in the background than the values are needed by the rest of the system.

If this is a pot meant to be adjusted by a human, then you have a lot of time. Let's say you run the A/D at 2 kHz, which is quite slow for even a modest microcontroller. 50 ms is about the limit of what humans consider instantaneous. In that time you process 100 samples and get to 98.9% settling, not that you really need to settle to that level in 50 ms for human input.

The other part of this is to make sure the A/D has enough resolution to begin with. The low pass filtering will give you a bit or two of apparent extra resolution, but is not something you should rely on. Let's say this is a volume control, and you want it to have a 60 dB range. Even just a 8 bit A/D gives you 0.24 dB per count. That's so little that nobody will notice if the volume is fluctuating up and down by that amount, assuming you take care to not tear the incoming signal, like by only changing gain at zero crossings or the like. Even 8 bit samples with filtering as described above will seem smooth to a human adjusting a volume knob.

You'd have to work at it to find a modern micro that doesn't have at least a 10 bit A/D. That means it can sense 1/1000 of the rotation range. Think about it. If 1/1000 of the rotation range actually matters, then you need to go back to the system-level design and rethink the whole problem at a higher level. You might, for example, have two pots. One is a course adjustment and one a fine adjustment. Or use a digital encoder and allow multiple turns. There are various system-level solutions, but reading a normal knob to 1/1000 of a turn should really be good enough whether it jitters between adjacent readings or not.

\$\endgroup\$
  • 1
    \$\begingroup\$ "reading a normal knob to 1/1000 of a turn should really be good enough whether it jitters between adjacent readings or not" No this is the entire problem I am trying to solve. I want to avoid receiving lots of values that are just due to jitter. The reason is that acting on value changes is jarring so I want to do it as little as possible. (Basically part of the system that I don't control is a bit broken.) \$\endgroup\$ – Timmmm Oct 31 '16 at 11:56
-1
\$\begingroup\$

If your noise is greater than desired resolution , fix the sensitivity issue with fixed R values in series or fix the noise issue.

Otherwise, ignore as you suggested or deal with the jitter by averaging.

  • jitter range reduces by sq.rt. of N samples averaged for random only

You can simply add hysteresis in the comparing the absolute value of the difference between the new reading from the previously "stored" reading in order to ignore readings that do not exceed some defined range of noise.'. You can set this threshold as big as you want in software so it can be greater than the LSB.

\$\endgroup\$

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