5

Lately I was asking myself about the possibility of measuring a potentiometer resistance with Arduino.

My questions are:

  1. Is it possible?
  2. If it's possible, what kind of restriction does the Arduino have with the resistance value measured?
  • This simple example will show you how to measure the position. It uses a potentiometer with its ends connected to +5V and 0V, and you read the analog voltage at the "wiper" connection which is the centre on most potentiomenters. (To clarify - this method does not directly measure the resistance, a different arrangement would be used for that. But most potentiometer applications really just need the position.) – Andy Aug 10 '16 at 9:59
  • @Andy You can always just add a quick equation into your code to turn the voltage back into resistance, as long as you know the value of the pot you're using – Doodle Aug 10 '16 at 11:04
  • @Hayman you're correct, if the overall resistance of the pot is known. But it's not entirely clear to me if the questioner wants to use a known pot in a circuit, or is trying to measure "resistance" of something in general. That's why I was being cautious :) – Andy Aug 10 '16 at 12:03
7

If you know Ohm's Law (which you should) and you realise that the ADC measures voltage, you should be able to work it out from there. But I will go into minute detail for you to ensure you understand.

Ohm's Law defines the relationship between Voltage (V), Current (I) and Resistance (R).

R = V/I

To find one unknown value (in your case R) you need to know the other two values. That is, the current flowing through the resistor, and the voltage dropped across the resistor.

We have no way of directly measuring current, but we can measure voltage using the ADC. So if we can somehow measure a voltage and use that to calculate the current then we have two of the three values and we can calculate the third. However, calculating the current requires that we know the resistance - and that is what we are wanting to find out.

So we need to then provide a known resistance that we can measure the voltage across, and thus find the current flowing through it. First a couple of reminders of basics:

  • Current flows the same through all resistances connected in series
  • The sum of all voltages dropped across resistors in series equals the total voltage across all the resistors.

So if we put two resistors in series and apply an fixed voltage across it (5V in our case) a single current will flow through them both. With that two voltages will be dropped across the resistors - and those two voltages will add up to 5V.

If we have one known resistor and one unknown resistor and we know the voltage dropped across both resistors then we can calculate the current that is flowing through the known resistor. And that current is the same current that is flowing through the unknown resistor. And since we know the voltage drop across that resistor we can then calculate its resistance using that voltage and the current we have just calculated.

Here's the circuit I just described:

enter image description here

Vin us 5V. Let's have R1 as, say, 10KΩ (a common enough value). R2 we don't know.

Using the ADC of the Arduino we measure a value of 681. First we convert that into a voltage:

Vout = 681 / 1024.0 * 5.0
     = 3.325V

So we know that R2 has 3.325V dropped across it, and since all the voltages must add up to 5V we know that R1 has (5 - 3.325) 1.675V dropped across it.

So the current (I=V/R) through R1 must be (1.675 / 10,000) 167.5µA (0.0001675A).

Now we can calculate the resistance of R2 since R=V/I and V is 3.325 and I is 0.0001675, so R must be 19850Ω - or pretty much 20KΩ.

That's the long-hand version from a current-based perspective. However there is a short-cut.

Since the output voltage is a simple ratio of the input voltage defined by the ratio between the resistors we can use that to create a much simpler formula.

From the example above the output voltage is two thirds the input voltage - and R2 is two thirds the total resistance (R1+R2). The two match perfectly. So we can use a simple ratio calculation to give us the resistor.

For instance, the ratio formula:

Vout = R2 / (R1 + R2) * Vin

(that's R2 as a proportion of the total resistance multiplied by the input voltage)

When rearranged to get R2 gives us:

R2 = R1 * (1 / ((Vin / Vout) - 1))

So taking the voltage we measured above (3.325) and the known resistor (10,000Ω) and the input voltage (5V) and substituting those values into the formula, we get:

R2 = 10,000 * (1 / ((5 / 3.325) - 1))
   = 10,000 * (1 / (1.504) - 1)
   = 10,000 * (1 / 0.504)
   = 10,000 * 1.984
   = 19840

Or pretty much 20KΩ. (Note: the discrepancy in the results is purely due to rounding errors. Use higher precision values and you get better results).

You have to have a rough idea of the kind of order of magnitude of resistor you are trying to find, though, in order to select an R1 of a comparable value so that the voltage Vout is large enough to measure accurately.

Also you need to be aware that the input to the ADC has quite a (relatively) low impedance (can be very crudely thought of as a resistor between the input and ground) which is measured in the low mega-ohm range. This can have an impact on the values you read with the ADC if your resistors are too high, since this impedance will be in parallel to the resistor R2, so you'd actually be measuring the resistance of both R2 and the ADC's input in parallel. To measure very high resistances you should first buffer the ADC through a voltage follower with a very high (tens or hundreds of tera-ohms) impedance input.

  • Actually, the conversion factor is 1024, not 1023, according to the ATmega328P datasheet. Not that it makes a big difference though... – Edgar Bonet Aug 11 '16 at 8:26
  • 1
    Put 5v into the ADC and you read 1023. 1023/1024*5 is not 5. 1023/1023*5 is 5. – Majenko Aug 11 '16 at 8:33
  • @EdgarBonet If we're really 'nitpicking' then you could argue that the 5V isn't truly 5.0000, so you could say that using 5 is also incorrect. The way I've always known it is there are 1024 levels, as 0 is the first number that makes 1023 full scale does it not? – Doodle Aug 11 '16 at 8:39
  • @Hayman You mean like I discuss on my blog? – Majenko Aug 11 '16 at 8:43
  • That was an interesting read, I was trying to think how to accurately measure Vcc on board, didn't know you could do it that way. Now all my analog reads will be a bit more accurate – Doodle Aug 11 '16 at 8:48
1

The question isn't explicitly clear, this answer is based on having a single known value pot and wishing to know its resistance at any one point rather than trying to find an unknown resistance entirely

You can't measure resistance directly. What you can do however is measure the voltage across a potentiometer.
There is a really good example provided by arduino which can be found here.

Now, it is possible to turn this into a resistance value with a little bit of editing to the code

int potPin = A0;    // Select the input pin for the potentiometer
int potR = 1000;    // This is your max potentiometer resistance in Ohms
int val = 0;        // Variable to store the value coming from the sensor
float voltage;      // This is the voltage from the wiper of the pot
float resistance;   // This is the resistance of the pot at the wiper

void setup() {
  Serial.begin(9600);
}

void loop() {
  val = analogRead(potPin);                      // Read the value from the pot wiper
  voltage = val * (5.0 / 1023.0);                // Convert the value into a voltage
  resistance = (voltage / 5.0) * potR;           // Convert the voltage into a resistance
  Serial.print("Voltage = ");
  Serial.print(voltage);                         // Print the voltage
  Serial.println("V");                           
  Serial.print("Resistance = ");
  Serial.print(resistance);                      // Print the resistance
  Serial.println("R");
  delay(1000);                                   // Add a little delay                           
}

As for your second question, it can do as high a resistance as you want. As long as you update the potR value in the code with the resistance of your pot (e.g. 1000000 for a 1MOhm pot)

I'm an electronics engineer by trade so my code could probably be cleaned up and made more efficient, this is just a starting point

  • 1
    Actually you can measure the resistance if and only if you have a reference resistor. Then you can measure the voltage between the reference resistor and the unknown resistor and then calculate the value of the unknown resistor. – Kwasmich Aug 10 '16 at 11:21
  • Just nitpicking: the scale factor is 1024, not 1023. – Edgar Bonet Aug 11 '16 at 8:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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