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:
The DHT22 communicates using a proprietary single-wire serial protocol. Here's a breakdown of the process:
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.
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 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.
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
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 ;
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 ;
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.
I like Notepad Next for Linux, a cross-platform, reimplementation of Notepad++. https://github.com/dail8859/NotepadNext
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.
AZDelivery Logic Analyzer 8 CH, 24MHz. (Amazon)
PulseView is a Qt-based logic analyzer and oscilloscope GUI for sigrok.