Thermistor Arduino
Thermistor Arduino
Gerald Recktenwald∗
July 11, 2010
a measured voltage drop. Precision resistance measurements involve techniques different from
those described in these notes. Multimeters and other instruments that measure resistance
have built-in circuits for measuring the voltage drop across a resistor when a precisely con-
trolled and measured current is applied to the resistor.
2 In the instructions for its data logging shield, adafruit recommends using the 3.3V input
to power sensors because because the 5V line is noisey. To use the 3.3V line, the 3.3V signal is
tied to the Aref pin. See http://www.ladyada.net/make/logshield/lighttemp.html. In my
informal experiments, there was no apparent difference between the 3.3V and 5V supplies.
EAS 199B – Thermistor Measurement 2
Vs Rt
Vo R
Figure 1: Voltage divider circuit (left) and sample breadboard wiring (right) for
measuring voltage to indicate thermistor resistance. For the breadboard wiring
on the right, Vo is measured with analog input Pin 1.
Vo = IR (2)
Solve Equation (1) and Equation (2) for I and set the resulting equations equal
to each other
Vs Vo Vs Vo
I= and I = =⇒ =
R + Rt R R + Rt R
The last equality can be rearranged to obtain.
Vo R
= (3)
Vs R + Rt
Rearranging Equation (3) to solve for Rt gives
Vs
Rt = R −1 . (4)
Vo
Equation (4) is used to compute the thermistor resistance from the measurement
of Vo .
// File: ThermistorVoltageResistance.pde
//
// Use a voltage divider to indicate electrical resistance of a thermistor.
Vo = analogRead(ThermistorPin);
Rt = R*( 1023.0 / float(Vo) - 1.0 );
Listing 1: ThermistorVoltageResistance.pde
Vo Rt
487 10863.08
488 10820.59
488 10820.59
487 10863.08
488 10820.59
489 10778.28
...
Notice how the resolution of the analog to digital converter (ADC) on the Ar-
duino causes discontinuous jumps in the measured value of Rt . When the value
of Vo changes from 487 to 488, the value of Rt jumps from 10863 Ω to 10820 Ω.
The jump is due to a change in the least significant bit of the value obtained
by the 10 bit ADC, not because of a discontinuous variation in the physical
resistance. Conversion of the measured Rt values to temperature will result
in a corresponding jump in T values. Appendix A contains an analysis of the
temperature resolution limit of the Arduino as a function of Rt and R.
4 The specific values of Vo and Rt will vary from run to run, and will depend on the charac-
teristics of the fixed resistor and thermistor used, and on the temperature of the thermistor.
// File: ThermistorTemperature.pde
//
// Use a voltage divider to indicate electrical resistance of a thermistor.
// Convert the resistance to temperature.
Vo = analogRead(ThermistorPin);
Rt = R*( 1023.0 / (float)Vo - 1.0 );
logRt = log(Rt);
T = ( 1.0 / (c1 + c2*logRt + c3*logRt*logRt*logRt ) ) - 273.15;
Listing 2: ThermistorTemperature.pde
Vo Rt T (C)
486 10905.74 22.47
482 11078.15 22.07
485 10948.58 22.37
484 10991.59 22.27
485 10948.58 22.37
485 10948.58 22.37
485 10948.58 22.37
483 11034.78 22.17
...
This output shows that a change of one unit in Vo causes a change of 0.1 ◦C in
the computed temperature. Thus, we can infer that the temperature resolution
of this thermistor/aduino combination is 0.1 ◦C. Note that resolution is only
a measure of the smallest difference that a sensor and instrument combination
can detect. A resolution of 0.1 ◦C does not imply that the accuracy of the
measurement is ±0.1 ◦C. The temperature resolution is discussed further in
Appendix A.
and what kinds of operations are required to obtain a value for log(x)? The
answer to these questions is, “Of course not.” Or perhaps you would think,
“Why should I care as long as the correct result is returned?”. Those answers
make sense and reflect the decisions to delegate tasks to people or services or
utilities that we trust.
With the example of log(x) in mind, what are the desirable characteristics
of a reusable module that allows us to measure the output of a thermistor?
There are many valid answers. In the next section we will develop a simple
model of a reusable thermistor module where all the code resides in a single
function. In another section, a more flexible, object oriented module will be
developed.
We really have two goals. First, we want to create a reusable module for
thermistor measurements. Reusable code is valuable for current and future
applications of temperature measurement with an Arduino. Second, we want to
understand some of the general principles for reusable code development. The
use of modular, reusable code is good practice in any programming work.
// File: thermistorFun.cpp
//
// Read a thermistor with Arduino and return temperature
#include "WProgram.h"
#include "thermistorFun.h"
Vo = analogRead(Tpin);
Rt = R*( 1024.0 / float(Vo) - 1.0 );
logRt = log(Rt);
T = ( 1.0 / (c1 + c2*logRt + c3*logRt*logRt*logRt ) ) - 273.15;
return T;
}
Listing 3: The ThermistorFun.cpp code contains the C code function for ther-
mistor measurements.
// File: thermistorFun.h
// Header file defining prototype for functions that read thermistors
T (C)
22.52
22.72
22.62
22.72
22.62
22.52
22.62
...
// File: ThermistorTemperatureFunction.pde
//
// Use a voltage divider to indicate electrical resistance of a thermistor.
// Thermistor reading and conversion calculations are encapsulated in a
// reusable function.
#include <thermistorFun.h>
T = thermistorRead(ThermistorPin);
Serial.println(T);
delay(200);
}
Listing 5: ThermistorTemperatureFunction.pde
Figure 3: Defining the variable types for input and output of the ThermistorFun
function.
22.77
22.67
22.57
22.57
22.67
22.67
22.57
// File: Thermistor.cpp
//
// Use a voltage divider to indicate electrical resistance of a thermistor
// Thermistor reading and T conversion are encapsulated in reusable objects
//
// Based on code by Max Mayfield, [email protected]
// posted on the Arduino playground
// http://www.arduino.cc/playground/ComponentLib/Thermistor2
// Modified and extended by G. Recktenwald, [email protected]
// 2010-06-07
#include "WProgram.h"
#include "Thermistor.h"
// --- constructor
Thermistor::Thermistor(int pin) {
_pin = pin; // Analog input pin to read voltage divider output
_Rfix = 9970; // Resistance of fixed resistor in the divider
_a1 = 1.009249522e-03; // Coefficients in the Steinhart-Hart equation
_a2 = 2.378405444e-04;
_a3 = 2.019202697e-07;
}
// --- Read the voltage across the fixed resistance, and from it compute T
float Thermistor::getTemp() {
return T;
}
// File: Thermistor.h
//
// Use a voltage divider to indicate electrical resistance of a thermistor
// Thermistor reading and T conversion are encapsulated in reusable objects
//
// Vdd ---o Vdd is supply voltage, typically 5V
// |
// Rt (thermistor)
// |
// Vo ---o Vo is output from the voltage divider: Vo = Vdd*R/(R+Rt)
// |
// R (fixed resistor, R approx. equal to Rt
// |
// GND
//
// Based on code by Max Mayfield, [email protected]
// posted on the Arduino playground
// http://www.arduino.cc/playground/ComponentLib/Thermistor2
// Modified and extended by G. Recktenwald, [email protected]
// 2010-06-07
#ifndef Thermistor_h
#define Thermistor_h
#include "WProgram.h"
#include "math.h"
class Thermistor {
public:
Thermistor(int pin);
float getTemp();
void fixedResistance(float Rfix);
void coefficients(float a1, float a2, float a3);
private:
int _pin;
float _Rfix;
float _a1, _a2, _a3;
};
#endif
Listing 7: The Thermistor.h header file defines the class interface for object-
oriented thermistor measurements.
// File: ThermistorSensor.pde
//
// Use a voltage divider to indicate electrical resistance of a thermometer
// Measurements and conversions are managed via objects
#include <Thermistor.h>
Serial.println(temperature);
delay(200);
}
Listing 8: ThermistorSensor.pde
A Temperature resolution
In this Appendix we consider how the resolution of the Analog to Digital Con-
verter and the choice of the fixed resistor can affect the temperature resolution
of the circuit in Figure 1.
Thermistors can be characterized by their resistance at 21 ◦C. We will des-
ignate that resistance RT∗
The Analog to Digital Converter (ADC) on the Arduino board has 10 bits of
resolution: the range of voltage inputs is divided into 210 = 1024 levels. The
standard input range is Vs = 5 V so the standard resolution of the input ADC
is
Vs
δV = = 4.88 mV (7)
1024
How does this voltage resolution determine the temperature resolution of the
Arduino when measuring thermistor output with the circuit in Figure 1? If
the voltage reading has a resolution of ±δV , then the uncertainty in voltage is
±δV /2. A change in voltage corresponds to a change in resistance.
Since
∗ Vs
RT = RT −1
Vo∗
then
Vs
RT∗ + δR = R − 1 (8)
Vo∗ + δV
T ∗ + δT = f (RT∗ + δR) (9)
Therefore
δT = (T ∗ + δT ) − T ∗ = f (RT∗ + δR) − f (RT∗ ) (10)
∗ ◦
For the thermistor in this demonstration, dT (T = T ) = 0.098 C
Figure 4 is a plot of δT as a function of fixed resistance R. The minimum
resolution (which is desired) is obtained when R = RT∗ . However, the shape of
the δT = f (R) function is rather flat near RT∗ . Therefore, the voltage divider is
relatively forgiving of mismatch between R and RT∗ .
It must be stressed that δT is not the accuracty of the temperature reading.
δT is only the resolution (or precision) of the temperature reading.
B Issues to Consider
B.1 ATMEL chips want low impedance on ADC inputs
From this thread on the Adafruit forum
http://forums.adafruit.com/viewtopic.php?f=25&t=15744
fat16lib quotes the ATmega328 data sheet, section 23.6.1:
0.14
0.12
0.1
δT ( C)
0.08
°
0.06
0.04
0.02
0
0 5 10 15 20 25 30
R (kΩ)