Google Analytics

Sunday, April 1, 2012

Arduino - Obtaining User Values Using Potentiometer

Obtaining User Input to an Arduino Using a Potentiometer

(code example at end)

There are many times where it's convenient to enter in values using a simple potentiometer instead of a GUI interface. An example would be whereby a user wants to set the desired temperature on a thermostat.

A potentiometer has three (3) leads coming from it. Typically, the center lead is the 'wiper'. The wiper has the ability to vary the resistance from one end of the potentiometer to the other end.

A potentiometer has a maximum resistance between two leads, typically the first and last lead, and an ability to vary the resistance seen on the other lead, the wiper.

Another way to think of this is to realize the potentiometer's wiper has the ability to provide 0% through 100% of the total resistance available through the other two (2) leads.

Per Ohm's law, which states the interaction between three (3) entities – resistance, voltage, and current – if a resistance is connected to a voltage source, than there will be a voltage drop across the two ends of the resistor.

A potentiometer is a resister that also includes a third lead – the wiper, can can move between the two ends of the resistor, and is capable of varying it's resistance while doing so. Because of this, the wiper lead sees a different voltage.

The voltage at the wiper can not be more than the maximum voltage connected on the voltage-in side of the resistor, when measured to the other end of the resistor. Likewise, the voltage at the wiper can not be less than the minimum voltage connected on the voltage-out side of the resistor.

So the voltage seen at the wiper will vary between 100% of the voltage at one end of the resistor, and 0% of the voltage at the other end of the resistor.

In a linear potentiometer (as opposed to a non-linear potentiometer, such as an 'audio' potentiometer, which is logarithmic), turning the potentiometer 5% clockwise will result in a change in the resistance seen at the wiper, by 5%. If there is a voltage applied to the first lead of the potentiometer, and ground and the last lead of the potentiometer, then this 5% change in the resistance will result in a 5% change in the voltage.

The voltage will drop across the potentiometer's wiper. Remember, it will either be at 0% of maximum, or 100% of maximum, or anywhere in between, but can not exceed those two values.

When working with an Arduino, I'm not typically concerned about the actual voltage present at the wiper. Instead, I'm concerned about the position of the wiper. For instance, when using a potentiometer to turn a setpoint up or down for a thermostat, I'm not interested, as a user of the thermostat, of the voltage that is being changed; instead, I'm interested in the temperature represented by the potentiometer, and how I'm changing it.

For this reason, when using a potentiometer in an Arduino circuit, I'm typically using it as a ratio-device. I'm more interested in the ratio, or percentage, of the position of the potentiometer's wiper, not the voltage being read at the wiper.

Here's what I mean by that.

On my porch heater thermostat, I have placed a potentiometer, which I use to set the temperature that I desire the porch to stay at. By setting the potentiometer's value, I am setting the temperature I desire for my porch.

If the potentiometer is connected at one end to a 5 volt power supply, and the other end is connected to ground, then the wiper, when turned, is capable of being at any voltage between 5 volts and 0 volts, inclusive.

But I don't set my porch heater to a voltage, I set it to a temperature.

On my porch heater, I decided I wanted to be able to specify (the setpoint), a temperature between 70 dF and 75 dF. That's a 5 degree F range. Thinking in percentages, 0% would be 70 dF, and 100% would be 75 dF. 50% would be half way the range of 5 degrees, or 2.5 dF. Since my bottom temperature is 0% at 70 dF, and 50% is half way between a range of 5 dF, thus the 2.5 dF, then that 2.5 added to the 0% of 70 dF is 72.5 dF. So, if I set my potentiometer to 50%, I'm actually setting my temperature to 72.5 dF.

Well, OK, you might be thinking, but how do I get voltages and percentages into temperature?

That's where software comes into play – the flexibility of software.

I'm constrained by the hardware here – the only thing I've got to work with here is the voltage, and it is going to range between 0% and 100% of the total 5 volts available. The Arduino is capable of reading the voltage. So it's capable of reading the 0 volts through 5 volts that are being supplied by the potentiometer. But that's all it's directly capable of doing using its Analog to Digital Converter (ADC).

So anything I want to do with the Arduino, in reading an external voltage, is going to range between this 0 volts and 5 volts. And the Arduino, in converting this analog value to digital, has the capability of dividing that 0 – 5 volts into 1024 equal divisions, because it has a 10 bit ADC converter. (Take a calculator and see what 2^10 gives you). The calculator will show you that 2^10 is 1024 individual values. But, since we are starting at 0 instead of at one, then the range is 0 – 1023.

So the Arduino converts the analog 0 – 5 volts to a digital value of 0 – 1023.

Here's where the ratios make everything simple, so it's important to understand this.

The ratio, or percentage, of the 0 – 5 volts is the same ratio, or percentage of 0 – 1023.

For example:
  • a voltage of 5 volts at the wiper, is 100% of the 0 – 5 volts. Likewise, it is 100% of the 1023 value, or 1023.
  • a voltage of 2.5 volts at the wiper, is 50% of the 0 – 5 volts, or 2.5 volts. Likewise, it is 50% of the 1023 value, or 512 (integer, not floating).
  • A voltage of 0 volts at the wiper, is 0% of the 0 – 5 volts, or 0 volts. Likewise, it is 0% of the 1023 value, or 0.

What that means, is if you can convert the input value to a ratio, or percentage, then you can apply that percentage to anything.

For instance, on my porch heater, I read the potentiometer, and get back a count of 256. To convert this to a ratio, then I'm trying to find out what percentage is 256 of the total 1024? So I'm going to divide 256 by 1024, and that will give me 25%. From a voltage standpoint, 25% of 5 volts is 1.25 volts, but I don't care about this at all. I'm only concerned with the percentage, which we've determined is 25%. But I am concerned with temperature, and my temperature range, 0% - 100% is 70 dF – 75 dF, which is a range of 5 degrees F. So 25% of the range of 5 degrees F is 1.25 degrees F, and since my base is 70 dF, and I'm 1.25 dF above that 0% value, then I'm at 71.25 dF.

So you can apply this to anything, and it's what makes a potentiometer so powerful in any circuit you are building.

The hardware gives you the range of 0 – 5 vdc, 0% - 100%, the ADC gives you 0% - 100% of 0 – 1023, and then using software, you choose what you want that to represent. In my case, I wanted that 0% - 100% to represent 70 dF to 75 dF for a porch heater. But for my Sous Vide cooker, I want that to represent 150 dF – 200 dF, which has a range of 50 dF, and using the previous example of 25% of the potentiometer, and 25% of the max 1024 counts, then I'm now talking about 25% of the range of 50 dF, or 12.5 degrees F above the base of 150 dF, or 162.5 dF.

Using software, you decide what the final values are that you are representing with the potentiometer. Then taking the percentage of the potentiometer, and the percentage of the maximum counts of 1024, you can directly apply that to whatever you are doing – RPMs, population, weights, valve opening, whatever.

Here's a coding example.

Assume we are wanting to set a desired temperature onto a thermostat. Further assume the thermostate will be capable of setting the temperature anywhere from 70 to 75 dF. Assume we will use analog pin A0 for the wiper on the potentiometer.

void setup() {
     pinMode(A0, INPUT);

void loop() {
     float setpoint = 0.0;
     float volts = 0.0;
     int counts = 0;
     float ratio = 0.0;
     float baseTemperature = 70.0;
     float tempratureRange = 5.0; //75 dF – 70dF = 5 degrees F range

     //get the potentiometer's wiper value in counts, 0 – 1024
     counts = analogRead(A0);

     //get the ratio of the counts as a percentage of mximum
     ratio = (float)counts / 1023.0;
     //using the ratio to calc the voltage (maximum of 5 vdc). It's not used, but just for fun.
     volts = 5.0 * ratio;  //we have a max of 5 volts

     //now get the setpoint temperature
     setpoint = (ratio * temperatureRange) + baseTemperature;

     //that's all there is to it!

     // now print this out
     Serial.print(“counts: “); Serial.print(counts);
     Serial.print(“, ratio: “); Serial.print(ratio);
     Serial.print(“, volts: “); Serial.print(volts);
     Serial.print(“, setpoint: “); Serial.println(setpoint);


1 comment:

  1. A simple and practical example that a newcomer to Arduino can understand. Bonus! Thanks, bud. - Andrew J.