<< Click to Display Table of Contents >>

Navigation:  Bits and PCs Blog - 2025.12.13 >

Temperature Sensors - 2025.03.12

Previous pageReturn to chapter overviewNext page

Several temperature sensor types are described below: NTC thermistor, PT100/500/1000 sensor, LMx35 precision analogue sensor, DS18xxx 1-wire digital sensor, LM75x digital temperature sensor, MCP9808 maximum accuracy digital sensor, D6T1A01 MEMS thermal imaging sensor, ... Each has C++ example code for Arduinos, easily adapted for ESP32 etc.

For overheating protection

When working with MOSFETs and other components that can overheat, it's a good idea to use temperature sensors in your prototypes to monitor the components. This helps reduce the size of your component cemetery. If overheating is still a risk, these sensors can be used in the final product too. My high-voltage high-current projects are prone to overheating if they are left running for too long. Low-cost RTD sensors (Resistance Temperature Detector or Resistive Temperature Device) are ideal for this, with ranges up to 600ºC.

MOSFETs and chips can operate at temperatures up to 175ºC or higher, so use a sensor that can detect well above the max. temperature - which will still return meaningful temperatures if it gets even hotter. Some sensor types start returning invalid temperatures if they get too hot (a bad idea), but NTC and Pt100/Pt1000 sensors are OK. Unless they melt.

A tiny NTC or Pt100 or Pt1000 sensor can be glued or taped directly to the case of the component, and sampled via any analogue input. For RTDs you can use a simple voltage divider to get reasonable accuracy. There is no need for a complicated circuit using an op amp unless you want high accuracy over a smaller range.

Fix the sensor to the component's case using high temperature polyamide tape (the copper-coloured stuff) with conductive paste, or heat-resistant-heat-conductive epoxy (this is not easy to find, and sometimes cracks off if regularly heated and cooled).

For temperature compensation

Sometimes temperature compensation is needed for sensitive circuits, like vibrating wire sensors (DigiSens.ch). Precision calibrated integrated-circuit sensors are ideal for this, such as the analogue LM135/235/335. These have a narrower range than RTDs, something like -30..+125ºC. However, if they go over their rated temperature they can start returning lower temperatures, which is not good for detecting overheating!

Digital temperature sensors with one-wire, I2C or SPI interfaces are also available, like the DS18B20 (range -55..+125ºC). These return the temperature as an accurate calibrated digital value in deg C or F. These also don't work for high overheating temperatures.

 

NTC Thermistors

ntc-thermistor (almost actual size)

NTC means Negative Temperature Coefficient - the resistance decreases as the temperature increases.

These sensors have a reasonable range, -40..+300ºC is common and some go all the way up to 600ºC. Miniature glass-encapsulated versions are often used in 3D printers. They do not have a linear response, the resistance changes far more at lower temperatures than it does at high temperatures. You can use the Steinhart-Hart equation to convert the resistance to temperature with reasonable accuracy.

If the temperature goes over the maximum, most of them will continue to return a meaningful resistance until the case actually melts. The 100K sensors I used work up to 500ºC, even though their rated maximum is 300ºC. Test this by heating it in a flame or small blowtorch (see Disclaimer). A component freezer spray can be used to test low temperatures down to -60ºC (but my MOSFETs rarely get that cold).

Thermistors are graded by their resistance at 25ºC (room temperature). For example, 10K ohms or 100K ohms at 25ºC. Choose the resistance according to the range you want to measure (see below). You can find the resistance-to-temperature tables on line. Each has a different resistance-to-temperature curve, roughly indicated by the sensor's "Beta value". The Beta value is always provided by the manufacturer, use the Beta value to find the right table. (But note that the online tables are often calculated from the Beta value using the equation - they are not actual measurements.)

The Steinhart-Hart equation needs three constants named A, B and C to configure the sensor. These are sometimes given by the manufacturer, but it's best to calculate them from the resistance-to-temperature tables of your sensor according to the range you want to measure. Three temperature/resistance values are needed to calculate the constants. For a small range, use the lower, middle and upper temperatures you want to measure. For component temperatures, a larger range is better (say) 25, 125 and 250ºC.

There are many thermistor constant calculators available on line. Here's the one that's linked to from the Wackypedia entry. I like this one because it also shows the curve. In the picture below, the curve is not too steep because a small range is being used (5..45ºC). For component temperature measurement you will need a larger range, so you will see a much flatter curve with a lower resolution at high temperatures, but that's OK for our application.

https://www.thinksrs.com/downloads/programs/therm%20calc/ntccalibrator/ntccalculator.html

thermistor-calculator

Once you have the three constants, A, B and C, use these in the simplified equation to convert the resistance Rt to temperature K in Kelvins. Don't forget to use the exponents (e-3 etc), and sometimes the mantissa is -ve (which is easy to miss).
 

 K = 1 / (A + B * ln(Rt) + C * (ln(Rt))^3)

Use the 'float' data type and return the result as an 'int', because the accuracy and resolution is not good enough for more than 3 significant digits. At low temperatures around room temperature it is quite accurate, but the accuracy (the resolution) decreases as the temperature increases.

The microcontroller's ADC is usually 10-bit (0-1023), which is spread over the entire temperature range, minus the offset from the voltage divider resistor, etc. This means you have quite a low resolution, especially at high temperatures - a change of '1' in the reading can mean a temperature change of several degrees.

Extreme Accuracy is not necessary for our application. We only need to know if it's warm, hot, very hot, or is about to explode. Short-circuit and open-circuit of the temperature sensor must also be detected.

Use a simple voltage divider to measure the sensor's resistance. Choose R1 according to sensor type and range, e.g. 4.7K or 10K ohms. It should be a 0.1% resistor with a low temperature coefficient like 25ppm/ºC. You must define this resistance value in the software, because it's used in the voltage calculation.

ntc-voltage-divider

It's easy to calculate the NTC sensor's resistance with this circuit. Vref should be the maximum voltage allowed by the analogue input (3.3 or 5V). 1024 is the 10-bit ADC range.

 int count = analogRead(pin);

 int vout = ((long)count * vref) / 1024;      // voltage across sensor in millivolts

 long r = ((long)vout * r1) / (vref - vout);  // resistance in ohms

Use a 32-bit long (or unsigned long) for the resistance because it can be > 16 bits. The code also needs averaging/smoothing and tests for short and open-circuit conditions.

 

Here's the full source code in C. This runs on all Arduinos, ESP32s, etc.

Note that I have used tab characters instead of spaces, with tabs set to 4 spaces. This is because I use 'Microsoft Visual Studio Community 2022' for development, with the Visual Micro Arduino IDE plugin to provide microcontroller support. This has more features than the Arduino IDE, it's more complicated to use but is way more intuitive than the awful 'VS Code'.

  NTC Thermistor source code, NTCThermistor.h   [Click to expand]

The optimized "rolling averager" is used to smooth the analogue readings.

  RollingAverage.h   [Click to expand]

 

Pt100/500/1000, Platinum Temperature Sensors

pt1000(not actual size, they're usually less than 3mm)

Example data sheet:
https://content.kemet.com/datasheets/YAGEO_Nexensos_M310_Datasheet_EN.pdf

These are probably the best type of analogue sensor, with a maximum ranges of -70..+600ºC. They are about the same price as the NTC thermistors. The cases are often flat (Yageo models) which make it easy to tape them to a MOSFET or chip. The resistance increases as the temperature increases.

There are three standard types, Pt100, Pt500 and Pt1000, defined by their resistance at 0ºC (100, 500 and 1000 ohms). It's basically just an etched platinum thin film resistor.

To calculate the temperature from the resistance, the easiest way is to use the IEC 60751 algorithm.

If the temperature is below 0ºC it should use a different algorithm, but since we're only interested in measuring heat, we can use only the > 0ºC algorithm, which is easier.

These sensors also use the voltage divider circuit shown above, the same as for the NTC Thermistor. It's important to limit the current through the sensor to prevent self-heating, and a minimum current is also needed.

 Pt100:   0.3 to 1 mA   - use 4.7K ohms at 3.3V, 5.6K at 5V
 Pt1000: 0.1 to 0.3 mA - use 12K ohms at 3.3V, 15K at 5V

But do the calculations yourself... see Ohm's Law. Or was it Cole's Law?

 

This code may not be accurate for values below 0ºC, but that's not a problem when testing for overheating.

  Source code using the DIN EN60751 Algorithm, Pt100x.h   [Click to expand]

 

LMx35, Precision Analogue Temperature Sensors

 

lmx35 (TO-92 or SOIC-8 package)

https://www.st.com/resource/en/datasheet/lm135.pdf

Use these if you are measuring temperatures -55..150ºC and you want greater accuracy. They need a supply of 5..40V, with a series resistor to limit the current to between 450uA and 5mA over the temperature range. They must be powered by a minimum of 5V, so if you're using a 3.3V microcontroller you will also need a voltage divider to keep the voltage below 3.3V.

The three models LM135/235/335 have different temperature ranges:
LM135 = -55 .. +150°C
LM235 = -40 .. +125°C
LM335 = -40 .. +100°C

Inside is a Zener diode with a breakdown voltage that varies according to the temperature, having a linear increase of 10mV per °K (Kelvin). The voltage variation with temperature is almost perfectly linear, so to calibrate the temperature very accurately you only need to add a single offset value. You could use a trimpot on the ADJ terminal for an adjustable offset voltage, but doing it in software is much cheaper.

 

Sufficient voltage to drive the sensor and its calibration circuit is needed. 3.3V is not high enough. Most of the examples in the data sheet show 15V, but anything from 5..40V works if you choose the right series resistance to limit the current to 450uA..5mA. Keep the current low to reduce internal heating, say max. 3mA, but don't let it go below 0.5mA because the sensor stops working.

When using a 3.3V controller you must use a second divider to reduce the voltage so it doesn't go over 3V. Use a pair of high-value resistors like 512K-512K. This divides the voltage by two, which makes it easy to calculate.

The resistors should have a low temperature coefficient to minimize drift, something like 25ppm/ºC. Avoid mounting the resistors near anything that gets warm, like a MOSFET or voltage regulator.

Because the sensor's output is linear, at 10mV/°K, you can use a single calibration point 'calibrationOffset'. There is no need to measure the voltage exactly, or mess about with the '2.982V at 25C' value. You can just set the calibration offset to adjust the voltage to the temperature. The calibration offset can be found by setting it to zero, and comparing the raw room temperature read by the sensor with the actual room temperature. The difference is the 'calibrationOffset'.

 

At 25°C the voltage is about 2.98V. With 10mV/°K (that's actually the same as 10mV/°C), then at -55°C it would be about 2.43V and at +150°C it would be 4.48V.

We know the current should be between 0.00045 and 0.005 Amps. The lowest current will be at 150°C, when the sensor drops 4.48V. If we say we want 500uA at 150°C, then we can calculate the resistance...

R1 = V / I
R1 = (Vcc - 4.48) / 0.0005
R1 = (5 - 4.48) / 0.0005
R1 = 1040 ohms -> use 1K ohms

At -55°C the current would be...

I = V / R
I = (5 - 2.43) / 1000
I = 2.57mA -> well within the max. value of 5mA

For higher Vcc voltages, increase the minimum current to 1 or 2mA, because the current range reduces as the voltage increases.

 

lmx35-voltage-divider

 

For a 3.3V controller, use the R2/R3 voltage divider to limit the analogue input voltage to less than 3V.
For a 5V controller, you don't need the R2/R3 divider.

 

  LMx35TempSensor.h   [Click to expand]

 

DS18xxx, 1-Wire Digital Thermometers

ds18b20 (TO-92 or SOIC-8 package)

They are also available in stainless steel waterproof packages, often with a connector board that has the I2C pull-ups.

ds18b20-waterproof

These are cheap sensors for reasonably accurate temperature measurement over the range -55°C .. +125°C. They are no good for over-temperature testing, but are perfect for temperature compensation and indoor or outdoor temperature measurement. These intelligent digital sensors can be powered by 3.3V or 5V, so you can use them with most microcontrollers.

There are three sensor types with different accuracies, DS18S20, DS19B20 and DS1822:
https://www.analog.com/media/en/technical-documentation/data-sheets/ds18s20.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ds18b20.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ds1822.pdf

They communicate via a '1-Wire' bus. 1-Wire is a half-duplex serial bus designed by Dallas Semiconductor. You can connect as many sensors as you like (in theory ;-), because each sensor has a unique 64-bit (!) factory-programmed 'ROM code', which is the sensor's serial number. The first byte of the 8-byte ROM Code is the device type.

0x10 = DS18S20

// fixed at 9-bit, 0.5°C accuracy

0x28 = DS18B20

// configurable 9/10/11/12 bit, 0.5°C accuracy

0x22 = DS1822

// configurable 9/10/11/12 bit, economy version, 2°C accuracy

OneWire needs a single open-drain pin for communications, with a 4.7K pull-up to the controller's Vcc voltage (3.3 or 5V).

The Arduino 'OneWire' library is used for communications
https://github.com/PaulStoffregen/OneWire

 

  DS18xxxTempSensor.h   [Click to expand]

NOTE: "Parasitic power mode" (allowing power and communications to use the same single wire) is not supported.

 

LM75x, Digital Temperature Sensor and Thermal Watchdog

lm75-temp-sensor

This is a very cheap 8-pin chip with I2C communications. It's only available in a small SMD SOIC or tiny TSSOP package, so it's usually best to buy it as a module, with the pull-up and bypass capacitors installed. It works with both 3.3V and 5V controllers and has a -55..+125°C temperature range. Up to 8 sensors can be connected on the same I2C bus.

The board has a decoupling capacitor and pull-ups on the I2C bus. If connecting several boards, you may need to remove some of the I2C pull-ups.

The chip has several [legitimate] manufacturers, for example
https://www.nxp.com/docs/en/data-sheet/LM75B.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/LM75.pdf
https://www.ti.com/lit/ds/symlink/lm75a.pdf
https://www.ti.com/lit/ds/symlink/lm75b.pdf

The LM75 and LM75A have 9-bit resolution. The LM75B has 11-bit resolution (specified as 0.125°C per step).

These also incorporate a useful Overtemperature Shutdown feature called 'OS Mode', using an open-drain 'OS' output. This allows it to work like a thermostat with hysteresis. The behaviour of the OS output is fully configurable.

There are many (rather better) pin-compatible chips available, such as the Maxim MAX7500, MAX6625, MAX6626, the DS75LV and DS7505, or the MicroChip MCP9808 (see below). But take care, these probably have different I2C commands and use different registers - I'll add details if I get to use them.

I2C Addresses
0x48..0x2F according to the A2 A1 A0 jumpers, the default is usually 0x48.

Bit

6543210

 

1001xxx

 

Here's the source code, using Arduino's standard 'Wire' library

  LM75TempSensor.h   [Click to expand]

 

MCP9808 - ±0.5°C Maximum Accuracy Digital Sensor

 

mcp9808-board

This chip is from Microchip. It has the usual I2C interface, user-selectable resolution, a fully programmable open-drain high/low/critical alarm output with readable alarm status, and works with 3.3 and 5V devices.

It is similar to the LM75 described above, but it's even smaller, a bit more sophisticated, and the register usage is sightly different.

The tiny chip costs about CHF1.30 (or CHF0.94 if you buy 2'500 of them :-), the boards are around CHF5.-

The board has a decoupling capacitor, pull-ups on the I2C bus and pull-downs on the A2/A1/A0 pins. If connecting several boards, you may need to remove some of the I2C pull-ups.

Data sheet
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/MCP9808-0.5C-Maximum-Accuracy-Digital-Temperature-Sensor-Data-Sheet-DS20005095B.pdf

This is the Adafruit board that I tested (no way am I trying to solder a weeny TSSOP chip)
https://www.adafruit.com/product/1782

I2C Addresses
0x18..0x1F according to A2 A1 A0 pins, the default is usually 0x18.

Bit

6543210

 

0011xxx

These boards have pins instead of jumpers for setting the lower 3 bits of the address.

 

Here's the source code, using Arduino's standard 'Wire' library

  MCP9808TempSensor.h   [Click to expand]

 

D6T1A01 Omron MEMS Thermal Imaging Sensor

d6t1a01

With these sensors, you don't need to have the sensor in direct contact with the item being measured. A MEMS (micro-electromechanical system) Thermal Sensor (an infrared sensor) measures the surface temperature of objects without touching them, a thermopile element absorbs radiant energy from the object and converts it to a digital value. In effect, these sensors can "see" the temperature on a small thermal matrix. The cheapest (the D6T1A01) has just one "pixel". The more expensive models have a matrix of up to 1024 pixels (32x32), so you can determine the approximate shape and motion of warm objects. (The MLX90640 is all the rage, but it costs CHF80!)

The values returned for each pixel are multiplied by 10, e.g. 252 = 25.2°C.

The temperature range for the [prohibitively] expensive models is -40..+200°C, with a 0.1°C resolution.

The cheap D6T1A01 model has a smaller range (5..50°C), but I tested it with the freezer and a cigarette lighter and it returned temperatures in the range -14..+125°C, with temperature readings updated every 100ms. I assume that the temperature it "sees" reduces with distance and the size of the temperature source, so 125°C could easily be greater than 200°C - but this must be tested.

These are (currently) 5V devices, so you must use use pull-ups to 3.3V (NOT TO 5V) on the open-drain SCL and SDA lines when using them with a 3.3V controller.

The D6T's I2C slave addresses CANNOT be changed, they are all fixed at 0x0A. For more than one sensor you can use the Software I2C library so any pins can be used for SDA/SCL. Or use an I2C multiplexer or bus switch. Or make a simple mux for the SDA signal with MOSFETs or a cheap CD4066 or 74HC4066 quad bilateral switch (the SCL clock signal can be shared). I'll add details of these circuits later.

 

D6T User Manual and programming guide
https://omronfs.omron.com/en_US/ecb/products/pdf/en_D6T_users_manual.pdf

Omron D6T MEMS Thermal Sensors Catalog
https://omronfs.omron.com/en_US/ecb/products/pdf/en_D6T_catalog.pdf

 

This code only supports the D6T1A01 with one "pixel", but it's easy to update for larger matrices.

  D6T1A01ThermalSensor.h   [Click to expand]

 

References

(If a link is broken, Google the title or the App Note number.)

Texas Instruments Application Note, A Basic Guide to RTD Measurements
https://www.ti.com/lit/an/sbaa275a/sbaa275a.pdf

Texas Instruments Application Note, RTD Alternative Measurement Methods in Real-Time Control Systems
https://www.ti.com/lit/an/snoaa67a/snoaa67a.pdf

Microchip Application Note AN687, Precision Temperature Sensing With RTD Circuits
https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ApplicationNotes/ApplicationNotes/00687c.pdf

Microchip Application Note AN1154, Precision RTD Instrumentation for Temperature Sensing
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/00001154B.pdf

ST Application Note AN5449, Temperature sensors: guidelines for system integration
https://www.st.com/resource/en/application_note/an5449-temperature-sensors-guidelines-for-system-integration-stmicroelectronics.pdf

UM10204 I2C-bus specification and user manual
https://www.nxp.com/docs/en/user-guide/UM10204.pdf