The Sensing Principle: How an NTC Sensor Thermistor Works

A Negative Temperature Coefficient (NTC) sensor thermistor is a passive semiconductor component whose electrical resistance drops predictably as its temperature rises. Manufactured from sintered metal oxides (like manganese, nickel, or cobalt), the ceramic matrix allows more charge carriers to jump the bandgap as thermal energy increases. For precision measurement, we typically use 10kΩ or 100kΩ NTC variants rated at 25°C, such as the Vishay NTCLE100E3103 or the EPCOS B57560G104F commonly found in 3D printer hotends. Unlike linear silicon sensors (e.g., LM35), the resistance-to-temperature curve of an NTC thermistor is highly exponential, requiring logarithmic math to extract accurate physical units.

Because the thermistor is a purely passive resistive element, it cannot output a digital signal or generate its own voltage. The output of a raw sensor thermistor is an analog voltage derived by placing it in a voltage divider network with a fixed reference resistor. As the thermistor's resistance shifts with temperature changes, the voltage at the divider's midpoint shifts proportionally. A microcontroller's Analog-to-Digital Converter (ADC) then samples this analog voltage, yielding a raw integer that must be mathematically scaled back into Ohms, and finally into Celsius or Kelvin.

Wiring and Pinout: Interfacing with ESP32 and Arduino

To read the analog voltage, you must build a voltage divider. The fixed resistor value should ideally match the nominal resistance of the thermistor at the center of your target measurement range (e.g., a 10kΩ resistor for a 10kΩ thermistor measuring room temperature). This maximizes the voltage swing and ADC resolution around your target.

Table 1: Sensor Thermistor Voltage Divider Wiring
Connection Point Microcontroller Pin Supply Range Notes & Constraints
VCC (Top of Divider) 3.3V or 5V Pin 3.3V - 5.0V Use the same voltage as the MCU's ADC reference (VREF).
Midpoint (Signal) ADC Input (e.g., GPIO 34) 0V - VCC Keep wires short (<50cm) to avoid capacitive coupling and EMI.
GND (Bottom of Divider) GND 0V Ensure a solid ground plane; noisy grounds ruin ADC resolution.
⚠️ ESP32 ADC Gotcha: The ESP32's internal ADC (ADC1) is notoriously non-linear near the rails (0V and 3.3V) and clips around 3.1V. If your thermistor reads max out at ~97°C instead of 100°C+ on an ESP32, this ADC saturation is the culprit. Stick to the mid-range voltages (0.5V to 2.5V) for accurate readings, or use an external I2C ADC like the ADS1115.

The Math: Converting Raw ADC Readings to Celsius

Translating the raw ADC integer into a usable temperature requires a three-step mathematical pipeline. Skipping or approximating these steps is the most common reason builders complain about "inaccurate" thermistors.

Step 1: Raw ADC to Voltage
Divide the raw ADC reading by the maximum ADC value, then multiply by the reference voltage. For a 10-bit Arduino (1023 max) at 5V, or a 12-bit ESP32 (4095 max) at 3.3V.

Step 2: Voltage to Resistance
Using the voltage divider formula, solve for the thermistor's resistance ($R_t$). If the thermistor is connected to GND (pull-up configuration with fixed resistor $R_s$ to VCC):
$R_t = R_s / ((V_{cc} / V_{out}) - 1)$

Step 3: Resistance to Temperature (The Beta Equation)
While the full Steinhart-Hart equation uses three coefficients for lab-grade accuracy across wide ranges, the Beta ($\beta$) parameter equation is perfectly adequate for most DIY and industrial applications spanning -20°C to +120°C. You will find the Beta value (usually between 3400K and 3950K) on the component's datasheet.

// C++ Implementation for Arduino / ESP32
const float VCC = 3.3;          // Supply voltage
const float R_SERIES = 10000;   // 10kΩ pull-up resistor
const float R_NOMINAL = 10000;  // Thermistor resistance at 25°C
const float T_NOMINAL = 25.0;   // Nominal temperature (Celsius)
const float B_COEFF = 3950;     // Beta coefficient from datasheet
const int ADC_MAX = 4095;       // 12-bit for ESP32 (use 1023 for Arduino)

float readThermistorCelsius(int rawADC) {
  // Prevent division by zero
  if (rawADC <= 0) rawADC = 1;
  if (rawADC >= ADC_MAX) rawADC = ADC_MAX - 1;

  // Step 1 & 2: Calculate Resistance
  float voltage = (rawADC / (float)ADC_MAX) * VCC;
  float resistance = R_SERIES * (voltage / (VCC - voltage));

  // Step 3: Beta Equation
  float steinhart;
  steinhart = resistance / R_NOMINAL;     // (R/Ro)
  steinhart = log(steinhart);             // ln(R/Ro)
  steinhart /= B_COEFF;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (T_NOMINAL + 273.15);// + (1/To)
  steinhart = 1.0 / steinhart;            // Invert
  steinhart -= 273.15;                    // Convert to Celsius

  return steinhart;
}

Interference, Calibration, and Real-World Gotchas

When your physical build doesn't match the math, the culprit is almost always environmental interference or hardware limitations. According to Analog Devices application notes, thermistor measurement errors usually stem from three sources:

  1. Self-Heating: Current flowing through the thermistor generates $I^2R$ heat. If your series resistor is too small, the thermistor will heat itself, reading 1-2°C higher than ambient. Keep the continuous current below 50µA for precision work by using higher value resistors (e.g., 100kΩ) or powering the divider from a GPIO pin that you only turn HIGH during the brief moment of ADC sampling.
  2. ADC Reference Drift: If you power your voltage divider from the USB 5V line, but the MCU's ADC references its internal 3.3V regulator, any USB ripple will look like a temperature change. Always derive the divider's VCC from the exact same voltage reference the ADC uses (e.g., the 3V3 pin on an ESP32).
  3. EMI and Wire Capacitance: Long, unshielded wires act as antennas, picking up 50/60Hz mains hum. This causes the ADC reading to jitter. Fix this by adding a 100nF ceramic capacitor in parallel with the thermistor (between the ADC pin and GND) to form a low-pass hardware filter, and use twisted-pair cable for runs over 1 meter.

Calibration Scaling: If you need absolute accuracy (±0.1°C), the Beta equation is not enough. You must perform a multi-point calibration. Submerge the thermistor in an ice bath (0°C) and boiling water (100°C, adjusted for your local altitude/barometric pressure), record the raw ADC values, and use those three points to solve for the A, B, and C coefficients of the full Steinhart-Hart equation.

Sensor Thermistor FAQ

How do I calibrate a sensor thermistor for a 3D printer hotend?

3D printer firmware (like Marlin) relies on pre-calculated lookup tables rather than calculating the Beta equation on the fly to save CPU cycles. To calibrate a 100kΩ hotend sensor thermistor, you must generate a custom resistance-to-temperature table. You can do this by measuring the thermistor's resistance at three distinct temperatures (e.g., ice water at 0°C, boiling water at 100°C, and hot oil at 200°C) using a trusted multimeter. Input these three (Resistance, Temperature) pairs into an online Steinhart-Hart calculator to generate the A, B, and C coefficients, then use Marlin's CREATE_THERMISTOR_TABLE.py script to output the C-array required for your configuration.h file.

Why is my ESP32 sensor thermistor reading fluctuating wildly?

Wild fluctuations (e.g., jumping ±3°C per second) on an ESP32 are almost always caused by ADC noise combined with the ESP32's internal Wi-Fi/Bluetooth RF interference. The ESP32's internal ADC has a noise floor of roughly 100mV, which translates to several degrees of error on a standard 10kΩ divider. To fix this, implement a software rolling average (e.g., sample 20 times and discard the highest and lowest 3 readings before averaging), add a 100nF hardware bypass capacitor at the ADC pin, or bypass the internal ADC entirely by using an external I2C 16-bit ADC like the Texas Instruments ADS1115, which provides rock-stable, noise-free readings.

Sensor thermistor vs DS18B20 digital probe: which should I use?

Choose a raw sensor thermistor when you need ultra-fast thermal response times (bare glass bead thermistors react in under 2 seconds), high-temperature survival (up to 300°C for specialized PTFE-coated variants), or analog simplicity without library dependencies. Choose a DS18B20 digital probe when you need to run cables over long distances (up to 100 meters via the 1-Wire protocol without signal degradation), require factory-calibrated ±0.5°C accuracy without writing math code, or need to daisy-chain multiple sensors on a single GPIO pin. The DS18B20 is generally superior for ambient room, liquid, or outdoor weather station monitoring, while the thermistor wins for tight-space, high-heat, or rapid-thermal-shock applications like soldering iron tips and 3D printer nozzles.