Potentiometer Value Unstable

Hi,

I'm trying to control a parameter with a potentiometer (b1k). I've mapped analogRead values from 0-1023 to values 65-220 with steps of 5 using simple division. However analogRead value of the potentiometer varies by 1 (ie. when set to 900, it sometimes reads 900, sometimes 901). Thus, the mapped value also varies by 5 for certain potentiometer values due to residual from the division.

Is this normal for a potentiometer? Should I buy a better one? Or, is there way to prevent this?

krypttr: Hi,

I'm trying to control a parameter with a potentiometer (b1k). I've mapped analogRead values from 0-1023 to values 65-220 with steps of 5 using simple division. However analogRead value of the potentiometer varies by 1 (ie. when set to 900, it sometimes reads 900, sometimes 901). Thus, the mapped value also varies by 5 for certain potentiometer values due to residual from the division.

Is this normal for a potentiometer? Should I buy a better one? Or, is there way to prevent this?

The quickest way is to average the analog readings over a short period of time. Also, there must be thousands of threads on the forum relating to variations in the analog voltage readings. Click the little lollypop in the upper right of the page heading for the "search" function.

Paul

Is this normal for a potentiometer?

Yes and normal for an analogue to digital converter as well.

HI,

Analog signals by their very nature vary. This is due to effects of external signals, such as; RF noise, Power supply noise, pickup from switched signals (LCD drivers etc), temperature.....etc

You will find it extremely difficult to get below your current +/-1 count. As suggested averaging might help but may not be the best solution.

If you want absolute stability, I suggest you look into a shaft encoder such as: encoders

You can also find them on eBay.

Being digital devices, they are absolutely stable. For the additional programming they require I'm sure arduino has a library you can use.

If you are not familiar with them, they are similar to the volume control on most modern automotive radios. They have no end stop so they can "count" over multiple turns (for better resolution). Also they often have detents at each position so they remain at the set position.

You can always be on the "hairy edge" with analog-to-digital conversion. Depending on the application a couple counts of [u]hystersis[/u] may help, or some other kind of "smarts" where small input-changes are ignored 'till there is a bigger change.

65-220 is only 166 steps, and should be possible with code with some deadband/hyterisis.
Here is an example I wrote for 0-100% (101 steps).
Maybe you could adapt it to your needs.
Leo…

// converts the position of a 10k lin(B) pot to 0-100%
// pot connected to A0, 5volt and ground

int rawValue;
int oldValue;
byte potPercentage;
byte oldPercentage;

void setup() {
  Serial.begin(115200); // set serial monitor to this baud rate, or change the value
}

void loop() {
  // read input twice
  rawValue = analogRead(A0);
  rawValue = analogRead(A0); // double read
  // ignore bad hop-on region of a pot by removing 8 values at both extremes
  rawValue = constrain(rawValue, 8, 1015);
  // add some deadband
  if (rawValue < (oldValue - 4) || rawValue > (oldValue + 4)) {
    oldValue = rawValue;
    // convert to percentage
    potPercentage = map(oldValue, 8, 1008, 0, 100);
    // Only print if %value changes
    if (oldPercentage != potPercentage) {
      Serial.print("Pot percentage is: ");
      Serial.print(potPercentage);
      Serial.println(" %");
      oldPercentage = potPercentage;
    }
  }
}

I've been trying various averaging or smoothing algorithms however none of them has a stable output. If it was for reading a sensor I'd say it's fine however I'm trying to set the setpoint of a pid algorithm with the potentiometer so I do need a stable output.

It seems encoders are the way to go as pointed out by @JohnRob. But, I will take a look at the aforementioned hystersis first.

Thank you all for much valued suggestions.

Before you go to far, measure the input voltage to your Arduino and be sure it is not varying.

Paul

You could also add some type of visual indication , may be one or even three Leds, so you can see if the potentiometer is set exactly in the middle of one of the 5 unit slots you have defined. This will minimize the risk of you setting it close to the border of two slots, with the risk that a 1 unit drift causes a shift to the next slot.

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

We may be able to suggest some code edits to help smooth out the phenomenon.

Thanks.. Tom... :)

krypttr: Hi,

I'm trying to control a parameter with a potentiometer (b1k). I've mapped analogRead values from 0-1023 to values 65-220 with steps of 5 using simple division. However analogRead value of the potentiometer varies by 1 (ie. when set to 900, it sometimes reads 900, sometimes 901). Thus, the mapped value also varies by 5 for certain potentiometer values due to residual from the division.

Is this normal for a potentiometer? Should I buy a better one? Or, is there way to prevent this?

Its absolutely inevitable that you get fluctuations of >=1 LSB of an ADC result. If theres a lot of noise you'll get more, if very clean signal you'll get only 1 LSB fluctuations, and perhaps only sometimes.

Your code needs to add hysteresis to the raw potentiometer reading - ie only recalculate the mapping if the input has varied by more than some threshold difference from the last recorded value. You only record a value if the threshold is exceeded.