Discuss this article in the Nuts & Volts forums at http://forum.nutsvolts.com.
The DHT22 is a recent contribution to the lineup of
joint humidity/temperature sensors. It is particularly
attractive to DIYers thanks to its low cost, which is
around $10. It spans an impressive range of 0% to100%
relative humidity, and - 40° C to 125° C (that’s - 40° F to
257° F). Of course, it’s doubtful any homebrew circuits
could operate at these two extremes of temperature, but
it’s nice to know the sensor won’t be the limiting factor.
The claimed accuracy is ±5% worst case for humidity
and ±0.2° C for temperature. A rather neat feature is that
both values are measured to the nearest tenth; that is, to
one decimal place.
Unfortunately, if you poke around the Web, you’ll
quickly discover that there are more questions than
answers concerning this device. Part of the reason for
this confusion is that it spits out the readings digitally
using a non-standard protocol. Another major problem
for English speaking experimenters is that the datasheet
(originally in Chinese) has been poorly translated and
more often than not leaves you scratching your head.
Then, there’s the problem of the numerical format of
the readings. This is not addressed in the datasheet and
demands a bit of detective work at the bench.
A few people have managed to put all the pieces
together and get it percolating in the Arduino or
C languages, often employing built-in timers or more
exotic aspects of microcontrollers.
This article lays bare these secrets and demystifies
the application of the DHT22. In particular, we’ll:
• Use the common and inexpensive PIC16F88
microcontroller to drive it.
How to Take a Reading
Let’s see if we can first make
sense of the communication
protocol. Begin by looking at the
schematic in Figure 1. As indicated
there, the DHT22 is a four-pin device;
+5V is applied to pin 1, while ground
is pin 4. Pin 3 is a “no-connection”
and simply ignored. Pin 2 is where
the magic occurs.
This single pin establishes a two-way conversation with the PIC16F88.
Obviously, this is going to be serial
communication, but it follows a
proprietary protocol — one you’ve
likely never seen before.
There will be five bytes
transmitted to the PIC. The first two
give the relative humidity, and the
next two give the temperature. The
last byte is a checksum used to
confirm everything went okay. We’ll
look more closely at how to interpret
these five bytes in just a moment, but
for now let’s presume that a string of
40 bits (five eight-bit bytes) is going
to shoot along pin 2 to port line A.0
of the PIC16F88. Referring again to
the schematic, A.0 appears at pin 17
of IC1 and can be configured either
as an input or output. We’ll assume
it’s an input when first powered on,
with resistor R1 acting as a pull-up.
To request a reading, port line
A.0 is made an output and then
pulled low for 18 milliseconds. After
this fairly lengthy time, the line is
pulled high again but for a much
shorter 40 microseconds. This
sequence then awakens the DHT22
sensor from its idling, low current
state. The PIC gets ready to listen to
it by making port line A.0 an input
The DHT22 responds with an
acknowledgement, indicated by the
following signals. The sensor now has
control of A.0 and pulls it low for 80
microseconds. The firmware in the
PIC can easily monitor this period
and if things run long, a timeout is
declared and some error-handling
can be invoked.
Okay, let’s assume everything
has gone according to Hoyle so far.
The DHT22 next brings port line A.0
high, again for 80 microseconds.
Once more, a timeout can be
checked on if desired.
Thus far, the PIC16F88 has sent a
request and the DHT22 has
responded with an acknowledgment.
The port line is still an input at this
point, and the microcontroller is
ready to start receiving those 40 bits
that make up the five bytes. Here’s
how it goes:
The DHT22 drops A.0 low for 50
microseconds. You can think of this
as a start signal. Now, the sensor
pulls the line high again. The length
of this pulse conveys the information
we want. If A.0 is high for 26 to 28
microseconds, a “zero” is indicated.
If it’s high for 70 microseconds, then
a “one” is implied. Hence, the pulse
width expresses the bit status.
In everyday language: After the
start signal, a short pulse represents a
zero, while a long pulse signals a
one. That takes care of the first bit.
Now, just go back to the start of this
paragraph and repeat the sequence
39 more times to get the remaining
bits. Notice that port line A.0 is still
an input. By the way, the bits always
come in from high order to low
March 2013 51