Lesson 1.12: Thermometer
This lesson puts together what you've seen so far —an analog input, a voltage divider and the display from the previous lesson— to build a thermometer that doesn't need a computer.
Parts
Libraries
- LiquidCrystal — bundled with the IDE
How it works
An NTC thermistor's resistance drops as it warms up. In series with a fixed 10 kΩ resistor it forms a voltage divider, and the midpoint voltage, read on A0, changes with temperature.
From the reading you solve for the thermistor's resistance. With the thermistor towards 5V and the fixed resistor towards GND: R = 10,000 × (1023 / reading − 1).
Resistance and temperature aren't linearly related. For household temperatures the beta-coefficient equation is enough: 1/T = 1/T₀ + ln(R/R₀)/B, with T in kelvin, R₀ = 10 kΩ at T₀ = 25 °C (298.15 K) and B the thermistor's coefficient, often 3950. If you need more accuracy, the Steinhart-Hart equation refines the result with three coefficients.
Wiring
| Component | Connects to | Note |
|---|---|---|
| LCD display | Same as in the previous lesson | RS to 12, E to 11 and D4–D7 to 5, 4, 3 and 2 |
| Thermistor, leg 1 | 5V | |
| Thermistor, leg 2 | A0 | |
| 10 kΩ resistor | Between A0 and GND |
Code
// Thermometer with a 10 kΩ NTC thermistor and an LCD.
#include <LiquidCrystal.h>
#include <math.h>
const int SENSOR_PIN = A0;
const float R_FIXED = 10000.0; // fixed resistor of the divider
const float R_NOMINAL = 10000.0; // thermistor at 25 °C
const float T_NOMINAL = 298.15; // 25 °C in kelvin
const float BETA = 3950.0; // from the thermistor's datasheet
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.begin(16, 2);
lcd.print("Temperature:");
}
void loop() {
int reading = analogRead(SENSOR_PIN);
if (reading <= 0 || reading >= 1023) return; // out of range: check the wiring
float resistance = R_FIXED * (1023.0 / reading - 1.0);
float kelvin = 1.0 / (1.0 / T_NOMINAL + log(resistance / R_NOMINAL) / BETA);
float celsius = kelvin - 273.15;
lcd.setCursor(0, 1);
lcd.print(celsius, 1); // one decimal
lcd.print((char)223); // degree symbol
lcd.print("C "); // the spaces clear leftovers from longer readings
delay(500);
}What the code does
- The constants at the top describe the circuit and the thermistor: if yours has a different B or nominal resistance, that's the only place to change it.
- log() is the natural logarithm, ln, in C++.
- lcd.print(celsius, 1) prints the number with one decimal: the circuit isn't more precise than that.
- (char)223 is the degree symbol in the display's character set.
Step by step
- Wire the display as in the previous lesson.
- Add the voltage divider: the thermistor between 5V and A0, and the 10 kΩ resistor between A0 and GND.
- Upload the code.
- Hold the thermistor between your fingers and watch the temperature rise.
Result
The display shows the temperature with one decimal and updates twice a second. Warming the thermistor with your fingers raises it a few degrees.
If it doesn't work
- If the temperature drops when you warm it, the thermistor and the resistor are swapped in the divider: swap them back or use R = 10,000 / (1023 / reading − 1).
- If the reading is a few degrees off a reference thermometer, adjust BETA and R_NOMINAL to your thermistor's data.
- If the display shows nothing, go back to the previous lesson: the problem is in its wiring or the contrast.