NTC thermistor/Using it/09. A temperature alarm
Using it · 09 of 12

A temperature alarm

A TK01 XL LED that lights above 28 °C. Switch it off at the same line and it flickers every time the reading wobbles across; switch it off one degree lower and it changes exactly once each way. That gap is hysteresis.

One line is not enough

The obvious alarm is one comparison: LED on if the temperature is above 28 °C, off if it is below. It works, until the temperature settles close to 28.

A temperature alarm
Switch off at
Reading
21.8 °C
TK01
off
Switched
0 times
A finger goes on the thermistor at 2 s and comes off at 14 s. Run it and watch the TK01's lane.

Run it with 28 °C, the same line. A fingertip on the thermistor pushes the reading up towards skin temperature, and it levels off not far above the line. Then the last few tenths of a degree of wobble carry it back and forth across 28, and the LED follows every crossing. The trace is drawn to show the behaviour, not recorded, but any real sensor near a threshold does the same.

On an LED it is a flicker. On a relay it is chatter, and on a buzzer a stutter.

Two lines

Now pick 27 °C, one degree lower. The LED turns on when the reading reaches 28 °C, and turns off only when it falls below 27. Between the two lines it stays as it was. The wobble is smaller than the gap, so it never reaches the other line, and the LED changes exactly twice.

That gap is called hysteresis, and the sketch holds it in two lines:

if (!alarmOn && c >= ALARM_C) alarmOn = true;
if (alarmOn && c < ALARM_C - HYST_C) alarmOn = false;

alarmOn remembers which side of the gap the alarm is on. Each line can only change it in one direction.

Wiring the LED

The TK01 goes in beside the thermistor: its GND to GND, its SIGNAL to the pin the XL LED book uses, D9 on an Uno, GPIO 4 on an ESP32, GP15 on a Pico. On an ESP32-S3 the XL LED book's GPIO 4 is already the thermistor here, so the LED moves to GPIO 5.

The sketch waits 250 ms between readings with delay, which is fine for an alarm that only has one job. If it has to do other things too, blinking without stopping is the way to take the delay out.

The code

The averaged reading, plus a TK01 XL LED that turns on at ALARM_C and turns off only below ALARM_C minus HYST_C. The LED's state is remembered in alarmOn so each line only fires when it has to.

ntc_alarm.ino
/*
  NTC Thermistor - a temperature alarm                   TK12 / /p/tk12

  Wiring, the TK12. Count from the square pad, parts up, header at
  the bottom:

    GND    -> GND
    VCC    -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
              ESP32-S3, GP26 on a Raspberry Pi Pico

  The TK01 XL LED, counted the same way:

    GND    -> GND
    NC     -> nothing   (both of its NC pins)
    SIGNAL -> D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an
              ESP32-S3, GP15 on a Raspberry Pi Pico

  Arduino IDE
    Tools > Board                 your board, e.g. Arduino Uno
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    No library needed.
*/

#include <math.h>

// The analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int SENSOR_PIN = A0;
// The TK01's SIGNAL. Uno: 9. ESP32: 4. ESP32-S3: 5. Pico: 15.
const int LED_PIN = 9;

const float ALARM_C = 28.0;      // on at or above this
const float HYST_C = 1.0;        // off only below ALARM_C - HYST_C

const int SAMPLES = 32;
const float R_FIXED = 10000.0;   // the 10 kOhm from VCC to SIGNAL
const float R25 = 10000.0;       // the thermistor at 25 C: the "103"
const float B = 3950.0;          // its B value: the "3950"
const float T0 = 298.15;         // 25 C in kelvin
const float VCC_MV = 3300.0;     // ESP32 only: your 3V3 pin, measured

bool alarmOn = false;

float thermistorOhms() {
  float sum = 0;
#if defined(ARDUINO_ARCH_ESP32)
  for (int i = 0; i < SAMPLES; i++) sum += analogReadMilliVolts(SENSOR_PIN);
  float mv = sum / SAMPLES;
  if (mv <= 0 || mv >= VCC_MV) return NAN;
  return R_FIXED * mv / (VCC_MV - mv);
#else
  for (int i = 0; i < SAMPLES; i++) sum += analogRead(SENSOR_PIN);
  float n = sum / SAMPLES;
  if (n <= 0 || n >= 1023) return NAN;
  return R_FIXED * n / (1023.0 - n);
#endif
}

float celsius(float ohms) {
  float invT = 1.0 / T0 + log(ohms / R25) / B;
  return 1.0 / invT - 273.15;
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  float r = thermistorOhms();
  if (isnan(r)) {
    Serial.println("SIGNAL at 0: check VCC. At the top: check GND.");
    delay(500);
    return;
  }
  float c = celsius(r);

  if (!alarmOn && c >= ALARM_C) alarmOn = true;
  if (alarmOn && c < ALARM_C - HYST_C) alarmOn = false;
  digitalWrite(LED_PIN, alarmOn ? HIGH : LOW);

  Serial.print(c, 2);
  Serial.println(alarmOn ? " C  ALARM" : " C");
  delay(250);
}

Set HYST_C to 0 to see what the figure shows without it: near 28 °C the LED flickers. LED_PIN is the TK01 XL LED book's own pin, except on the ESP32-S3, where GPIO 4 is the thermistor here, so the LED moves to GPIO 5.

When it does not work

How do I test it without a heater?

Hold a fingertip on the thermistor. A fingertip is warmer than most rooms, and the reading climbs past 28 °C within several seconds. If your room is already above 28 °C, raise ALARM_C a few degrees until the LED starts off.

How wide should the hysteresis be?

Wider than the flicker, narrower than you care about. With 32 readings averaged the flicker is a small fraction of a degree, so one degree is ample. A heater or a fan that should not switch every few seconds wants several degrees.

The LED never lights.

Check the TK01 alone first: its SIGNAL on LED_PIN, its GND on GND, and a sketch that just sets LED_PIN HIGH. Then open the serial monitor and see what temperature the sketch thinks it is. If the reading is right and below 28, warm it more or lower ALARM_C.

Can I switch something bigger than an LED?

Through a relay block or a transistor, yes, and there hysteresis matters more: a relay that chatters wears out its contacts. Never power a motor or a heater from the pin itself.

Where this goes next

What the ±1 % parts allow, and what they leave out.

How far to trust it

Edit this page — content/books/ntc-thermistor/a-temperature-alarm.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

NTC Thermistor

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum