Arduino Thermistor Theory, Calibration, and Experiment
PCBGOGO - Manufacturer Sponsor for this project
I will be using an NTC 3950 100k thermistor as mentioned above, and it will serve as the primary component used in this tutorial. Additionally, an Arduino board will be needed along with a DHT22 temperature sensor if the user is planning to follow along completely with this experiment. I have added a parts list below with some affiliate link from amazon:
Thermistors can be approximated by assuming a third-order function called the Steinhart-Hart approximation [source on thermistor calibration]:
where T is the temperature calculated from the thermistor change in resistance, R . The coefficients C0 , C1 , and C2 need to be found using a non-linear regression method. The Steinhart-Hart equation is often simpilfied and rewritten as an exponential of first order:
Now we see an approxate method for relating T to the resistance, R . The coefficients a, b, c can be found using a least-squares fit against factory calibration data that be acquired from the manufacturer. For my thermistor, I found factory tables that allowed me to fit the data using the equation above [example datasheet with table].
Using Python, I was able to download one of the tables for my thermistor and fit the data to an exponential curve using the function above and scipy’s ‘curve_fit’ toolbox. The resulting relationship and coefficients are shown below:
Now that we have a relationship between the resistance of the thermistor wire and the temperature measured, we need to understand how we can translate resistance into a meaningful quantity that we can measure using an analog-to-digital converter, namely, we need to convert resistance to voltage. And this is explained in the next section.
Arduino has a 10-bit analog-to-digital converter (ADC) that measures voltage values. Since our thermistor outputs resistance, we need to construct a relationship between our resistance and voltage in order to relate the change in resistance to voltage. We can do this using a simple voltage divider:
For Arduino, we will use 3.3V as our V0 to keep the noise low on the thermistor measurements. Using Kirchhoff’s Laws to derive a relationship between our voltage input and two resistances using the following relation:
which we can rewrite in terms of resistances and the common loop current:
Lastly, we can rewrite our current as a function of the two resistances of the loop:
Combining the last two equations, we can get a representation for the voltage across the second resistor (our thermistor):
And finally, we have the classic voltage divider equation:
The full implementation of the algorithms and Figures 1 and 3 is implemented below in Python 3.6.
Now that we have a relationship between the voltage read by the Arduino and the temperature measured by the thermistor, and we have selected our voltage divider resistor - we can now test if the system works and if our algorithm is correct! The correct prediction of temperature from the known parameters above is as follows:
A few observations can be made regarding the wiring diagram above. The first, is that a 10uF capacitor is placed between the 3.3V and GND pins. Also, it is important to note that we will be using an external voltage reference using the 3.3V pin. And the reason is twofold: the expected voltage from the thermistor will be in the 1.5V range, and secondly, the 3.3V pin has less noise so our voltage readings will be more stable, resulting in more stable temperature readings (read more about the reference voltage here). The Arduino code for measuring temperature using our derivations above and the wiring in Figure 4 is below:
The code above averages 10 temperature readings for a more stable output and gives a readout roughly every 500 ms in both Celsius and Fahrenheit. The parameters should be updated for the user-specific thermistor, and the average amount can also be adjusted based on the user’s desired stability.
In the next section I compare our thermistor to a DHT22 temperature and humidity sensor.
As a simple test, I decided to wire up a DHT22 temperature and humidity sensor to see how well the thermistor equation approximate temperature based on its resistance. The DHT22 is a classic Arduino sensor, so I expected the two to be fairly close when compared at room temperature. I also wanted to see their respective responses when their surrounding temperatures are increased and watch the response with time to get an idea of how the sensors work over actively changing temperature scenarios.
The wiring for the thermistor and DHT22 sensor combination is shown below.
The Arduino code to accompany the DHT22 and thermistor comparison is also given below. It uses the “SimpleDHT” library which can be installed through the Library Manager.
The code above calculates both temperatures and prints them to the serial monitor every 0.5 seconds. It also averages every 10 readings from the thermistor. The code also prints out the difference between the two temperature sensor methods. Below, I have plotted the temperature difference to show the average deviation between thermistor and DHT22.
On average and depending on the actual temperature, the difference can span 0.05 C - 1.5 C. And this span is likely due to a few things: the ADC is somewhat noisy on the Arduino, even with a capacitor and 3.3V external voltage reference - not to mention it’s only 10-bit; the thermistor equation also carries some error with it - so for highly accurate readings a temperature-by-temperature interpolation would be the most accurate way to ensure quality results; and lastly, the DHT22 additionally carries 0.5 C error with it, so we can expect errors between them to be as high as 2 C. So, the fact that we’re only seeing 0.5 C difference between them is not bad!
Just to contrast the abilities of the two sensors, the plot below demonstrates the power of the thermistor and the weakness of the DHT22:
In the plot above, it’s easy to see the power of the thermistor and its ability to handle quick-changing scenarios. The DHT22 is only equipped to handle a 0.5s update rate, and in reality can only resolve ambient temperatures, not large bursts of hot or cold. The plot below really illustrates the deficiencies in the DHT22’s ability to handle bursts of temperature changes. Thermistors have temperature responses that are fairly quick, while the DHT22 takes a few readings. The DHT22 also requires some time to recover from a heating period, primarily because of its housing and slow component response.
The thermistor is a clear winner when temperature fluctuations are of great importance to measurements. This is why they are often used in experiments where temperatures do fluctuate quickly and accurate measurements are needed.
In this article, I discussed thermistors and how to implement them in Arduino by fitting factory calibrated data to acquire accurate coefficients for finding temperature from resistance. I also discussed how to use a voltage divider to measure voltage as a function of resistance outputted form the thermistor. And lastly, I used a DHT22 temperature sensor to compare the accuracy and advantages of using a thermistor.
Thermistors are used in a wide variety of applications because of their accuracy, high responsivity in rapidly changing environments, and their inexpensive and easy-to-use hardware. One of the difficulties with using thermistors is their non-linear repsonse, however with quality calibration and response curves, the non-linear effects can be handled. There are many other experiments that can be done with thermistors to analyze their time responses, lower the non-linear hindrances, and investigate the self-heating effects. This project was meant to introduce thermistors and their theory, while also increasing the understanding of why they are a great choice over other temperature-sensing methods.
See More in Arduino and Sensors: