User Tools

Site Tools


en:pfw:dht22

**This is an old revision of the document!**

DHT22 Protocol

Introduction

The DHT22 module is a low-cost digital temperature and humidity sensor. It utilizes a capacitive humidity sensor and a thermistor to measure the surrounding air and outputs a digital signal via a single data pin. It's known for its wider measurement range and higher accuracy compared to its predecessor, the DHT11.

Key features include:

  • Measures both temperature (from -40°C to 80°C with an accuracy of ±0.5°C) and humidity (from 0% to 99.9%RH with an accuracy of ±2-5%).
  • Digital output via a single-wire interface, simplifying communication with microcontrollers like Arduino and Raspberry Pi.
  • Operates on a voltage range of 3.3V to 6V.
  • Has a relatively low power consumption.
  • Offers good long-term stability.
  • Typically comes on a small PCB with necessary pull-up resistors, making it easy to integrate into projects.
  • Has a sampling rate of no more than 0.5 Hz (once every 2 seconds).
  • Suitable for indoor environmental monitoring, weather stations, and HVAC systems.

SDA

The DHT22 communicates using a proprietary single-wire serial protocol. Here's a breakdown of the process:

  1. Start Signal from Microcontroller: The microcontroller initiates communication by pulling the data line low for a specific duration (typically > 800µs to 1ms). This signals the DHT22 to wake up and prepare to send data.
  2. Response from DHT22: After the start signal, the DHT22 pulls the data line low for about 80µs and then high for another 80µs. This serves as a response signal indicating that the sensor is ready to transmit data.
  3. Data Transmission (40 bits): The DHT22 transmits 40 bits of data representing humidity and temperature readings, followed by a checksum bit. Each bit is transmitted as follows: * The data line is first pulled low for approximately 50µs. * Then, it's pulled high for a varying duration: * 26-28µs high indicates a “0” bit. * 70µs high indicates a “1” bit.
  4. Data Format (5 bytes): The 40 bits of data are structured into five 8-bit bytes: * Byte 1: Humidity integer part (0-99) * Byte 2: Humidity decimal part (always 0 for DHT22) * Byte 3: Temperature integer part (-40 to +80) * Byte 4: Temperature decimal part (always 0 for DHT22) * Byte 5: Checksum (sum of the first four bytes, modulo 256)
  5. End of Transmission: After transmitting all 40 bits, the DHT22 releases the data line, and it's pulled high by an external pull-up resistor, returning to the idle state.

The microcontroller needs to carefully time these pulses to correctly interpret the data sent by the DHT22. Libraries for popular platforms like Arduino and Raspberry Pi handle these timing-critical operations.

am2302-en-aosong.pdf This Aosong document has the correct data, although it is a creepy English translation.

On page 2, under 4, “The definition of single-bus interface,” pin 2 of the sensor is called SDA, Serial Data. A table and a figure show the pin assignment of the AM2302.

Screenshot of the 40-bit response on the SDA line. (PulsView Logic Analyser)

Implementation

Testing with a Logic Analyser (PulsView)

Pin P1.0 is bidirectional. It sends the start pulse and then receives the 40 data bits from the sensor module.

The code includes test pulses on pin P1.6 to check the timing. You can remove those.

The top line is the DHT22's response, and the following line shows the timing checks. The checksum is correct.

The time-critical part is assembler code. The surrounding code was written in noForth. It uses tools.f and noforth_m_asm from the noForth library. These must be compiled into noForth on the MSP430G2553 beforehand.

Sensor modules vary in their output speed due to manufacturing and temperature conditions. 1/4 of the response pulse is approximately the waiting time to read the bit. Therefore, the code adapts to the observed speed. A 'while' loop is used for this, but its execution takes about twice as long as the wait loop for reading the bit. The waiting time from 'moon' is therefore simply doubled to make it fit.

The timing is critical. So, it's correct now. Here we read a "0"

Pseudocode

Function: Pio    ( -- )  \ set port I/O function. SDA --> P1.0 
Function: wakeup ( -- )  \ notify sensor to prepare the data
Function: @data  ( -- sun moon hum tmp chk chksum )  \ get sensor data
  get response time of sensor, store in register 'sun' (just for testing)
  get startpulse duration, store in register 'moon'
  40 loop 
     read bit using 'moon' based delay 
     lshift bit into array xx yy zz
  08 loop       
     lshift array  \ adjust xx yy zz --> hum tmp chk 
  calculate chksum
Function: (dht22)  ( -- sun moon hum tmp chk chksum ) \ wake up and read sensor
Function:  dht22   ( -- )  \ print temperatur and humidity
Function:  test    ( n -- ) \ multiple readings  
    n loop  dht22

Numerical representation of the measured values

Humidity

The first 16 bits coming from the DHT22 are the relative humidity in tenths of a percent. They can be processed directly with the 16-bit noForth and correspond to a positive integer. Rounded to whole digits for display purposes. Here is an excerpt from the noforth source code:

: .hum ( hum -- )   10 / . ." %rel" space  ;  

Temperature

The next 16 bits are the temperature in tenths of a degree Celsius. Temperatures from zero degrees and higher can be processed directly using the 16-bit noForth; they correspond to a positive integer.

Temperatures below zero degrees are represented by the DHT22 as follows: The MSB of the 16-bits is set, but otherwise the temperature is specified as a positive integer. This number format does not correspond to the two's complement of noForth. Here, the MSB must first be evaluated to determine the sign. The sign is prepended for output. The measured value can then be further processed as a positive integer. Whole degrees are displayed to the left of the decimal point, tenths to the right. The unit °C is specified.

: .tmp ( tmp -- )  
  dup hx 8000 and hx 8000 =  \ check MSB
      if [char] - 
      else [char] + 
      then emit
  hx 7fff and ( tmp -- +tmp )    \ reset MSB
  10 /mod 3 .r [char] . emit .    \ --> TTT.T
  [char] f decemit  [char] C emit  \ print °C
  space
  ;  
 

This is already included in the following source code. And here you can see how this was discovered: The temperature format of the DHT22

Source Code - and what it was used for.

DHT22 with Launchpad MSP430G2553 and noForth

This program was used to test DHT22 modules before installation. The DHT22 modules were tested for functionality at room temperature, pre-sorted in this way, and then frozen in a bag of moist sand in the freezer and tested again. One module displayed incorrect temperature values ​​in frost conditions, the display of negative values ​​did not comply with the specifications.

More information on the MSP430G2553

All about noForth

Source code editor

I like Notepad Next for Linux, a cross-platform, reimplementation of Notepad++. https://github.com/dail8859/NotepadNext

Terminal

To work with the embedded noForth system I use e4thcom by Manfred Mahlow. https://wiki.forth-ev.de/doku.php/projects:e4thcom

Sometimes I also use Windows and Teraterm, for example, to log longer MCU outputs to a file. I also prefer it for testing parts of the source code using copy and paste.

Logic Analyser

AZDelivery Logic Analyzer 8 CH, 24MHz. (Amazon)
PulseView is a Qt-based logic analyzer and oscilloscope GUI for sigrok.


en/pfw/dht22.1745667640.txt.gz · Last modified: 2025-04-26 13:40 by mka