Reading ohms accurately

I have a project which involves using an Arduino Uno to read a PT1000 temperature sensor. I have a formula to convert ohms into temperature, but I can not figure out how to get an accurate ohm reading from my code; all the conversions I have tried are off by quite a bit, up to around 200 ohms. I need to be able to read 1 ohm changes. Here's my current code:

  int valueS1 = analogRead(0);   //read the value from the sensor
  float S1Volts = valueS1 / 1024.0 * 5.0;  //convert 0-1023 to volts
  float vDropS1 = 4.90 - S1Volts;   //find drop across unknown resistor
  //10K known resistor used to calculate resistance
  float S1Resistance = 10000 * (1 / ((5 / S1Volts) - 1));
  Serial.print("Resistance:");
  Serial.println(S1Resistance);

Any ideas? Thanks!

int valueS1 = analogRead(0);   //read the value from the sensor

What sensor?

Always post ALL your code.

This is not accurate unless you have actually measured the Arduino supply voltage. With USB power, it is typically 4.5V:

 float S1Volts = valueS1 / 1024.0 * 5.0;  //convert 0-1023 to volts

.

Where does "4.9" come from?

float vDropS1 = 4.90 - S1Volts;   //find drop across unknown resistor

With a PT1000 sensor, you should use a 1K precision resistor in the voltage divider. With the precision resistor connected between Vcc and the analog input, the formula for the unknown resistance becomes:

  float R_unknown = 1000.*adc_value / (1024. - adc_value);  //adc_value is 0 - 1023

Sorry I am new at this, I'll try to explain. The '4.90' is my measurement of the AREF voltage on my board; I had read this might fix the problem, but it didn't. Can I have the complete code for calculating the resistance? If you could give a modification of the original however you'd do it that would be great. Thank you.

Your problem seems to come entirely from using 5.0 as the voltage in some places, and 4.9 in one.

Get rid of the conversion to voltage completely. Since you're using a voltage divider the analogRead measurement you get will be identical no matter what the actual voltage is. You can factor out the reference voltage by changing all the voltage values in your formula to 1.0.

  int valueS1 = analogRead(0);   //read the value from the sensor
  float S1Ratio = valueS1 / 1024.0;  //convert 0-1023 to volts
  float vDropS1 = 1.0 - S1Ratio;   //find drop across unknown resistor
  //10K known resistor used to calculate resistance
  float S1Resistance = 10000.0 * (1.0 / ((1.0 / S1Ratio) - 1.0));
  Serial.print("Resistance:");
  Serial.println(S1Resistance);

How does this work?

What is the tolerance of your 10k resistor?

With the new code it is about the same; I am reading 1314 ohms on a resistor which my meter says is 992 ohms. My 10K has +/- 5% tolerance. When I measured it I got close to 9.8K. Is this a problem with my resistor's tolerance or the circuit? Currently the circuit I am using is the 10K between 5V and the A0 pin on my Arduino, with the unknown resistor between GND and A0.

andrewsElectronics:
With the new code it is about the same; I am reading 1314 ohms on a resistor which my meter says is 992 ohms. My 10K has +/- 5% tolerance. When I measured it I got close to 9.8K. Is this a problem with my resistor's tolerance or the circuit? Currently the circuit I am using is the 10K between 5V and the A0 pin on my Arduino, with the unknown resistor between GND and A0.

Print the value of the analogRead without any calculations applied to it. It should be about 95. The error you're seeing here appears to be much larger than a tolerance problem, and might be a problem with your circuit.

If you want any hope of precision, a 5% tolerance resistor is garbage. You need a precision resistor (0.5% or better), and for best accuracy it should be close in value to the other resistor (1k instead of 10k).

andrewsElectronics:
My 10K has +/- 5% tolerance. When I measured it I got close to 9.8K.

Nominal value: 10K
Measured value: 9.8K
That is a -2% error, well within the 5% tolerance of your resistor. You could use the measured value instead of the nominal value to get better accuracy.

Get a ds18b20!

Sorry, the error in the reading was indeed my fault. The discrepancy was caused by a dirty connection. I did a few things. First, I fixed the connection, and I also replaced the 10K resistor reading 9.8K with one reading 10.5K on my meter. I am reading 987 ohms on a resistor I measured at 982 ohms; and 482 on a 502 ohm. Probably this error is just caused by the tolerances right? On a much higher unknown resistor (300K) I had an error of 1K. I would like to have a range of 200 ohms to 40K ohms. Is there a reference resistor which would do this? Or two different ones I could select between?

The impedance of the Arduino's analog inputs is around 10K, so you should try to use resistors for your voltage divider that are around that figure or lower, but not too much higher. 300K, for example, is too high and may not give a reliable reading.

What multimeter are you using? Did you compare the resistors you measure against a second multimeter to see how consistent they are?

You should think about what level of precision and accuracy you want for your temperature measurements. The PT1000 appears to have, according to this page, 5 digits of precision, and therefore I assume accuracy, between -70C and +500C. The analog inputs on an Uno/Mega cannot match that, they only have 3 digits of precision. You may want to consider using external, higher-precision D/A converters, such as ads1115.

You can buy pt100 boards for Arduino with built in amplification - see Google. “Max 31865 Arduino” . What you are attempting has lower resolution and no compensation for lead resistance - you are also operating the sensor at different currents dependant on temperature which may cause errors .

Or as someone said , bin it and use a DS18B20 much easier if the temperature range suits.

The ds18b20 has a smaller range than pt1000, -55C to 125C compared to -70C to 500C. But that might be enough for the OP...

Ok, I seem to have come to a solution using a combination of better reference resistors and different AREF voltage. I now can read within 2 ohms, which is good enough. Thank you!