# How to include Vref in thermistor temperature calculation?

simulate this circuit – Schematic created using CircuitLab

This is the code that I'm using to get the temperature:

``````#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp;
float Vref = 2.52;

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

void loop() {
long Resistance;
Resistance = 10000 / ((1023.0 / VRT) - 1);
Temp = log(Resistance);
Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
Temp += -273.15;
Serial.println(Temp);
delay(500);
}
``````

I know that the calculation should be: `V = Vref × VRT ÷ 1023` but i don't know how to implant it in this code, any help appreciated.

# Update

After Edgar Bonet answer, the edited code is:

``````#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp, VR;

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

void loop() {
long Resistance;
VR = 2.52 * VRT / 1024;
Resistance = 10000 * VR / (2.52 - VR);
Temp = log(Resistance);
Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
Temp += -273.15;
Serial.println(Temp);
delay(500);
}
``````

But the temperature reading is 2 centigrade less than what it should be, when i remove the `analogReference(EXTERNAL);` it shows the normal/correct temperature readings.

The formula to get the analog voltage from the ADC reading is:

V = Vref × reading ÷ 1024

(yes, it's 1024, not 1023). The formula to get the thermistor resistance from the measured voltage is:

R = Rref × V ÷ (Vref − V)

where Rref is your 10 kΩ pull-up. You can combine these two formulas in order to get the resistance directly from the ADC reading:

You may notice that, while doing this simplification, Vref cancels out. It's not an error. The readings you get with this setup are indeed independent of your reference voltage.

Update 1: After the OP's edit, we now have a completely different question. The question is now: how come the readings do depend on the reference voltage that is used, whereas in theory they should not.

The answer lies most likely in the ADC calibration. If high accuracy is a requirement, the correct formula for the measured voltage is

V = Vref × (reading + Eoff) ÷ (1024 + Egain)

where Eoff and Egain are the offset error and the gain error respectively. These errors are not knows a priori, and they are usually neglected when the accuracy requirement is low. The datasheet only gives constraints on how big these errors can be. The actual values depend on the specific microcontroller and can somewhat depend on the reference voltage. The only solution to get rid of these errors is to calibrate your own ADC. See Response of the Arduino ADC for an example on how this could be done.

Update 2: If I had to program this in an Arduino, I would rather simplify the calculations as much as possible before coding:

• do not compute the measured analog voltage, nor the resistance, as they are not needed
• rewrite the calibration polynomial as a function of log(R/Rref) instead of log(R) (which actually means log(R/(1 Ω)))
• optimize the evaluation of the polynomial by using Horner's method.

With these optimizations, we get:

``````// Coefficients of polynomial fit of log(R/Rref) -> 1/T.
const float c0 = 3.3540165e-3;
const float c1 = 2.5416075e-4;
const float c2 = -2.5959644e-6;
const float c3 = -9.3951087e-8;

{
float R_ratio = reading / (1024.0 - reading);  // = R / Rref
float x = log(R_ratio);
float inverse_T = c0 + x*(c1 + x*(c2 + x*c3));
return 1/inverse_T - 273.15;
}

void loop()
{
deay(500);
}
``````
• so in this example it should be this: `Resistance = 2.52 * VRT / (1024 - VRT);`, correct? – ElectronSurf Aug 30 '19 at 13:21
• No. Your reference resistance is 10 kΩ, not 2.52 Ω. – Edgar Bonet Aug 30 '19 at 13:23
• but the readings is wrong, `Resistance = 10000 * VRT / (1024 - VRT);` did i missed something? it's like 2C less... – ElectronSurf Aug 30 '19 at 13:27
• I don't understand your last comment. Please, edit your original question if there is something missing. – Edgar Bonet Aug 30 '19 at 13:28
• when i use your suggested formula `Resistance = 10000 * VRT / (1024 - VRT);` the temperature is 2 centigrade less than what it should be. – ElectronSurf Aug 30 '19 at 13:29