using DHT11 sensor with STM32

Description

DHT11 digital temperature and humidity sensor is a composite Sensor contains a calibrated digital signal output of the temperature and humidity. Today in this tutorial we will be using DHT11 sensor with STM32.

INITIALIZATION

As you can see above, in order to initialize the sensor, we have to pull the data line LOW for around 18 ms. After this DHT11 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 DHT11 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 18ms.

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

DHT11 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 DHT11 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 DHT11 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

First of all we need to create the delay in microseconds. I have made a video about it. You can check that HERE

INITIALIZATION

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

2.) Pull the pin low and wait for 18ms.

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

void DHT11_start (void)
{
set_gpio_output (); // set the pin as output
HAL_GPIO_WritePin (DHT11_PORT, DHT11_PIN, 0); // pull the pin low
delay (18000); // wait for 18ms
set_gpio_input (); // set as input
}
RESPONSE

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.

void check_response (void)
{
	delay (40);
	if (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)))  // if the pin is low
	{
		delay (80);  // wait for 80us
		if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1))) check = 1;  // now if the pin is high response = ok i.e. check =1
	}
	while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_1)));   // wait for the pin to go low
}
READ DATA

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.

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
		delay(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;
}

 

Result

 

 

DOWNLOAD

You can buy me a coffee sensor 🙂

download the CODE below

, , , , ,

21
Leave a Reply

avatar
12 Comment threads
9 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
10 Comment authors
KamilGuest namePavan JadhavJayceSkywalker Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
AHAC
Guest
AHAC

good

basma
Guest
basma

thank you for this tutoriel, it’s a perfect job ^^
i try to modify your code to read values from DHT22, i modify the time like it was in the datasheet but i don’t understand why the sensor returns 0, i use an stm32f4Discovery without LCD could you help me plz !!

basma
Guest
basma

uint8_t Rh_byte1, Rh_byte2, Temp_byte1, Temp_byte2; uint16_t sum, RH, TEMP; uint8_t check = 0; void DHT22_Out(void){ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz ; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); } void DHT22_In(void){ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz ; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); } void DHT22_Start(void){ DHT22_Out(); GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_RESET); Delay(500); GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET); Delay(30); DHT22_In(); } void Check_Response(void){ Delay(40); if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)) { Delay(80); if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)) check=1; } while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)); } uint8_t Read_Data(void){ uint8_t i, j ; for (j=0; j<8 ; j++){ while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1));… Read more »

basma
Guest
basma

this is my code if you don’t mind check it with me to be useful

Marek
Guest
Marek

Hey, Your website is just amazing, I really admire it. I was just wondering – woudn’t be easier to set GPIO pin in open-drain mode instead writing set_gpio_output and set_gpio_input functions?
Greetings,
Marek

Hamid
Guest
Hamid

Hi, where is the ” dwt_stm32_delay.h and .c ” , also ” i2c-lcd.h and .h “. I need it asap please. Many thanks.

Skywalker
Guest
Skywalker

Can you help me how connect dht11 with stm32f103c.Thank!

skywalker
Guest
skywalker

Can you help me how connecting stm32f103c8t6 with Dht11. Thank!

Jayce
Guest
Jayce

Could you help me with this function? The check variable always returns check = 0.
And when I run debug the Debugger pop-up is: Cannot access target. Shutting down debug session.
void DHT11_start (void)
{
set_gpio_output (); // set the pin as output
HAL_GPIO_WritePin (GPIOB, GPIO_PIN_0, 0); // pull the pin low
DWT_Delay_us (18000); // wait for 18ms
set_gpio_input (); // set as input
}

void check_response (void)
{
DWT_Delay_us (40);
if (!(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)))
{
DWT_Delay_us (80);
if ((HAL_GPIO_ReadPin (GPIOB, GPIO_PIN_0))) check = 1;
printf(“DHT11_Response = %d”, check);
}
printf(“DHT11_Response = %d”, check);
while ((HAL_GPIO_ReadPin (GPIOB, GPIO_PIN_0))); // wait for the pin to go low
}

Pavan Jadhav
Guest
Pavan Jadhav

Hi ControllersTech Team,

I appreciate for your work related to DHT11 with STM32 however I am getting stuck in the [ check response ] function & not sure what is the exact problem here. With the debugging what I observed is that it stucks in while loop within the check_response function…
It will be highly appreciated to have your guidance.

Guest name
Guest
Guest name

in function: uint8_t read_data should not be: DWT_Delay_us(50) rather than: DWT_Delay_us(40) ?
In Datasheet is written: “When DHT is sending data to MCU, every bit of data begins with the 50us low-voltage-level”

Kamil
Guest
Kamil

i did this programm with delays for DHT22 and i got 0 warnings and 0 errors, but from sensor i see 0, and LCD just lights (any on it). Can I send project to you? Im very pleased
Best regards Man

Menu