An Arduino thermometer with a 10k thermistor
Intermediate
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
A thermistor is a resistor that changes with temperature. The common kind is an NTC thermistor, which has less resistance as it warms up. A 10k one is 10,000 ohms at 25 °C, about 33,000 at freezing and under 6,000 at body heat. It costs a few cents, which is why it is in nearly every kit.
The circuit above is an Uno with a 10k thermistor and a 10k resistor on A0, and a 16x2 LCD that shows the temperature in °C and °F. Drag the slider on the thermistor and the reading follows. It runs in your browser on the sketch below, so you can see each step of the math come out in the serial monitor.
What you need
- An Arduino Uno
- A 10k NTC thermistor (beta 3950 is the common one)
- A 10k resistor
- A 16x2 LCD, wired as in the LCD tutorial
- A full-size breadboard and jumper wires
Wiring
| Part and pin | Goes to | Note |
|---|---|---|
| 10k resistor | 5 V to A0 | The top of the divider |
| Thermistor | A0 to GND | The bottom of the divider |
| LCD RS and E | Pins 12 and 11 | |
| LCD D4 to D7 | Pins 5, 4, 3, 2 | |
| LCD VSS, RW, V0, K | GND | |
| LCD VDD and A | 5 V |
From a resistance to a voltage
The Uno cannot measure resistance, only voltage. So the thermistor goes in a voltage divider with a fixed 10k resistor, and A0 reads the point between them. At 25 °C both are 10k, so A0 sits at half of 5 V and reads 512.
Warm the thermistor and its resistance falls, so the voltage at A0 falls too. In the circuit above, A0 reads about 540 at the starting 22.5 °C, 512 at 25 °C and 383 at 37 °C. Lower reading, warmer room. That is backwards from what most people expect, and it is the first thing to get straight.
From a voltage to degrees
The sketch works backward in two steps. First it turns the reading into ohms: R = 10000 × reading / (1023 − reading). Then it turns ohms into degrees with the beta equation from the datasheet: 1/T = 1/298.15 + ln(R / 10000) / 3950, with T in kelvin. Subtract 273.15 for °C.
Put 25 °C on the slider and the serial monitor prints "temperature 25.0 C". Put 37 °C and it prints "temperature 37.0 C". The log() call is in the Arduino math library, so the whole thing is two lines of floating point.
void loop() {
int reading = analogRead(A0);
if (reading <= 0 || reading >= 1023) {
lcd.setCursor(0, 0);
lcd.print("Check wiring ");
delay(500);
return;
}
float ohms = R_FIXED * reading / (1023.0 - reading);
float kelvin = 1.0 / (1.0 / 298.15 + log(ohms / R_25C) / BETA);
float celsius = kelvin - 273.15;
float fahrenheit = celsius * 9.0 / 5.0 + 32.0;
lcd.setCursor(0, 0);
lcd.print("Temp ");
lcd.print(celsius, 1);
lcd.print(" C ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.print(fahrenheit, 1);
lcd.print(" F ");
Serial.print("temperature ");
Serial.print(celsius, 1);
Serial.println(" C");
delay(500);
}How exact is it?
In Mokxi the thermistor follows the beta equation exactly, so the sketch reads back exactly what the slider says. A real one is not so tidy. A good part is within about 1% of its rated resistance, a single beta drifts by a degree or two at the ends of its range, and the current through the divider warms the bead a little. For better than a degree across a wide range, people use the three-term Steinhart-Hart equation and calibrate against a known temperature.
The simulated bead also changes the instant you move the slider. A real bead in epoxy takes a few seconds to catch up with the air around it.
Try it in the editor
Change BETA to 3435, a value other thermistors use, and see how far off the reading goes when the code and the part disagree. Then click the thermistor and set its beta property to 3435 too, and the reading is right again.
Swap the 10k resistor and the thermistor, so the thermistor is on top. Now the reading rises as it warms, and the formula in the sketch is wrong. You would need R = 10000 × (1023 − reading) / reading instead.
Common mistakes
Using a fixed resistor that does not match. The divider is easiest to read when the fixed resistor equals the thermistor at the middle of your range. A 10k thermistor wants a 10k resistor.
The formula for the other way around. Check which part is on top in your divider, and use the matching line for R.
The wrong beta. It is printed on the datasheet or the shop page, often as B25/50 or B25/85. 3950 is common but not universal.
Using integer math. 1 / 298.15 in integers is zero. Keep every number in the equation a float, as the sketch does.
Questions
How do I wire a 10k thermistor to an Arduino?
Put a 10k resistor from 5 V to A0 and the thermistor from A0 to GND. Read A0 with analogRead() and use the beta equation to turn the reading into degrees.
Do I need a library for a thermistor?
No. It is two lines of math with log() from the standard library, as in the sketch above. Libraries exist that wrap the same equation.
Thermistor or TMP36: which should I use?
A TMP36 gives a voltage that is already in a straight line with temperature, so the code is simpler. A thermistor is cheaper, more sensitive near room temperature and comes in waterproof probes. Both have tutorials here.
Why does my thermistor reading go down when it gets hot?
Because an NTC thermistor loses resistance as it warms, so with the thermistor on the bottom of the divider the voltage at A0 drops. The beta equation turns that falling reading into a rising temperature.
Keep going
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.