Lately I was asking myself about the possibility of measuring a potentiometer resistance with Arduino.
My questions are:
- Is it possible?
- If it's possible, what kind of restriction does the Arduino have with the resistance value measured?
Lately I was asking myself about the possibility of measuring a potentiometer resistance with Arduino.
My questions are:
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:
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:
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.
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