Learn how to interface the DHT11 and DHT22 digital temperature sensors with the Raspberry Pi to get temperature and humidity readings. You’ll learn how to connect the sensors to the Raspberry Pi, include the required libraries, and write a Python script that displays the current temperature and humidity on the shell/terminal.
Table of Contents
Throughout this tutorial, we’ll cover the following main topics:
- Prerequisites
- Introducing the DHT11 and DHT22 Sensors
- Wiring the DHT Sensor to the Raspberry Pi
- Raspberry Pi Getting Temperature and Humidity from DHT Sensor (Python Script)
Prerequisites
Before continuing with this tutorial, check the following prerequisites.
- Get familiar with the Raspberry Pi board—if you’re not familiar with the Raspberry Pi, you can read our Raspberry Pi Getting Started Guide here.
- You must know how to run and create Python files on your Raspberry Pi. We like to program our Raspberry Pi via SSH using an extension on VS Code. We have a detailed tutorial about that subject: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).
- Know how to use the Raspberry Pi GPIOs so that you know how to wire the circuit properly. Read the following tutorial: Raspberry Pi Pinout Guide: How to use the Raspberry Pi GPIOs?
Introducing DHT11/DHT22 Sensors
The DHT11 and DHT22 sensors are used to measure temperature and relative humidity. These are very popular among makers and electronics hobbyists.
These sensors contain a chip that does analog to digital conversion and spit out a digital signal with the temperature and humidity. This makes them very easy to use with any microcontroller.
DHT11 vs DHT22
The DHT11 and DHT22 are very similar but differ in their specifications. The following table compares some of the most important specifications of the DHT11 and DHT22 temperature and humidity sensors. For a more in-depth analysis of these sensors, please check the sensors’ datasheet.
Temperature range | 0 to 50 ºC +/-2 ºC | -40 to 80 ºC +/-0.5ºC |
Humidity range | 20 to 90% +/-5% | 0 to 100% +/-2% |
Resolution | Humidity: 1% Temperature: 1ºC | Humidity: 0.1% Temperature: 0.1ºC |
Operating voltage | 3 – 5.5 V DC | 3 – 6 V DC |
Current supply | 0.5 – 2.5 mA | 1 – 1.5 mA |
Sampling period | 1 second | 2 seconds |
Price | $1 to $5 | $4 to $10 |
Where to buy | Check prices | Check prices |
The DHT22 sensor has a better resolution and a wider temperature and humidity measurement range. However, it is a bit more expensive, and you can only request readings with 2 seconds interval.
The DHT11 has a smaller range and it’s less accurate. However, you can request sensor readings every second. It’s also a bit cheaper.
Despite their differences, they work in a similar way, and you can use the same code to read temperature and humidity. You just need to select in the code the sensor type you’re using.
DHT Pinout
DHT sensors have four pins as shown in the following figure. However, if you get your DHT sensor in a breakout board, it comes with only three pins and with an internal pull-up resistor on pin 2.
The following table shows the DHT22 and DHT11 pinout. When the sensor is facing you, pin numbering starts at 1 from left to right
DHT pin | Connect to |
1 | 3.3V |
2 | Any digital GPIO; also connect a 4.7k Ohm pull-up resistor |
3 | Don’t connect |
4 | GND |
DHT Sensor Breakout Board
If you got a DHT11 or DHT22 sensor on a breakout board, they only come with three pins and have an internal pull-up resistor on the data pin.
In this case, wiring is even simpler and you don’t need to wire an external resistor. The DHT breakout boards usually have labels on the pins: GND, VCC, and DATA.
DHT pin | Connect to |
GND | GND |
VCC | 3V3 (OUT) |
DAT | GPIO 4 (or any other digital pin) |
Parts Required
Here’s a list of parts you need to build the circuit (if you don’t have a DHT breakout board, you need a 4.7kOhm resistor):
- Raspberry Pi board – read Best Raspberry Pi Starter Kits
- DHT11 or DHT22 temperature and humidity sensor
- 4.7k Ohm resistor or similar value (not needed if you have a DHT breakout board)
- Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Wiring the DHT11/DHT22 Sensor to the Raspberry Pi
Wire the DHT22 or DHT11 sensor to the Raspberry Pi as shown in the following schematic diagram. If you have a DHT breakout board, ignore the resistor.
In this example, we’re connecting the DHT data pin to GPIO 4. However, you can use any other suitable digital GPIO. Learn more about the Raspberry Pi GPIOs here.
Getting DHT11/22 Temperature and Humidity
There are different ways to get temperature and humidity readings from the DHT11 or DHT22 sensors using the Raspberry Pi with Python. We’ll use the Adafruit_CircuitPython_DHT Python library.
Update your Raspberry Pi
First, update and upgrade your Raspberry Pi, if any updates are available. Run the following command:
sudo apt update && sudo apt upgrade
If there’s a need to update, it will ask you if you want to continue. Click Y and Enter to proceed. You may need to wait a few minutes if it needs to update.
Create a Virtual Environment
We’ll install the DHT library in a virtual environment. Creating a virtual environment will isolate the Python libraries we’re using, in this case, the DHT library, from the rest of the system.
We’ll create our virtual environment on a directory on our Desktop. Enter the following command on a Terminal window to move to the Desktop:
cd ~/Desktop
Create a folder for your project. This is where we’ll create the virtual environment and install the library. We’ll create a folder called dht_test.
mkdir dht_test
Move to the newly created folder:
cd ~/Desktop/dht_test
Create a virtual environment for this directory called myenv. This must be the same directory where we’ll install the DHT library. Replace myenv with the desired name for your virtual environment.
python3 -m venv myenv
Then, you can run the following command to check that the virtual environment is there.
ls -l
Activate the virtual environment:
source myenv/bin/activate
Your prompt should change to indicate that you are now in the virtual environment.
Installing the Adafruit_CircuitPython_DHT Library
Now that we are in our virtual environment, we can install the library. Run the following command:
python3 -m pip install adafruit-circuitpython-dht
After a few seconds, the library will be installed (ignore any yellow warnings about deprecated packages).
Python Code for Raspberry Pi DHT11/DHT22
The following script gets temperature and humidity from the DHT sensors and prints the readings on the Python shell. Create a new Python file with a name of your choice, for example, dht_basic.py, and copy the following code.
# Complete Project Details: https://RandomNerdTutorials.com/raspberry-pi-dht11-dht22-python/
# Based on Adafruit_CircuitPython_DHT Library Example
import time
import board
import adafruit_dht
# Sensor data pin is connected to GPIO 4
sensor = adafruit_dht.DHT22(board.D4)
# Uncomment for DHT11
#sensor = adafruit_dht.DHT11(board.D4)
while True:
try:
# Print the values to the serial port
temperature_c = sensor.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = sensor.humidity
print("Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%".format(temperature_c, temperature_f, humidity))
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
sensor.exit()
raise error
time.sleep(3.0)
To create and run Python scripts on the Raspberry Pi, we like to use VS Code with an SSH extension: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).
How the Code Works
Continue reading to learn how the code works, or skip to the Demonstration section.
Importing libraries
Start by importing the required libraries: the time module to add delays to our code, the board module to interact with the Raspberry Pi GPIOs and the adafruit_dht to read from the DHT sensor.
import time
import board
import adafruit_dht
DHT Sensor
On the following line, we initialize our DHT sensor. We are using a DHT22 connected to GPIO 4 (you can use any other suitable GPIO as long as you change the code on the following line):
sensor = adafruit_dht.DHT22(board.D4)
If you’re using a DHT11, it should be like this:
sensor = adafruit_dht.DHT11(board.D4)
From now on, we’ll refer to our DHT sensor as sensor in our code.
While loop
Then, we have a loop that keeps the program running indefinitely, until you stop the program. Inside the loop we’ll try to read the sensor and display the readings.
while True:
try:
Reading Temperature and Humidity
Getting temperature in Celsius degrees and humidity is as easy as using the temperature and humidity properties of the sensor object. So, you can get temperature like this:
temperature_c = sensor.temperature
By default, it will get the temperature in Celsius degrees. We add a line to convert it to Fahrenheit degrees.
temperature_f = temperature_c * (9 / 5) + 32
We save the humidity value on the humidity variable:
humidity = sensor.humidity
After getting sensor readings, we’ll display them on the shell using the print() function.
print("Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%".format(temperature_c, temperature_f, humidity))
Formatting the printing output
Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%: This is the format string that defines how the output will be displayed. The format string contains placeholders indicated by curly braces {} that will be filled in with actual values using the .format() method.
Temp={0:0.1f}ºC indicates the placeholder for the first value (temperature). It specifies how the value will be formatted:
- {0}: This specifies the index of the value to be inserted (0 refers to the first value provided to the .format() method).
- :0.1f: This is a formatting specification that specifies how the value should be displayed. The 0 represents the minimum number of digits, and the .1f means that it will display the value as a floating-point number with one digit after the decimal point.
Temp={1:0.1f}ºF: This part of the format string follows the same structure as above but refers to the second value (temperature_f).
Humidity={2:0.1f}%: This part of the format string refers to the third value (humidity).
Finally, .format(temperature_c, temperature_f, humidity) inserts the actual values into the placeholders within the format string. The values provided in the parentheses are inserted into the placeholders according to their respective indexes (0, 1, 2).
If we can’t get valid temperature and humidity readings, we handle the exceptions on the except blocks:
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
sensor.exit()
raise error
We get new temperature readings every three seconds. You can adjust the delay time by changing the argument of the sleep() method.
time.sleep(3)
Demonstration
Save your Python file on the same folder of your virtual environment (in our case Desktop/dht_test). Then run it on your Raspberry Pi. Run the following command (make sure you are on the correct path—the same folder of the virtual environment):
python dht-basic.py
The virtual environment must be active to run the script. If the virtual environment is not active, you can rerun the following command to activate myenv.
source myenv/bin/activate
You should get new temperature and humidity readings on the Python Shell or on the Raspberry Pi Terminal every three seconds.
You can stop the execution of the program by pressing CTRL+C.
You may also like reading: Raspberry Pi: BME280 Temperature, Humidity and Pressure Sensor (Python).
Wrapping Up
In this tutorial, you learned how to interface the DHT11 and DHT22 digital temperature and humidity sensors with the Raspberry Pi and how to write a Python program to get and display readings. This is one of the most basic projects to get you started with the DHT11 or DHT22 sensor.
We hope you found this tutorial useful. If you’re a beginner to the Raspberry Pi, you can get started with the following tutorials:
- Getting Started with Raspberry Pi
- Raspberry Pi Pinout Guide
- Programming Raspberry Pi Remotely using VS Code (Remote-SSH)
You can check all our Raspberry Pi projects on the following link:
Finally, if you would like to interface the DHT11/22 sensor with other microcontrollers, we have tutorials for ESP32, ESP8266, and Arduino:
- ESP32: Getting Started with the DHT11/DHT22 Sensor
- ESP8266: Getting Started with the DHT11/DHT22 Sensor
- Arduino: Getting Started with the DHT11/DHT22 Sensor
- ESP32/ESP8266 (MicroPython): Getting Started with the DHT11/DHT22 Sensor
- Raspberry Pi Pico: DHT11/DHT22 Temperature and Humidity Sensor (MicroPython)
Thanks for reading.
Thanks for the update, but I was hoping to see a course for the Pi Pico and micropython.
Hi.
Probabçy at the beginning of next year.
Thanks for your interest.
Regards,
Sara
Hi Sara, can you develop tutorials on how to interface a force Sensor FSR402 or better sensor on esp32 or esp8266. For the measurement of power on a bike crank. Mahen.
Hi.Unfortunately, we don’t have any tutorials about that subject.
Regards,
Sara
Hi Sara,
I am getting error external-managed-environment when executing
sudo pip3 install Adafruit_DHT
It seems the latest versions of Python do not allow global package installations using pip
Any idea
Best regards
Roger
Hi.
Thanks for letting me know.
I’ll update the tutorial.
Regards,
Sara
The tutorial was updated with new instructions.
The library we were using was deprecated. We now use another library and install it in a virtual environment.
Regards,
Sara
Thanks Sara,
That update did solve the issue.
Best regards,
Roger
Great.
Thanks for letting me know.
Regards,
Sara
Hi Sara,
Thanks for the tutorial.
I am having issues running this script with a DHT11 connected to my Raspberry pi 5.
When I run the script I get the following output:
“Unable to set line 4 to input”
I then have to Ctrl+C to end the program.
I’ve double checked the wiring, all looks good.
Any ideas please?
Thanks
Hi.
How are you running the code?
Are you running on your virtual environment? Did you install the library we recommend?
Regards,
Sara
Hi,
Code is being run via virtual environment, the Adafruit_CircuitPython_DHT Library is installed.
Full error (post Ctrl+C):
(iot_env) pi@raspberrypi:~/iot_env $ /home/pi/iot_env/bin/python /home/pi/iot_env/DHT11.py
Unable to set line 4 to input
^CTraceback (most recent call last):
File “/home/pi/iot_env/DHT11.py”, line 16, in
temperature_c = sensor.temperature
^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 273, in temperature
self.measure()
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 218, in measure
pulses = self._get_pulses_pulseio()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 147, in _get_pulses_pulseio
while self.pulse_in:
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py”, line 174, in len
message = self._wait_receive_msg()
^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py”, line 110, in _wait_receive_msg
message = self._mq.receive(block=True, type=type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sysv_ipc.Error: Signaled while waiting
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/home/pi/iot_env/DHT11.py”, line 27, in
sensor.exit()
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 89, in exit
def exit(self) -> None:
KeyboardInterrupt
Not sure if the output is relevant/helpful.
Thanks
Matt
This did help in my case:
sensor = adafruit_dht.DHT22(board.D4, use_pulseio=False)
BTW. I moved away from the DHT sensors due to the instability when reading.
Best regards,
Roger
Thanks – I did see that suggestion yesterday whilst researching the issue.
Unfortunately, didn’t work for me:
Traceback (most recent call last):
File “/home/pi/iot_env/DHT11.py”, line 28, in
raise error
File “/home/pi/iot_env/DHT11.py”, line 16, in
temperature_c = sensor.temperature
^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 273, in temperature
self.measure()
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 220, in measure
pulses = self._get_pulses_bitbang()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_dht.py”, line 162, in _get_pulses_bitbang
with DigitalInOut(self._pin) as dhtpin:
^^^^^^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/digitalio.py”, line 185, in init
self.direction = Direction.INPUT
^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/digitalio.py”, line 215, in direction
self._pin.init(mode=Pin.IN)
File “/home/pi/iot_env/lib/python3.11/site-packages/adafruit_blinka/microcontroller/generic_linux/libgpiod/libgpiod_pin_2_x.py”, line 51, in init
self._line_request = self._chip.request_lines(
^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/pi/iot_env/lib/python3.11/site-packages/gpiod/chip.py”, line 315, in request_lines
req_internal = self._chip.request_lines(line_cfg, consumer, event_buffer_size)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 16] Device or resource busy
Thanks – I did see that suggestion yesterday whilst researching the issue.
Unfortunately, didn’t work for me:
OSError: [Errno 16] Device or resource busy
Hi Sara, the sketch doesn’t work on my Pi 3b+, latest 64-bit OS. Here the error log:
myenv) kdbeer@raspberrypi:~/mu_code/DHT11 $ python DHT11_basic.py
/home/kdbeer/mu_code/DHT11/myenv/lib/python3.9/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/libgpiod_pulsein64: error while loading shared libraries: libgpiod.so.2: cannot open shared object file: No such file or directory
Traceback (most recent call last):
File “/home/kdbeer/mu_code/DHT11/DHT11_basic.py”, line 11, in
sensor = adafruit_dht.DHT11(board.D4)
File “/home/kdbeer/mu_code/DHT11/myenv/lib/python3.9/site-packages/adafruit_dht.py”, line 294, in init
super().init(True, pin, 18000, use_pulseio)
File “/home/kdbeer/mu_code/DHT11/myenv/lib/python3.9/site-packages/adafruit_dht.py”, line 86, in init
self.pulse_in = PulseIn(self._pin, maxlen=self._max_pulses, idle_state=True)
File “/home/kdbeer/mu_code/DHT11/myenv/lib/python3.9/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py”, line 89, in init
message = self._wait_receive_msg(timeout=0.25)
File “/home/kdbeer/mu_code/DHT11/myenv/lib/python3.9/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py”, line 107, in _wait_receive_msg
raise RuntimeError(
RuntimeError: Timed out waiting for PulseIn message. Make sure libgpiod is installed.
can you give me hint how to solve it ?
Thanks for helping !
Hi.
I’m not sure about that error message.
I didn’t face that issue with my setup.
Taking a look at this discussion: https://github.com/adafruit/Adafruit_CircuitPython_DHT/issues/29
It is suggested to run the following command:
sudo apt-get install libgpiod2
Let me know if this solves the issue.
Regards,
Sara
Hi Sara, thanks for your support. The re-installation of the gpio lib solved the problem. As a work around I upfront your hint modified the sketch in that way that it worked without the ‚import board‘ statement. Thanks again ! Dieter
it additionally needed:
(myenv) pi@raspberrypi:~/Desktop/dht_test $ python3 -m pip install RPi.GPIO
else showing error:
ModuleNotFoundError: No module named ‘RPi’
Hi.
Can you tell me which Raspberry Pi and which OS are you using?
We didn’t need to run that on our setup.
Regards,
Sara
Hi Sara, I use a Pi 3B+ with OS 64bit from 2023-12-05. I did a complete new installation. Kind regards Dieter
Hi Sara,
I went through all your steps but always fail at running the skript. All errors returned are about failed imports because no such modul exsist. I am a complete beginner and don´t know how to solve the problem.
I would be happy with some help
Best Regards
Faris