Introduction: Testing Temperature Sensors - Which One for Me?

About: Retired teacher of computing - started 1967 with FORTRAN IV. I now play with development boards such as Raspberry Pi, Pico, Arduino, micro:bit and Adafruit CircuitPython boards like the Insybitsy M4 and Circui…

One of the first sensors that newcomers to physical computing want to try out is something to measure temperature. Four of the most popular sensors are the TMP36, which has analogue output and needs an analogue to digital converter, the DS18B20, which uses one-wire connectivity, the DHT22, or the slightly cheaper DHT11, which just needs a digital pin, but also provides an humidity reading, and lastly the BME680 which uses I2C (with SPI as well on some breakout boards) and gives temperature, humidity, gas (VOC) and atmospheric pressure but costs a bit more.

I want to see how accurate they are, and discover any advantages or disadvantages. I already own an accurate mercury thermometer, left over from the colour photographic printing back in the days of chemical processing, to compare them against. (Never throw anything out - you will need it later!)

I'm going to use CircuitPython and an Adafruit Itsybitsy M4 development board for these tests. Suitable drivers are available for all the devices.


My initial list:

  • Itsybitsy M4 Express microcontroller
  • micro USB cable - for programming
  • TMP36
  • DS18B20
  • 4.7K Ohm resistor
  • DHT22
  • BME680
  • Multi-meter
  • Breadboard or strip board
  • Connecting wire

Step 1: Circuits

The orange wires are 3.3 V

The black wires are GND

At the bottom of the board are test points for measuring voltages. (3.3v, GND and TMP36 analogue output)

The centre sockets are, left to right:

  • TMP36: 3.3v, analogue signal out, GND
  • DS18B20: GND, digital signal out, 3.3v
  • DHT22: 3.3v, signal out, empty, GND
  • BME680: 3.3v, SDA, SCL, empty, GND

The rear connector, for connection to the IB M4E board, left to right

  • 3.3v
  • TMP36 - analogue out to pin A2
  • GND
  • DS18B20 digital out to pin D3 - green
  • DHT22 digital out to pin D2 - yellow
  • SDA - white
  • SCL - pink

The 4.7K Ohm resistor is a pullup from signal to 3.3v for 0ne-wire connection on the DS18B20.

There are 2 cut tracks on the back of the board:

  • Below the left hand end of both the pink and white wires. (Under the yellow wire.)

Step 2: Method

For each sensor I will write a short script to read temperature (and other items if available) several times and check the temperature against my mercury(Hg) thermometer. I will be looking to see how closely the temperature compares to the mercury reading and if the readings are steady/consistent.

I will also look at the documentation to see if the readings fit within the expected accuracy and if there is anything that can be done to make improvements.

Step 3: TMP36 - Initial Trial

The left leg is 3.3v, the right leg is GND and the centre leg is an analogue voltage representing the temperature using the following formula. TempC = (millivolts - 500) / 10

So, 750 millivolts gives a temperature of 25 C

There appears to be a couple of problems here. The temperature from the 'normal', mercury thermometer, is much lower than from the TMP36 and the readings are not very consistent - there is some 'jitter' or noise.

The TMP36 sensor sends outs a voltage proportional to the temperature. This has to be read by the A/D converter before the temperature is calculated. Let's read the voltage directly from the sensor middle leg with a multi-meter and compare it to the result from the A/D. The reading from the centre leg with my multi-meter is 722 millivolts, much lower and a very steady reading.

There are two things we can try. Substitute a potentiometer for the TMP36 and adjust the voltage in the calculation to the microcontroller's actual voltage. We will then see if the calculated voltage is closer and if the noise/jitter is reduced.

Let's measure the actual voltage being used my the microcontroller and the A/D. This was assumed to 3.3v but is actually only 3.275v.

Step 4: Potentiometer Substitution Results

This is much better. The readings are within a couple of millivolts with much less noise. This suggests that the noise is from the TMP36 rather than the A/D. The reading on the meter is always steady - no jitter. (The meter may be 'smoothing' the jittery output.)

One way of improving the situation may be to take an average reading. Take ten readings quickly and use the average. I will also calculate the standard deviation while I am changing the program, to give an indication of spread of the results. I will also count the number of readings within 1 standard deviation of the mean - the higher the better.

Step 5: Average Readings and a Result

There is still a great deal of noise and the reading from the TMP36 is still higher than from the mercury thermometer. To reduce noise I've included a 100NF capacitor between signal and GND

I then searched for other solutions on the internet and found these: Dr Monk suggests including a 47 k Ohm resistor between signal and GND. While this guy suggests sorting 15 readings into order and averaging the centre 5.

I modified the script and the circuit to include these suggestions and included a reading from the mercury thermometer.

At last! Now we have steady readings within the accuracy range of the device description.

This was quite a lot of effort to get sensor working which only has an manufacturer's accuracy of:

Accuracy - Highest (Lowest) : ±3°C (±4°C) They only cost about $1.50 (£2)

Step 6: DS18B20 - Initial Testing

Be very careful. This package looks very similar to the TMP36 but the legs are the other way round with 3.3v on the right and GND on the left. The signal out is in the centre. In order to get this device to work we need a 4.7 k Ohm resistor between signal and 3.3v. This device uses the one-wire protocol and we need to download a couple of drivers into the lib folder of the Itsybitsy M4 Express.

This costs about $4 / £4
Technical specs:

  • Usable temperature range: -55 to 125°C (-67°F to +257°F)
  • 9 to 12 bit selectable resolution
  • Uses 1-Wire interface - requires only one digital pin for communication
  • Unique 64 bit ID burned into chip
  • Multiple sensors can share one pin
  • ±0.5°C Accuracy from -10°C to +85°C
  • Temperature-limit alarm system
  • Query time is less than 750ms
  • Usable with 3.0V to 5.5V power

The main problem with this sensor is that it uses the Dallas 1-Wire interface and not all microcontrollers have a suitable driver. We are in luck, there is a driver for the Itsybitsy M4 Express.

Step 7: DS18B20 Working Well

This shows a great result.

A steady set of readings without any extra work and calculation overheads. The readings are within the expected accuracy range of ±0.5°C when compared with my mercury thermometer.

There is also a waterproof version at about $10 which I have used in the past with equal success.

Step 8: DHT22 and DHT11

The DHT22 uses a thermistor to obtain the temperature and costs about $10 / £10 and is the more accurate and expensive brother of the smaller DHT11. It also uses a one-wire interface but is NOT compatible with the Dallas protocol used with the DS18B20. It senses humidity as well as temperature. These devices sometimes need a pull up resistor between 3.3 v and the signal pin. This package has one already installed.

  • Low cost
  • 3 to 5V power and I/O
  • 2.5mA max current use during conversion (while requesting data)
  • Good for 0-100% humidity readings with 2-5% accuracy
  • Good for -40 to 80°C temperature readings ±0.5°C accuracy
  • No more than 0.5 Hz sampling rate (once every 2 seconds)
  • Body size 27mm x 59mm x 13.5mm (1.05" x 2.32" x 0.53")
  • 4 pins, 0.1" spacing
  • Weight (just the DHT22): 2.4g

Compared to the DHT11, this sensor is more precise, more accurate and works in a bigger range of temperature/humidity, but it is larger and more expensive.

Step 9: DHT22 Results

These are excellent results with very little effort. The readings are pretty steady and within the expected tolerance. The humidity reading is a bonus.

You can only take readings every second.


Step 10: DTH11 Test

My mercury thermometer showed 21.9 degrees C. This is a pretty old DHT11 I retrieved from an old project and the humidity value is very different from the DHT22 readings from a few minutes ago. It costs about $5 / £5.

Its description includes:

  • Good for 20-80% humidity readings with 5% accuracy
  • Good for 0-50°C temperature readings ±2°C accuracy - less than the DTH22

The temperature appears to still be in the accuracy range but I do not trust the humidity reading from this old device.

Step 11: BME680

This sensor contains temperature, humidity, barometric pressure, and VOC gas sensing capabilities in a single package but is the most expensive of the sensors on test here. It costs about £18.50 / $22. There is a similar product without the gas sensor which is a little bit cheaper.

This is a gold standard sensor of the five. The temperature sensor is accurate, and with suitable drivers, very easy to use. This version uses I2C but the Adafruit breakout board can also use SPI.

Like the BME280 & BMP280, this precision sensor from Bosch can measure humidity with ±3% accuracy, barometric pressure with ±1 hPa absolute accuracy, and temperature with ±1.0°C accuracy. Because pressure changes with altitude, and the pressure measurements are so good, you can also use it as an altimeter with ±1 meter or better accuracy!

The documentation says it needs some 'burn-in time' for the gas sensor.

Step 12: Which One Should I Use?

  • The TMP36 is very cheap, small and popular but quite difficult to use and may be inaccurate.
  • The DS18B20 is small, accurate, cheap, very easy to use and has a waterproof version.
  • The DTH22 also indicates humidity, is moderately priced and is easy to use but may be too slow.
  • The BME680 does a great deal more than the others but is expensive.

If I just want temperature I would use the DS18B20 with ±0.5°C accuracy but my favourite is the BME680 because it does so much more and can be put to use in a large number of different projects.

One final thought. Make sure you keep your temperature sensor well away from the microprocessor. Some Raspberry Pi HATs allow heat from the main board to warm up the sensor, giving a false reading.

Step 13: Further Thoughts and Experimentation

Thank you gulliverrr, ChristianC231 and pgagen for your comments on what I have done so far. I'm sorry for the delay but I've been on holiday in Ireland, without access to my electronics kit for a couple of weeks.

Here is a first attempt to show the sensors working together.

I wrote a script to read the sensors in turn and print out the temperature values every 20 seconds or so.

I put the kit into a fridge for an hour, to cool everything down. I plugged it into the PC and got Mu to print the results. The output was then copied, turned into a .csv file (comma separated variables) and graphs draw from the results in Excel.

It took about three minutes from taking the kit out of the fridge before results were recorded, so some rise in temperature had taken place in this interval. I suspect that the four sensors have different thermal capacities and so would warm up at different rates. The rate of warming would be expected to decrease as the sensors approached room temperature. I recorded this as 24.4°C with my mercury thermometer.

The wide differences in temperature at the start of the curves could be down to the different thermal capacities of the sensors. I'm pleased to see that the lines converge towards the end as they approach room temperature. I'm concerned that the TMP36 is always much higher than the other sensors.

I looked up the data sheets to check again the described accuracy of these devices


  • ±2°C accuracy over temperature (typ)
  • ±0.5°C linearity (typ)


  • ±0.5°C Accuracy from -10°C to +85°C


  • temperature ±0.5°C


  • temperature with ±1.0°C accuracy

Step 14: Full Graph

You can now see that the sensors did eventually level off and agree on the temperature more or less within their described accuracy. If 1.7 degrees is taken off the TMP36 values (±2°C is expected) there is good agreement between all the sensors.

The first time I ran this experiment the DHT22 sensor caused a problem: output:

14.9 , 13.5 , 10.3 , 13.7

15.7 , 14.6 , 10.5 , 14.0

16.6 , 15.6 , 12.0 , 14.4

18.2 , 16.7 , 13.0 , 15.0

18.8 , 17.6 , 14.0 , 15.6

19.8 , 18.4 , 14.8 , 16.2

21.1 , 18.7 , 15.5 , 16.9

21.7 , 19.6 , 16.0 , 17.5

22.4 , 20.2 , 16.5 , 18.1

23.0 , 20.7 , 17.1 , 18.7

DHT read error: ('DHT sensor not found, check wiring',)

Traceback (most recent call last):

File "", line 64, in

File "", line 59, in get_dht22

NameError: local variable referenced before assignment

So I modified the script to cope with this problem and restarted the recording:

DHT read error: ('DHT sensor not found, check wiring',)

25.9 , 22.6 , -999.0 , 22.6

DHT read error: ('DHT sensor not found, check wiring',)

25.9 , 22.8 , -999.0 , 22.7

25.9 , 22.9 , 22.1 , 22.8

25.9 , 22.9 , 22.2 , 22.9

DHT read error: ('DHT sensor not found, check wiring',)

27.1 , 23.0 , -999.0 , 23.0

DHT read error: ('DHT sensor not found, check wiring',)

27.2 , 23.0 , -999.0 , 23.1

25.9 , 23.3 , 22.6 , 23.2

DHT read error: ('DHT sensor not found, check wiring',)

28.4 , 23.2 , -999.0 , 23.3

DHT read error: ('DHT sensor not found, check wiring',)

26.8 , 23.1 , -999.0 , 23.3

26.5 , 23.2 , 23.0 , 23.4

26.4 , 23.3 , 23.0 , 23.5

26.4 , 23.4 , 23.1 , 23.5

26.2 , 23.3 , 23.1 , 23.6

I had no problem with the second run. The Adafruit documentation does warn that sometimes the DHT sensors do miss readings.

Step 15: Conclusions

This curve clearly shows that the higher thermal capacity of some sensors increases their reaction time.

All the sensors record temperatures rising and falling.

They are not very quick to settle to a new temperature.

They are not very accurate. (Are they good enough for a weather station?)

You may need to calibrate your sensor against a trusted thermometer.

Sensors Contest

Participated in the
Sensors Contest