Temperature measurement using DHT22 in STM32

Description

In my last post, I mentioned the use of microseconds delay, check HERE, and this post is the application of that. Today I am going to interface DHT22 with STM32 microcontroller, which utilizes delay in microseconds.

The DHT-22  is a digital-output relative humidity and temperature sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and sends out a digital signal on the data pin. You can download the datasheet here.

I am not going to waste more time by going into more details, I am sure you already know what this is and that’s why you are here. So let’s jump to the point. If you look at the datasheet, you will find the signal pattern to initialize the sensor as shown in the picture below

INITIALIZATION

Here the black line is the signal from the microcontroller and the white line is the signal from the DHT22. As you can see in order to initialize the sensor, we have to pull the data line LOW for around 500 us (microseconds) and pull it HIGH for around 20-40 us. After this DHT22 will pull the line low for 80us and than high for 80us. Once this is done, the sensor will be initialized and start transmitting.

NOTE:- You need to connect pull-up resistance to the data line or else DHT22 will not be able to pull it HIGH.

So to initialize the sensor, steps are as follows:-

1.)  Set the pin (data) as output.

2.) Pull the pin low and wait for 500us.

3.) Pull the pin high and wait for 30us.

4.) set the pin as input for receiving the data.

DHT22 will now send the response as you can see in the figure above. To check the response, steps are as follows:-

1.) wait for 40us

2.) check if the pin is low, than wait for 80us. This will totally be a delay of 120us and the pin should be high now.

3.) Check if the pin is high. If it is, than the response is ok.

4.) Now wait for the pin to go low as you can see below that the pin is low for 50us before transmitting any bit.

DATA Transmission

Now DHT22 will send 40 bits of data.  Each bit’s transmission begins with low-voltage-level that last 50us, the following high-voltage-level signal’s length decides whether the bit is “1” or “0”.

So if the length of high-voltage-level is around 26-28us, the bit is “0”.

And if the length is around 70us, than the bit is “1”.

The 40 bits sent by DHT22 are as follows DATA = 8 bit integral RH data + 8 bit decimal RH data + 8 bit integral T data+8 bit decimal T data + 8 bit checksum

If the data transmission is right, check-sum should be the last 8 bit of “8 bit integral RH data+8 bit decimal RH data+8 bit integral T data+8 bit decimal T data”

Reading data is also very simple. Steps are as follows:-

1.) Wait for the pin to go high.

2.) Wait for 40us. This is because the length of “0” bit is 26-28us  and if the pin is high after 40us, it indicates that the bit is “1”.

3.) write the respective values to the variable.

Some Insight into the CODE

INITIALIZATION
void DHT22_start (void)
{
	set_gpio_output ();  // set the pin as output
	HAL_GPIO_WritePin (GPIOA, GPIO_PIN_1, 0);   // pull the pin low
	DWT_Delay_us (500);   // wait for 500us
	HAL_GPIO_WritePin (GPIOA, GPIO_PIN_1, 1);   // pull the pin high
	DWT_Delay_us (30);   // wait for 30us
	set_gpio_input ();   // set as input
}
RESPONSE
void check_response (void)
{
	DWT_Delay_us (40);  // wait for 40us
	if (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))) // if the pin is low
	{
		DWT_Delay_us (80);   // wait for 80us
		if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))) check = 1;  // if the pin is high, response is ok
	}
	while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));   // wait for the pin to go low
}
READ DATA
uint8_t read_data (void)
{
	uint8_t i,j;
	for (j=0;j<8;j++)
	{
		while (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));   // wait for the pin to go high
		DWT_Delay_us (40);   // wait for 40 us
		if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)) == 0)   // if the pin is low 
		{
			i&= ~(1<<(7-j));   // write 0
		}
		else i|= (1<<(7-j));  // if the pin is high, write 1
		while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));  // wait for the pin to go low
	}
	return i;
}

 

Connection

Result

 

 

100%
100%

DOWNLOAD

You can buy me a coffee sensor 🙂

download the CODE below

, , , , , ,

26
Leave a Reply

avatar
9 Comment threads
17 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
13 Comment authors
Bilgehan KarginmohammadSUMIT MISHRAVadim M.Ritik Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Hamza ELGUEZZAR
Guest
Hamza ELGUEZZAR

where is dwt_stm32_delay.h/dwt_stm32_delay.c please !

Zac Pike
Guest
Zac Pike

Do I need to change the Master Transmit address from 0x4E to whatevery my I2C is putting out? For Arduino I needed to use a scanner and check to see what it was and change that over before transmitting? Just wondering because I used everything here for my STM32F4 and it’s not working…thanks.

Simon
Guest
Simon

Hello, I just followed your youtube video here. This code is different with another I2C code, First your codes on this project are: void lcd_send_cmd (char cmd) { char data_u, data_l; uint8_t data_t[4]; data_u = cmd&0xf0; data_l = (cmd<<4)&0xf0; data_t[0] = data_u|0x04; //en=1, rs=0 data_t[1] = data_u; //en=0, rs=0 data_t[2] = data_l|0x04; //en=1, rs=0 data_t[3] = data_l; //en=0, rs=0 HAL_I2C_Master_Transmit (&hi2c1, 0x4E,(uint8_t *) data_t, 4, 100); } void lcd_send_data (char data) { char data_u, data_l; uint8_t data_t[4]; data_u = data&0xf0; data_l = (data<<4)&0xf0; data_t[0] = data_u|0x05; //en=1, rs=0 data_t[1] = data_u|0x01; //en=0, rs=0 data_t[2] = data_l|0x05; //en=1, rs=0 data_t[3] =… Read more »

beema
Guest
beema

is it same and works for dht11 module?

basma
Guest
basma

hello thanks for the code, i want to read values from dht22 but without using an LCD how could to modify your code to be useful in my case

joel
Guest
joel

In line No. 78 if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))) check = 1;
Variable “check” is not used anywhrere. Could you explain Why the “check” need?

Vadim M.
Guest
Vadim M.

Hi! Thank you for your tuto! For the right checksum you shound do:
if (sum == ((Rh_byte1+Rh_byte2+Temp_byte1+Temp_byte2) & 0xFF))

Best regards

SUMIT MISHRA
Guest
SUMIT MISHRA

Hi, why you used separate delay function instead of HAL Delay? Any specific reason?

Bilgehan Kargin
Guest
Bilgehan Kargin

I’ve practiced everything you’ve told us. But, while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))); // wait for the pin to go low
in this line, waiting forever, I can not go to next step. What could be the reason ?

Menu