Learning Goals 5 min
- Wire an NTC thermistor with a 10 kΩ partner resistor as a voltage divider, and explain why the voltage on A0 changes with temperature.
- Convert an ADC reading to thermistor resistance using the divider equation, then to temperature in °C using the simplified Steinhart-Hart (β-parameter) formula.
- Pinch the thermistor between your fingers and watch the printed °C climb in real time — your first quantitative real-world measurement.
Warm-Up 10 min
So far we've used the ADC to read "0–1023". That's a number, not a temperature. To get to °C we need two conversions and one formula. Together they aren't scary — but skipping the explanation leaves you with magic incantations. Today we earn the magic.
Quick puzzle
An NTC thermistor has resistance 10 kΩ at 25 °C. As it gets hotter, the resistance:
- (a) goes up
- (b) goes down
- (c) stays the same
Reveal
(b) goes down. NTC = Negative Temperature Coefficient. Hotter → fewer ohms. Cooler → more ohms. The opposite of most things you know (a copper wire's resistance goes up with temperature). That single property — coupled with the right circuit — is everything we need.
New Concept · Voltage divider + β equation 20 min
The voltage divider
The thermistor and a 10 kΩ resistor in series, between +5 V and GND, form a voltage divider. The voltage at the midpoint depends on the ratio of the two resistors:
V_out = 5 V × R_fixed / (R_thermistor + R_fixed)When the thermistor is at 25 °C, it's 10 kΩ — same as the fixed resistor — so V_out = 2.5 V exactly. As the thermistor heats up and its resistance drops, R_fixed becomes the bigger of the two, so V_out rises toward 5 V. Cool the thermistor → its resistance rises → V_out drops toward 0 V.
Wiring it up
| From | Via | To |
|---|---|---|
| +5V rail | Thermistor | A0 column (midpoint) |
| A0 column (midpoint) | 10 kΩ resistor | GND rail |
Two components, three wires, one analog reading. Don't worry about which way the thermistor faces — it's a passive resistor with no polarity.
From V_out back to thermistor resistance
The ADC reads V_out as a number 0–1023. We need to go backwards through the divider to get the thermistor's actual resistance. Rearranging the divider equation:
R_thermistor = R_fixed × (1023 / raw - 1)(Quick sanity check: when raw = 511 — half-way — that gives 10000 × (1023/511 - 1) ≈ 10020 Ω, almost exactly 10 kΩ. Matches the 25 °C case. Good.)
From resistance to temperature — the β equation
The full Steinhart-Hart equation has three coefficients and an awkward logarithm. For Level 2 we use the simplified β-parameter form, which uses only one extra constant β (beta — typically around 3950 for hobby thermistors):
1/T_K = 1/T0_K + (1/β) × ln(R / R0)where:
- T_K = current temperature in Kelvin (what we want).
- T0_K = reference temperature in Kelvin — usually 298.15 (which is 25 °C).
- R0 = thermistor resistance at the reference — for a 10 kΩ NTC, R0 = 10000.
- R = current thermistor resistance (we just computed it).
- β = the thermistor's "beta" constant — typically 3950 for the common 10 kΩ NTC modules sold for Arduino.
Solve for T_K, then convert to °C by subtracting 273.15. In C++:
float tK = 1.0 / (1.0/298.15 + (1.0/3950.0) * log(R / 10000.0));
float tC = tK - 273.15;log here means natural log (base e) in C++ — the standard convention. Don't use log10 by accident.
Putting it together
int raw = analogRead(A0);
float R = 10000.0 * (1023.0 / raw - 1.0);
float tK = 1.0 / (1.0/298.15 + (1.0/3950.0) * log(R / 10000.0));
float tC = tK - 273.15;That's the whole conversion. From here you can Serial.print(tC, 1) for one decimal place, compare to a threshold, trigger an alert, log it. Tomorrow's Personal Thermometer project does all of that.
Worked Example · Read the thermistor and print °C 20 min
Step 1 — wiring
Build the divider as described above. Thermistor between +5 V and A0; 10 kΩ resistor between A0 and GND. Three breadboard wires. Take a moment to double-check both ends of the divider make solid contact — a loose wire here gives a wandering reading.
Step 2 — the sketch
Save as thermistor-read.ino:
// L02-11: NTC thermistor → °C using β-equation
const int THERM = A0;
const float R_FIXED = 10000.0; // partner resistor in ohms
const float R0 = 10000.0; // thermistor R at reference temperature
const float T0_K = 298.15; // reference temperature in Kelvin (25 °C)
const float BETA = 3950.0; // thermistor beta constant
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(THERM);
float R = R_FIXED * (1023.0 / raw - 1.0);
float tK = 1.0 / (1.0/T0_K + (1.0/BETA) * log(R / R0));
float tC = tK - 273.15;
Serial.print("raw: "); Serial.print(raw);
Serial.print(" R: "); Serial.print(R, 0);
Serial.print(" Ω T: "); Serial.print(tC, 1);
Serial.println(" °C");
delay(500);
}Step 3 — upload and read
Open Serial Monitor. With the thermistor sitting in still room air:
raw: 512 R: 9961 Ω T: 25.0 °C raw: 511 R: 10020 Ω T: 24.9 °C raw: 513 R: 9902 Ω T: 25.1 °C
Should hover around your room temperature — ~25 °C if you're in an air-conditioned classroom; ~28 °C if it's a warm afternoon. Some jitter is normal; you can apply L02-08's smoothing to flatten it.
Step 4 — pinch the thermistor
Squeeze the thermistor between your fingertip and thumb. Watch the temperature climb steadily over 30–60 seconds toward 32–34 °C (your skin temperature). Release — it drops back to room temp over the next 30 seconds. The Arduino is now a thermometer.
Step 5 — sanity check with a real thermometer
If you have a kitchen thermometer or a phone with a temperature sensor, compare. The Arduino reading should be within ±2 °C of the truth across normal room ranges. If it's consistently 3 °C too high or too low, tweak BETA up or down by ~100 and re-test.
Try It Yourself 20 min
Goal: Add the smoothing from L02-08. Apply a running average with N = 10 to the raw reading before computing R and T. The °C display should stop wobbling.
Hint
Take the smoothed-pot pattern from L02-08 and use it on the raw thermistor reading. Convert the smoothed value (still 0–1023) to R and T as before. Lower visible wobble → higher confidence in readings.
Goal: Print the temperature in both °C and °F simultaneously. Useful for showing a Malaysian classroom — kids see both metric and the format they'll meet on US web pages.
Hint
°F = °C × 9 / 5 + 32. Computed as float from tC:
float tF = tC * 9.0 / 5.0 + 32.0;
Serial.print(tC, 1); Serial.print(" °C ");
Serial.print(tF, 1); Serial.println(" °F");Goal: Refactor the conversion into a helper function: float readTempC(int pin). The function does the read + R + T calculation and returns °C. Then loop() is one line: Serial.println(readTempC(A0), 1);.
Hint
float readTempC(int pin) {
int raw = analogRead(pin);
float R = R_FIXED * (1023.0 / raw - 1.0);
float tK = 1.0 / (1.0/T0_K + (1.0/BETA) * log(R / R0));
return tK - 273.15;
}Now the maths is in one place. If you ever change BETA or R0 for a different thermistor, you change one constant — the rest of the sketch is untouched. This is the function-as-recipe pattern from L01-12.
Mini-Challenge · The cold-warm-hot indicator 15 min
Use the thermistor on A0, plus three LEDs (blue on D9, green on D10, red on D11 — each with its own 220 Ω). Wire them as in L02-05's RGB lesson but using three separate LEDs.
The sketch reads the temperature and lights exactly one LED:
- Blue if T < 24 °C (cool).
- Green if 24 ≤ T < 30 °C (normal room).
- Red if T ≥ 30 °C (warm/hot).
It works if:
- At rest in a typical Malaysian classroom (~26 °C) → green is on.
- Pinch the thermistor for 60 seconds → red turns on (your skin is warmer than 30 °C).
- Blow on the thermistor (the breath is cooler than skin) → may flicker between red and green as it cools.
- Submerge it briefly in a glass of ice water (carefully, don't splash the Arduino) → blue turns on.
Reveal one valid sketch
const int THERM = A0;
const int BLUE = 9;
const int GREEN = 10;
const int RED = 11;
const float R_FIXED = 10000.0;
const float R0 = 10000.0;
const float T0_K = 298.15;
const float BETA = 3950.0;
float readTempC() {
int raw = analogRead(THERM);
float R = R_FIXED * (1023.0 / raw - 1.0);
float tK = 1.0 / (1.0/T0_K + (1.0/BETA) * log(R / R0));
return tK - 273.15;
}
void setColour(int b, int g, int r) {
digitalWrite(BLUE, b);
digitalWrite(GREEN, g);
digitalWrite(RED, r);
}
void setup() {
pinMode(BLUE, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(RED, OUTPUT);
Serial.begin(9600);
}
void loop() {
float t = readTempC();
Serial.print("T: "); Serial.print(t, 1); Serial.println(" °C");
if (t < 24) setColour(HIGH, LOW, LOW); // blue
else if (t < 30) setColour(LOW, HIGH, LOW); // green
else setColour(LOW, LOW, HIGH); // red
delay(500);
}Two helpers (readTempC and setColour) keep the main loop crystal clear. The thresholds 24 and 30 are tunable for your room — air-conditioned classrooms might use 22/28; outdoor pavilions might use 28/34.
Recap 5 min
A thermistor changes its resistance with temperature. Put it in series with a fixed 10 kΩ resistor across +5 V and GND, and the midpoint voltage carries the temperature information. The Arduino reads the voltage, you compute the thermistor's resistance from the divider equation, then you plug R into the β-equation to get Kelvin, subtract 273.15 to get Celsius. Wrap the maths in a helper function and you have a clean readTempC() you can use anywhere. Tomorrow we turn all of this into a polished Personal Thermometer project with thresholds and alarms.
- Thermistor
- A resistor whose resistance changes significantly with temperature. NTC = resistance drops as temperature rises. PTC = opposite.
- NTC (Negative Temperature Coefficient)
- The common kind in hobby kits. 10 kΩ NTC = 10 kΩ at 25 °C, lower above, higher below.
- Voltage divider
- Two resistors in series across a voltage. The midpoint voltage = V_total × R_lower / (R_upper + R_lower). Used to convert a variable resistance into a variable voltage.
- β (beta) parameter
- The single thermistor constant in the simplified Steinhart-Hart equation. Typically 3950 for the common 10 kΩ NTC.
- Kelvin
- Absolute temperature scale where 0 K is absolute zero. T(K) = T(°C) + 273.15.
log()(in C++)- Natural logarithm — base e. Not base 10. (Base 10 is
log10().)
Homework 5 min
Three temperatures, three places. Run your thermistor sketch in three different spots and record what you see:
- Inside the fridge for 30 seconds (carefully — keep the Arduino out, dangle just the thermistor leads through the door).
- On your desk at room temperature.
- Held against your skin for 60 seconds.
For each, note the displayed °C, your expected °C (use a kitchen thermometer or just common sense), and the difference. If the readings are within 2 °C across the board, your circuit is solid.
Bonus question: If your reading is consistently 2 °C high in all three measurements, what one constant would you change to fix it? (Hint — re-read the "watch out!" note on β.)
Bring back next class:
- Your three-temp comparison table.
- Your answer to the bonus question.
- Your
hw-l02-11.inosketch — bring it on your laptop. Tomorrow it becomes the personal thermometer.