Picking the wrong environmental sensor costs you weeks of drift, noisy data, and rewired breadboards. The DS18B20 measures temperature only, but it does so in waterproof probes over long cables. The DHT22 is cheap and simple, but slow and loosely specified. The BME280 adds barometric pressure on I2C or SPI. The SHT4x family delivers the best humidity accuracy at very low power. This guide compares all four with real specs, pinouts, wiring, and firmware.
Quick Takeaways
- Best for temperature only, long cables, or waterproof probes: DS18B20 (±0.5°C, 1-Wire).
- Best budget humidity sensor: DHT22 (±0.5°C, ±2-5% RH, but only one reading every 2 seconds).
- Best all-in-one for weather stations: BME280 (temperature, humidity, and pressure on I2C/SPI).
- Best accuracy and lowest power: SHT4x (±0.2°C, ±1.8% RH, as low as 0.4 µA in idle-heavy duty cycles).
| Feature | DS18B20 | DHT22 | BME280 | SHT4x (SHT40/41/45) |
|---|---|---|---|---|
| Measures | Temp | Temp + RH | Temp + RH + Pressure | Temp + RH |
| Temp accuracy | ±0.5°C | ±0.5°C | ±1.0°C | ±0.2°C (SHT41/45) |
| RH accuracy | N/A | ±2-5% | ±3% | ±1.8% (SHT41), ±1.0% (SHT45) |
| Interface | 1-Wire | Proprietary single-wire | I2C/SPI | I2C |
| Supply voltage | 3.0-5.5V | 3.3-6V | 1.71-3.6V | 1.08-3.6V |
| Max sample rate | ~1 Hz (12-bit) | 0.5 Hz | Up to ~100+ Hz (forced/normal) | Up to ~100+ Hz |
| Typical cost | Low | Low | Low-Medium | Medium |
| Best use | Probes, long runs | Hobby builds | Weather stations | Precision, battery IoT |
Verify exact figures against the current manufacturer datasheet before finalizing a design. Revisions and module vendors vary.
Component Overview
DS18B20 (Maxim/Analog Devices)
The DS18B20 is a digital thermometer on the 1-Wire bus. Each chip has a unique 64-bit ROM code, so many sensors share a single GPIO pin. Resolution is configurable from 9 to 12 bits. At 12 bits, conversion takes up to 750ms, which limits update rate.
Key specs:
- Range: -55°C to +125°C
- Supply: 3.0V to 5.5V
- Parasitic power mode: possible, but unreliable on long runs
- Waterproof stainless-steel probe versions are widely available
Use it for soil, water, freezers, and pipes. It has no humidity channel.
DHT22 (AM2302)
The DHT22 combines a capacitive humidity sensor and a thermistor. It speaks a timing-based single-wire protocol, not 1-Wire. The datasheet limits sampling to one read per 2 seconds. Reading it faster returns stale data or errors.
Key specs:
- Range: -40°C to 80°C, 0-100% RH
- Supply: 3.3-6V
- Resolution: 0.1°C, 0.1% RH
- Needs a 4.7kΩ-10kΩ pull-up on the data line (often built into modules)
Humidity accuracy degrades near the extremes and after prolonged condensation. Long-term drift is the main weakness.
BME280 (Bosch Sensortec)
The BME280 is a combined digital sensor for temperature, relative humidity, and barometric pressure. It supports I2C (address 0x76 or 0x77) and SPI. Because pressure is included, you can compute altitude or track weather trends.
Key specs:
- Pressure: 300-1100 hPa, ±1 hPa absolute
- Humidity: 0-100% RH, ±3%
- Temperature: -40°C to +85°C, ±1°C
- Supply: 1.71-3.6V (most breakout boards add a regulator and level shifter)
Self-heating skews the temperature reading. In forced mode with long standby intervals, error drops. Do not mount it next to a regulator or ESP32 module.
Counterfeit modules are common. A part sold as BME280 that lacks humidity is actually a BMP280 (chip ID 0x58 vs 0x60 for BME280). Check the ID register when readings look wrong.
SHT4x Family (Sensirion)
The SHT40, SHT41, and SHT45 are the newest in the line, replacing the SHT3x series. All use I2C (default address 0x44). The suffix sets accuracy: SHT45 is the most precise. They include an on-chip heater to burn off condensation, which is useful in outdoor and high-humidity installs.
Key specs:
- Temperature: -40°C to +125°C
- Humidity: 0-100% RH
- Supply: 1.08-3.6V
- Very low average current, which suits battery-powered ESP32 and nRF52 nodes
Sensirion’s CRC-8 check on every transfer catches bus corruption that cheaper sensors silently pass through.
Pinout Configuration
| Sensor | Pin 1 | Pin 2 | Pin 3 | Pin 4 |
|---|---|---|---|---|
| DS18B20 (TO-92, flat face toward you) | GND | DQ (data) | VDD | N/A |
| DHT22 (front view, grill facing you) | VCC | DATA | NC | GND |
| BME280 breakout (I2C) | VIN | GND | SCL | SDA |
| SHT4x breakout (I2C) | VIN | GND | SCL | SDA |
Pin order on breakouts varies by vendor. Read the silkscreen before powering up. Reversing VCC and GND on a TO-92 part destroys it within seconds.
Circuit Diagram Breakdown
DS18B20 Wiring
- Connect VDD to 3.3V (or 5V).
- Connect GND to ground.
- Connect DQ to a GPIO (example: GPIO4).
- Place a 4.7kΩ pull-up resistor between DQ and VDD.
For cable runs beyond ~10 m, use shielded twisted pair, keep the 4.7kΩ pull-up near the microcontroller, and consider lowering it to 2.2kΩ for heavier bus loads.
DHT22 Wiring
- VCC to 3.3V.
- GND to ground.
- DATA to GPIO with a 10kΩ pull-up to VCC (skip on 3-pin modules with a pull-up).
- Add a 100nF decoupling capacitor close to the sensor.
BME280 and SHT4x Wiring (I2C)
- VIN to 3.3V.
- GND to ground.
- SDA and SCL to the MCU’s I2C pins (ESP32 default: GPIO21/GPIO22).
- Pull-ups of 4.7kΩ on SDA and SCL if the breakout lacks them.
Both the BME280 (0x76/0x77) and SHT4x (0x44) can share one I2C bus because their addresses differ.
Firmware and Code
DS18B20 (Arduino C++, ESP32)
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_PIN 4 // DQ line on GPIO4
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(115200);
sensors.begin(); // Enumerate devices on the bus
sensors.setResolution(12); // 12-bit = 0.0625°C steps, ~750ms conversion
}
void loop() {
sensors.requestTemperatures(); // Trigger conversion on all sensors
float tempC = sensors.getTempCByIndex(0);
if (tempC == DEVICE_DISCONNECTED_C) {
Serial.println("DS18B20 not found. Check pull-up and wiring.");
} else {
Serial.printf("Temp: %.2f C\n", tempC);
}
delay(2000);
}
A reading of 85.0°C is the power-on reset value. If you see it constantly, the conversion did not finish or power is unstable.
DHT22 (Arduino C++)
#include <DHT.h>
#define DHTPIN 5 // DATA on GPIO5
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
delay(2000); // DHT22 max rate: one read per 2 seconds
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) { // NaN means checksum or timing failure
Serial.println("DHT22 read failed");
return;
}
Serial.printf("Temp: %.1f C RH: %.1f %%\n", t, h);
}
BME280 (Arduino C++, Adafruit library)
#include <Wire.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme; // I2C interface
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA=GPIO21, SCL=GPIO22
if (!bme.begin(0x76)) { // Try 0x77 if this fails
Serial.println("BME280 not detected. Check address and wiring.");
while (1) delay(10);
}
// Forced mode, 1x oversampling: minimal self-heating
bme.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp
Adafruit_BME280::SAMPLING_X1, // Pressure
Adafruit_BME280::SAMPLING_X1, // Humidity
Adafruit_BME280::FILTER_OFF);
}
void loop() {
bme.takeForcedMeasurement(); // Wake, measure, return to sleep
Serial.printf("T: %.2f C RH: %.1f %% P: %.1f hPa\n",
bme.readTemperature(),
bme.readHumidity(),
bme.readPressure() / 100.0F);
delay(5000);
}
SHT4x (MicroPython, ESP32)
from machine import I2C, Pin
import time
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
SHT4X_ADDR = 0x44
CMD_MEASURE_HIGH = b'\xFD' # High-precision measurement
def crc8(data):
crc = 0xFF
for byte in data:
crc ^= byte
for _ in range(8):
crc = ((crc << 1) ^ 0x31) & 0xFF if crc & 0x80 else (crc << 1) & 0xFF
return crc
def read_sht4x():
i2c.writeto(SHT4X_ADDR, CMD_MEASURE_HIGH)
time.sleep_ms(10) # Max measurement time ~8.3 ms
d = i2c.readfrom(SHT4X_ADDR, 6) # T(2) CRC(1) RH(2) CRC(1)
if crc8(d[0:2]) != d[2] or crc8(d[3:5]) != d[5]:
raise ValueError("CRC mismatch")
t_raw = (d[0] << 8) | d[1]
rh_raw = (d[3] << 8) | d[4]
temp = -45 + 175 * t_raw / 65535
rh = max(0, min(100, -6 + 125 * rh_raw / 65535))
return temp, rh
while True:
t, rh = read_sht4x()
print("Temp: {:.2f} C RH: {:.1f} %".format(t, rh))
time.sleep(5)
Head-to-Head Comparison
Accuracy and Drift
| Metric | DS18B20 | DHT22 | BME280 | SHT4x |
|---|---|---|---|---|
| Temp tolerance | ±0.5°C | ±0.5°C | ±1.0°C | ±0.2°C |
| RH tolerance | None | ±2-5% | ±3% | ±1.0-1.8% |
| Long-term RH drift | None | High | Medium | Low |
| Condensation recovery | N/A | Poor | Fair | Good (built-in heater) |
| Data integrity | CRC-8 | 8-bit checksum | None on I2C | CRC-8 per word |
Power and Integration
| Metric | DS18B20 | DHT22 | BME280 | SHT4x |
|---|---|---|---|---|
| Active current | ~1mA | ~1.5mA | ~350µA | ~320µA |
| Sleep/standby | ~750nA | ~50µA | ~0.1µA | ~80nA |
| Pins needed | 1 | 1 | 2 (I2C) | 2 (I2C) |
| Multi-sensor on one bus | Yes (unique ROM IDs) | No | 2 addresses | 1 address (variants differ) |
| Battery-friendly | Fair | Poor | Good | Excellent |
Decision Table
| Your Project | Pick |
|---|---|
| Aquarium, freezer, pipe, soil probe | DS18B20 |
| Classroom demo, quick prototype | DHT22 |
| Weather station with altitude/pressure | BME280 |
| Calibrated indoor air monitoring | SHT4x |
| Coin-cell or solar IoT node | SHT4x |
| Many temperature points on one wire | DS18B20 |
Practical Workflow: Building a Multi-Sensor IoT Weather Station
This build combines three sensors for redundancy and cross-checking.
Parts:
- ESP32 DevKit
- BME280 breakout (pressure and ambient reading)
- SHT45 breakout (reference humidity)
- DS18B20 waterproof probe (ground temperature)
- 4.7kΩ resistors (x3)
- Solar radiation shield (Stevenson-style)
Steps:
- Wire BME280 and SHT45 on the same I2C bus (GPIO21/GPIO22). Addresses 0x76 and 0x44 do not conflict.
- Wire the DS18B20 on GPIO4 with a 4.7kΩ pull-up to 3.3V.
- Mount the I2C sensors inside the radiation shield, away from the ESP32 (which heats up when Wi-Fi is active).
- Use deep sleep between readings: wake, read all three, publish via MQTT, sleep for 5-10 minutes.
- Compare BME280 and SHT45 humidity in post-processing. A sustained gap over 5% RH signals drift or contamination.
Mitigating self-heating: Place sensors at least 5 cm from the MCU. Read in forced mode. Keep Wi-Fi off during the measurement window.
Protecting Sensor Lines From Voltage Spikes
For outdoor wiring or long cables, add:
- A TVS diode (e.g., SMAJ5.0A) from the data line to GND at the board entry
- A 100Ω series resistor on data lines
- An optocoupler or I2C isolator (e.g., ADuM1250) when the sensor shares a different ground reference
Common Failure Diagnostics
| Symptom | Likely Cause | Fix |
|---|---|---|
| DS18B20 reads -127°C | Disconnected data line or missing pull-up | Check wiring, add 4.7kΩ |
| DS18B20 reads 85°C | Power-on default, conversion not finished | Wait full conversion time, stabilize VDD |
| DHT22 returns NaN | Reading faster than 2s, missing pull-up | Add delay, add 10kΩ pull-up |
| BME280 not found | Wrong address or counterfeit BMP280 | Scan I2C, check chip ID (0x60) |
| BME280 humidity reads 0% | Chip is actually a BMP280 | Replace with a genuine part |
| SHT4x CRC errors | Long I2C wires, weak pull-ups | Shorten bus, lower I2C to 100kHz |
| Humidity stuck at 100% | Condensation | Run SHT4x heater cycle, or dry the sensor |
| Temp reads high indoors | Self-heating from nearby MCU | Move sensor, use forced mode |
Which Sensor Should You Choose?
- Choose the DS18B20 when you need rugged probes, many points on one wire, or long cable runs.
- Choose the DHT22 only for low-stakes projects where cost matters more than accuracy.
- Choose the BME280 when pressure matters or when you want a well-supported all-in-one library ecosystem.
- Choose the SHT4x when humidity accuracy, low power, and long-term stability decide the project.
For most new designs in 2026, the SHT4x is the strongest humidity and temperature option, and the BME280 is still the strongest value when you also need pressure.
FAQ
Which is more accurate, DHT22 or BME280?
For temperature, both are specified near ±0.5°C to ±1°C, but the DHT22 is slightly tighter on paper. For humidity, the BME280 (±3% RH) is more consistent over time than the DHT22 (±2-5% RH with higher drift). The SHT4x beats both.
Can I use DS18B20 to measure humidity?
No. The DS18B20 measures temperature only. Pair it with a humidity sensor such as the SHT4x or BME280 if you need both.
Why does my BME280 read too high a temperature?
Self-heating and nearby heat sources are the usual causes. Use forced mode, lower the oversampling, keep the sensor away from the MCU and regulators, and apply a small software offset only after verifying against a reference thermometer.
Is the DHT22 still worth buying?
Only for low-cost learning projects. Its 2-second sample limit, humidity drift, and lack of I2C make the SHT4x or BME280 better choices for anything long-running.




