Project Overview & Difficulty Rating
Time Required: 20 minutes
Target Board Variant: Raspberry Pi 5 (8GB) or Raspberry Pi 4 Model B running Raspberry Pi OS (Bookworm, 64-bit).
The DHT11 is a ubiquitous, low-cost temperature and humidity sensor. However, integrating a dht11 sensor raspberry pi setup is notoriously frustrating for beginners because the DHT11 uses a custom single-bus protocol that requires microsecond-level timing. Linux is not a real-time operating system (RTOS); background tasks routinely interrupt the Raspberry Pi's GPIO reading cycles, causing read failures.
Furthermore, the legacy Adafruit_Python_DHT library is deprecated and will fail to compile on modern Raspberry Pi OS (Bookworm) kernels. This guide uses the modern, supported adafruit-circuitpython-dht library, which leverages the libgpiod2 interface for reliable hardware access on the Pi 4 and Pi 5.
Parts List
- Microcontroller: Raspberry Pi 5 (8GB) or Pi 4 Model B
- Sensor: DHT11 3-pin module (AM2305 chipset equivalent). Note: We strongly recommend the 3-pin module variant because it includes a built-in 10kΩ pull-up resistor and filter capacitor. Bare 4-pin DHT11 sensors require manual resistor soldering.
- Wiring: 3x Female-to-Female Dupont jumper wires
- Software: Raspberry Pi OS (Bookworm, 64-bit) with Python 3.11+
Hardware Wiring & Pin Mapping
The DHT11 operates safely on 3.3V logic, which aligns perfectly with the Raspberry Pi's GPIO voltage limits. Never feed 5V into the Pi's GPIO data pins, as this will permanently damage the SoC.
| Sensor Pin (Silkscreen) | Raspberry Pi GPIO Name | Physical Pin Number | Wire Color (Standard) |
|---|---|---|---|
| VCC (or +) | 3.3V Power | Pin 1 | Red |
| DATA (or OUT) | GPIO 4 | Pin 7 | Yellow / Orange |
| GND (or -) | Ground | Pin 9 | Black |
- Power Down: Shut down the Raspberry Pi completely and disconnect the USB-C power supply.
- Connect Power: Plug the red jumper wire from the sensor's VCC pin to Physical Pin 1 (3.3V) on the Pi.
- Connect Ground: Plug the black jumper wire from the sensor's GND pin to Physical Pin 9 (GND) on the Pi.
- Connect Data: Plug the yellow jumper wire from the sensor's DATA pin to Physical Pin 7 (GPIO 4) on the Pi.
- Verify: Use a multimeter in continuity mode to ensure the GND wire reads near 0 ohms against the metal shield of the Pi's USB ports (a known ground reference).
Python Code for Raspberry Pi OS (Bookworm)
Before writing the code, you must install the underlying C library that CircuitPython relies on for GPIO access. Open your terminal and run:
sudo apt update
sudo apt install libgpiod2
pip3 install adafruit-circuitpython-dht --break-system-packages
--break-system-packages flag is required on Raspberry Pi OS Bookworm due to PEP 668 restrictions. Alternatively, set up a Python virtual environment (python3 -m venv env) before installing.
Create a file named dht11_reader.py and paste the following complete, compilable code. This script includes robust error handling to manage the inherent timing jitter of Linux.
import time
import board
import adafruit_dht
# Pin definition: Maps to Physical Pin 7 (GPIO 4)
dht_device = adafruit_dht.DHT11(board.D4)
def read_sensor():
while True:
try:
# Read temperature and humidity
temperature_c = dht_device.temperature
humidity = dht_device.humidity
# Calculate Fahrenheit
temperature_f = temperature_c * (9 / 5) + 32
print(f'Temp: {temperature_f:.1f}°F ({temperature_c:.1f}°C) | Humidity: {humidity}%')
except RuntimeError as error:
# RuntimeError is thrown by the library on checksum/timeout failures.
# This is expected on Linux due to OS thread interruption.
print(f'Read failed: {error.args[0]}')
time.sleep(2.0)
continue
except Exception as error:
# Catch-all for hardware disconnects or I2C/GPIO lockups
dht_device.exit()
raise error
# DHT11 hardware requires a 1-second minimum delay between reads.
# We use 3 seconds to reduce bus contention and CPU load.
time.sleep(3)
if __name__ == '__main__':
try:
read_sensor()
except KeyboardInterrupt:
print('Script terminated by user.')
dht_device.exit()
Debugging: Fixing Read Failures and Jitter
If your script fails, do not immediately assume the sensor is dead. The single-bus protocol is highly sensitive to electrical noise and OS scheduling. Here are the first three things to check when it fails:
- Pull-up Resistor Presence: Measure the resistance between the VCC and DATA pins on your sensor module with a multimeter. It should read ~10kΩ. If it reads infinite (OL), you have a bare 4-pin sensor and must solder a 10kΩ resistor between those pins.
- Cable Length and Capacitance: The DHT11 data line is highly susceptible to parasitic capacitance. If your Dupont jumper wires exceed 1 meter (3.3 feet), the signal edges will degrade, causing checksum failures. Keep wires short.
- Logic Level Verification: Measure the voltage at the sensor's VCC pin while the Pi is on. It must read between 3.2V and 3.4V. If it reads 5V, you are plugged into the wrong physical pin and risk frying the Pi's GPIO bank.
Exact Error Strings and Ranked Causes
Error 1: RuntimeError: Timed out waiting for PulseIn.
- Cause 1 (Most Likely): Missing pull-up resistor. The data line floats and never returns to a HIGH state.
- Cause 2: Severe OS timing jitter. The Pi was busy handling a network interrupt during the microsecond pulse window.
- Cause 3: Wiring fault. The DATA wire is not making solid contact with Physical Pin 7.
Error 2: RuntimeError: Checksum error.
- Cause 1 (Most Likely): Data line noise. Long wires or routing the data wire parallel to AC mains or PWM motor lines is inducing voltage spikes that corrupt the 40-bit data packet.
- Cause 2: Power supply ripple. A cheap, unfiltered USB-C power supply is introducing noise onto the 3.3V rail.
RuntimeError exceptions and retries after a 2-second delay. In a production environment, this retry logic is mandatory for DHT sensors on Linux.
Extending and Simplifying the Build
How to Simplify the Build
If the Linux timing jitter and Checksum error faults become unbearable for your data-logging application, ditch the DHT11 entirely. Simplify your hardware by switching to an I2C-based sensor like the AHT20 or BME280. I2C uses a dedicated hardware clock line (SCL), making it completely immune to OS-level microsecond timing interruptions. The AHT20 costs roughly $2 more than a DHT11 but offers vastly superior accuracy (±2% RH vs ±5% RH) and zero Linux jitter.
How to Extend the Build
To turn this into a smart home node, extend the Python script using the paho-mqtt library. Wrap the print() statements in an MQTT publish function to send the JSON payload to a Mosquitto broker, which Home Assistant can ingest via the MQTT integration. Alternatively, add an SSD1306 I2C OLED display to the Pi's I2C bus (Pins 3 and 5) to render the temperature locally without needing a monitor.
DHT11 Sensor Raspberry Pi FAQ
Why does my DHT11 sensor Raspberry Pi setup keep throwing timeout errors?
Timeout errors (RuntimeError: Timed out waiting for PulseIn) occur because the Raspberry Pi runs a general-purpose desktop operating system, not a real-time OS. When the Pi's CPU pauses the Python script to handle a background task (like a Wi-Fi interrupt or USB polling) during the exact microsecond the DHT11 is transmitting data, the library misses the pulse and times out. Implementing the retry logic shown in our code block is the standard software fix.
Can I power the DHT11 sensor with 5V on the Raspberry Pi GPIO?
While the DHT11 sensor itself can operate on 5V, you must never connect a 5V data output directly to a Raspberry Pi GPIO pin. The Pi's GPIO pins are strictly 3.3V tolerant. If you power the sensor with 5V, its DATA pin will output 5V logic highs, which will permanently damage the Pi's SoC. Always power the DHT11 from the Pi's 3.3V pin (Physical Pin 1).
Do I need a pull-up resistor for the DHT11 data pin on a Raspberry Pi?
Yes, the single-bus protocol requires the data line to be pulled HIGH when idle. If you are using a bare, blue 4-pin DHT11 component, you must solder a 4.7kΩ to 10kΩ resistor between the VCC and DATA pins. If you are using a 3-pin DHT11 module (mounted on a small PCB), the manufacturer has already included this surface-mount resistor on the board, and no additional components are needed.
What is the difference between using a DHT11 and DHT22 sensor on a Raspberry Pi?
The wiring and Python code for the DHT11 and DHT22 (AM2302) are nearly identical on the Raspberry Pi, requiring only a single class change in the code (adafruit_dht.DHT22(board.D4)). However, the DHT22 offers a much wider temperature range (-40°C to 80°C vs 0°C to 50°C) and higher precision (0.1°C resolution vs 1°C resolution). For indoor room monitoring, the DHT11 is sufficient; for outdoor weather stations or greenhouse monitoring, the DHT22 is mandatory.
References:
Adafruit CircuitPython DHT Library Documentation
Raspberry Pi OS Official Documentation






