How DHT11 DHT22 Sensors Work & Interface With Arduino

Its summer, you’re sweating heavily and all you really want to know is why the weatherman predicted this morning that today’s relative temperature would max out to 20°C while it feels more like 25°C. Enter the DHT11, DHT22/AM2302 Digital Temperature & Humidity Sensor from AOSONG – the best way to prove the weatherman wrong!

These sensors are fairly simple to use, low cost and are great for hobbyists who want to sense the world around them! These sensors are pre-calibrated and don’t require extra components so you can start measuring relative humidity and temperature right away.

One of the greatest features they provide is that both temperature & humidity are measured to the nearest tenth; that is, to one decimal place. The only downside of this sensor is you can get new data from it once every second or two. But, considering its performance and price, you can’t complain.

DHT11 Vs DHT22/AM2302

We have two versions of the DHTxx sensor series. They look a bit similar and have the same pinout, but have different characteristics. Here are the details:

The DHT22 is the more expensive version which obviously has better specifications. Its temperature measuring range is from -40°C to +125°C with +-0.5 degrees accuracy, while the DHT11 temperature range is from 0°C to 50°C with +-2 degrees accuracy. Also the DHT22 sensor has better humidity measuring range, from 0 to 100% with 2-5% accuracy, while the DHT11 humidity range is from 20 to 80% with 5% accuracy.

Max Operating Current15.5mm x 12mm x 5.5mmDHT11 Temperature Humidity Sensor Fritzing part Illustration15.1mm x 25mm x 7.7mmDHT22 Temperature Humodoty Sensor Fritzing part Illustration
DHT11 and DHT22/AM2302 Specification Comparison
 DHT11DHT22
Operating Voltage3 to 5V3 to 5V
Max Operating Current2.5mA max2.5mA max
Humidity Range20-80% / 5%0-100% / 2-5%
Temperature Range0-50°C / ± 2°C-40 to 80°C / ± 0.5°C
Sampling Rate1 Hz (reading every second)0.5 Hz (reading every 2 seconds)
Body size15.5mm x 12mm x 5.5mm15.1mm x 25mm x 7.7mm
AdvantageUltra low costMore Accurate

Though DHT22/AM2302 is more precise, more accurate and works in a bigger range of temperature & humidity; there are three things where the DHT11 beats the hell out of DHT22. It’s less expensive, smaller in size and has higher sampling rate. The sampling rate of the DHT11 is 1Hz i.e. one reading every second, while the sampling rate of DHT22 is 0.5Hz i.e. one reading every two seconds.

However, the operating voltage of both sensors is from 3 to 5 volts, while the max current used during conversion (while requesting data) is 2.5mA. And the best thing is that DHT11 and DHT22/AM2302 sensors are ‘swappable’ – meaning, if you build your project with one you can just unplug it and use another. Your code may have to adjust a little but at least the wiring is the same!

For a little more insight, please refer below datasheets for DHT11 and DHT22/AM2302 sensor.

Hardware Overview

Now let’s move on to the interesting stuff. Let’s teardown both the DHT11 and DHT22/AM2302 sensors and see what’s inside.

The casing is in two parts so to get inside it is just a matter of getting a sharp knife and splitting the case apart. Inside the case, on the sensing side, there is a humidity sensing component along with a NTC temperature sensor (or thermistor)

Inside DHT11 DHT22 AM2302 Temperature Humidity Sensor

Humidity sensing component is used, of course to measure humidity, which has two electrodes with moisture holding substrate (usually a salt or conductive plastic polymer) sandwiched between them. The ions are released by the substrate as water vapor is absorbed by it, which in turn increases the conductivity between the electrodes. The change in resistance between the two electrodes is proportional to the relative humidity. Higher relative humidity decreases the resistance between the electrodes, while lower relative humidity increases the resistance between the electrodes.

Internal Structure of Humidity Sensor in DHT11 DHT22
Internal Structure of Humidity Sensor

Besides, they consist of a NTC temperature sensor/Thermistor to measure temperature. A thermistor is a thermal resistor – a resistor that changes its resistance with temperature. Technically, all resistors are thermistors – their resistance changes slightly with temperature – but the change is usually very very small and difficult to measure.

Thermistors are made so that the resistance changes drastically with temperature so that it can be 100 ohms or more of change per degree! The term “NTC” means “Negative Temperature Coefficient”, which means that the resistance decreases with increase of the temperature.

NTC Thermistor Temperature Resistance Characteristic Curve
NTC Thermistor with Characteristic Curve

On the other side, there is a small PCB with an 8-bit SOIC-14 packaged IC. This IC measures and processes the analog signal with stored calibration coefficients, does analog to digital conversion and spits out a digital signal with the temperature and humidity.

How DHT11 and DHT22/AM2302 Works?

Let’s briefly discuss how DHT11, DHT22/AM2302 sensors work before we connect it to an Arduino.

The DHT11, DHT22/AM2302 sensors use their own (non-standard but similar to Dallas) 1-wire protocol for communication. As this protocol is based on the MASTER (MCU, say Arduino) – SLAVE (Sensor) structure, the sensor will answer only when master requests for the data. Otherwise, sensor keeps quiet (remains in sleep mode). To access the sensor, master must follow the sequence of single bus, if there is a sequence of confusion, the sensor will not respond to the master.

NOTE

These sensors (Usually all 1-wire sensors) have open drain outputs so the external pull-up resistor, about 5.1kΩ – 10kΩ, is usually required. So, when the bus is idle, its status will switch to HIGH. This maintains logic “1” when the bus is not driven, just like with I2C.

Once the sensor is powered up, it takes up to 2s to become stable. In this period, the sensor tests the environment temperature and humidity, and records relative data. When finished, it enters sleep mode automatically.

The communication starts, when the master (MCU) sends out a start signal. With this, the sensor wakes up from the sleep mode, switches to the High-speed mode and sends a response signal. Following that it outputs a string of 40 bits data consisting of relative temperature and humidity values. Once finished, the sensor switches back to the sleep mode automatically, waiting for next communication. The corresponding timing diagram is shown as below.

DHT11 DHT22 Working Single Wire Protocol Waveform Timing Diagram

Start Signal:

To request a reading, microcontroller pulls the data line LOW for more than 800µs (The typical hold time is 1ms). After this fairly lengthy time, the line is pulled HIGH again but for a much shorter 20µs. This sequence acts as a start signal and awakens the sensor from its idle state.

DHT11 DHT22 Working Start Signal Waveform Timing Diagram

Response Signal:

Once the start signal ends, the sensor sends out a response signal. The sensor pulls the data line LOW for 80µs an pulls HIGH again for 80µs. In this period, the sensor re-tests the environmental temperature and humidity, records the relative data and gets ready for the data transmission.

DHT11 DHT22 Working Response Signal Waveform Timing Diagram

40 bit Data:

When response signal ends, the sensor starts outputting 40 bits serial data continuously. Before sending every bit, sensor pulls the data line LOW for around 50µs. Following that the length of the HIGH pulse decides the bit status i.e. either 0 or 1. If the line is HIGH for 26-28µs, it indicates bit ‘0’, whereas 70µs long pulse indicates bit ‘1’.

DHT11 DHT22 Working 40 bit data Signal Waveform Timing Diagram

Once all the 40 bits are transmitted, the sensor pulls the data line LOW for 50ms to indicate the end and enters the sleep mode automatically.

How To Read Temperature and Humidity From 40 bit Data

Now, comes one of the most mysterious aspects of the sensor: figuring out what the 40 bit data mean. While the relative humidity is always a non-negative number, the temperature might be negative. And don’t forget about the decimal fraction portion of the number. Let’s see if we can solve this mystery.

The 40 bit data contains 16 bits of humidity, 16 bits of temperature and last 8 bits represent parity bits (a simplest form of error detecting code) with Most Significant Bit (MSB) first. The corresponding timing diagram is shown as below.

DHT11 DHT22 40 bit Sensor data With Humidity Temperature and Parity bits

NOTE

The 16 bits of humidity & temperature is actually a 16-bit representation of 10 times the actual humidity & temperature values. The scaling factor of 10 will make more sense in a moment.

Consider we received following 40 bits of data from the sensor.

0000 0010   1001 0010   0000 0001   0000 1101   1010 0010

As we discussed above, first 16 bits represent relative humidity. Next 16 bits represent relative temperature and last 8 bits represent checksum. With this, the data can be separated as:

0000 0010 1001 00100000 0001 0000 11011010 0010
Relative HumidityRelative TemperatureChecksum

It’s always a good idea to confirm if the data received does not contain any errors before proceeding further. Let’s see how a checksum can help pinpoint erroneous results.

Here the simple rule is SUM of first four bytes (8 bits) should match last byte i.e. checksum. If this doesn’t match, you should discard the scrambled pattern.

0000 0010 + 1001 0010 + 0000 0001 + 0000 1101 = 1010 0010

This clearly indicates that the received data is valid. So, now you can proceed with calculation of relative humidity and temperature.

To get the relative humidity and temperature, you just need to convert the 16-bit binary value to decimal. That’s it.

Relative Humidity  =>  0000 0010 1001 0010 (BIN)  =>  658 (DEC)

Relative Temperature  =>  0000 0001 0000 1101 (BIN)  =>  269 (DEC)

But remember, these values are 10 times greater than the actual values. So, the final result will be.

Relative Humidity = 65.8 % RH

Relative Temperature = 26.9 °C

Voila! There’s the relative humidity and temperature, accurate to one decimal place, shining away at you.

DHT11 and DHT22/AM2302 Pinout

The DHT11, DHT22/AM2302 sensors are fairly easy to connect. They have four pins:

DHT11 DHT22 AM2302 Temperature Humidity Sensor Pinout

VCC pin supplies power for the sensor. Although supply voltage ranges from 3.3V to 5.5V, 5V supply is recommended. In case of 5V power supply, you can keep the sensor as long as 20 meters. However, with 3.3V supply voltage, cable length shall not be greater than 1 meter. Otherwise, the line voltage drop will lead to errors in measurement.

Data pin is used to communication between the sensor and the microcontroller.

NC Not connected

GND should be connected to the ground of Arduino.

Wiring – Connecting DHT11 and DHT22/AM2302 to Arduino UNO

Now that we have a complete understanding of how DHT sensors work, we can begin hooking it up to our Arduino!

Luckily, it is trivial to connect DHT11, DHT22/AM2302 sensors to Arduino. They have fairly long 0.1″-pitch pins so you can easily plug them into any breadboard. Power the sensor with 5V and connect ground to ground. Finally, connect the Data pin to a digital pin #2.

Remember, as discussed earlier in this tutorial, we need to place a pull-up resistor of 10KΩ between VCC and data line to keep it HIGH for proper communication between sensor and MCU. If you happen to have a breakout board of the sensor, you need not add any external pull-up. It comes with a built-in pull-up resistor.

Arduino Wiring Fritzing Connections with DHT11
Wiring DHT11 to Arduino UNO
Arduino Wiring Fritzing Connections with DHT22
Wiring DHT22 to Arduino UNO

With that, you’re now ready to upload some code and get it working.

Arduino Code – Printing values on Serial Monitor

As discussed earlier in this tutorial, the DHT11, DHT22/AM2302 sensors have their own single wire protocol used for transferring the data. This protocol requires precise timing. Fortunately, we don’t have to worry much about this because we are going to use the DHT library which takes care of almost everything.

Download the library first, by visiting the GitHub repo or, just click this button to download the zip:

To install it, open the Arduino IDE, go to Sketch > Include Library > Add .ZIP Library, and then select the DHTlib ZIP file that you just downloaded.  If you need more details on installing a library, visit this Installing an Arduino Library tutorial.

Once you have the library installed, you can copy this sketch into the Arduino IDE. The following test sketch will print the temperature and relative humidity values on the serial monitor. Try the sketch out; and then we will explain it in some detail.

#include <dht.h>
#define dataPin 8 // Defines pin number to which the sensor is connected
dht DHT; // Creats a DHT object

void setup() 
{
	Serial.begin(9600);
}
void loop() 
{
	//Uncomment whatever type you're using!
	int readData = DHT.read22(dataPin); // DHT22/AM2302
	//int readData = DHT.read11(dataPin); // DHT11

	float t = DHT.temperature; // Gets the values of the temperature
	float h = DHT.humidity; // Gets the values of the humidity

	// Printing the results on the serial monitor
	Serial.print("Temperature = ");
	Serial.print(t);
	Serial.print(" ");
	Serial.print((char)176);//shows degrees character
	Serial.print("C | ");
	Serial.print((t * 9.0) / 5.0 + 32.0);//print the temperature in Fahrenheit
	Serial.print(" ");
	Serial.print((char)176);//shows degrees character
	Serial.println("F ");
	Serial.print("Humidity = ");
	Serial.print(h);
	Serial.println(" % ");
	Serial.println("");

	delay(2000); // Delays 2 secods
}

The sketch starts by including DHT library. Next, we need to define the Arduino pin number to which our sensor’s Data pin is connected and create a DHT object. So, that we can access special functions related to the library.

#include <dht.h>
#define dataPin 8 // Defines pin number to which the sensor is connected
dht DHT; // Creats a DHT object

In the ‘setup’ function; we need to initiate the serial communication as we will use the serial monitor to print the results.

void setup() {
  Serial.begin(9600);
}

In the ‘loop’ function; we will use the read22() function which reads the data from the DHT22/AM2302. It takes sensor’s Data pin number as a parameter. If you are tinkering with DHT11, you need to use read11() function. You can do that by uncommenting second line.

//Uncomment whatever type you're using!
int readData = DHT.read22(dataPin); // DHT22/AM2302
//int readData = DHT.read11(dataPin); // DHT11

Once the humidity and temperature values are calculated, we can access them by:

float t = DHT.temperature; // Gets the values of the temperature
float h = DHT.humidity; // Gets the values of the humidity

The DHT object returns temperature value in Celsius (°C). It can be converted in to Fahrenheit (°F) using a simple formula:

T(°F) = T(°C) × 9/5 + 32

//print the temperature in Fahrenheit
Serial.print((t * 9.0) / 5.0 + 32.0);

At the end we will print the temperature and the humidity values on the serial monitor.

DHT11 DHT22 AM2302 Sensor DHTlib library Output on Serial Monitor
Output on Serial Monitor

Arduino Project

Arduino Code – DHT11 and DHT22/AM2302 with LCD

Sometimes you come up with an idea where you want to monitor temperature and humidity levels in your DIY incubator. Then you’ll probably need 16×2 character LCD to display prevailing conditions in your incubator, instead of a serial monitor. So, in this example, we’ll hook the LCD up to the Arduino along with the DHT11, DHT22/AM2302 sensor.

In case you are not familiar with 16×2 character LCDs, consider reading (at least skimming) below tutorial.

SUGGESTED READING

Tutorial Interfacing 16x2 character LCD with Arduino Uno
Interfacing 16×2 Character LCD Module with Arduino
Want your Arduino projects to display status messages or sensor readings? Then these LCD displays might be the perfect fit. They are extremely common and...

Next, we need to make connections to the LCD as shown below.

Arduino Wiring Fritzing Connections with DHT11 and 16x2 Character LCD
Wiring DHT11 and 16×2 Character LCD to Arduino UNO
Arduino Wiring Fritzing Connections with DHT22 and 16x2 Character LCD
Wiring DHT22 and 16×2 Character LCD to Arduino UNO

The following sketch will print the temperature and relative humidity values on the 16×2 character LCD. It uses the same code except we print values on LCD.

#include <LiquidCrystal.h> // includes the LiquidCrystal Library
#include <dht.h>
#define dataPin 8

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Creates an LCD object. Parameters: (rs, enable, d4, d5, d6, d7)
dht DHT;
bool showcelciusorfarenheit = false;

void setup() 
{
	lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display
}

void loop() 
{
	int readData = DHT.read22(dataPin);
	float t = DHT.temperature;
	float h = DHT.humidity;
	lcd.setCursor(0,0); // Sets the location at which subsequent text written to the LCD will be displayed
	lcd.print("Temp.: "); // Prints string "Temp." on the LCD

	//Print temperature value in Celcius and Fahrenheit every alternate cycle
	if(showcelciusorfarenheit)
	{
		lcd.print(t); // Prints the temperature value from the sensor
		lcd.print(" ");
		lcd.print((char)223);//shows degrees character
		lcd.print("C");
		showcelciusorfarenheit = false;
	}
	else
	{
		lcd.print((t * 9.0) / 5.0 + 32.0); // print the temperature in Fahrenheit
		lcd.print(" ");
		lcd.print((char)223);//shows degrees character
		lcd.print("F");
		showcelciusorfarenheit = true;
	}
	
	lcd.setCursor(0,1);
	lcd.print("Humi.: ");
	lcd.print(h);
	lcd.print(" %");
	delay(5000);
}
DHT11 DHT22 Arduino Sketch Temperature Humidity Measurements Output on LCD
Temperature & humidity measurements on LCD