How to use DHT22 with STM32
UPDATE
If you are not able to get DHT11 or DHT22 values, Here is another method you can use. This one is unified for both the sensors. No setup needed for timer and all. Just select the data pin as output and you are done. you need to select the DHT TYPE in DHT.c
https://controllerstech.com/wp-content/uploads/2020/06/DHT_11_22_DWT.zip
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. In order to initialize the sensor, we have to pull the data line LOW for at least 1ms, and pull it HIGH for around 20-40 us.
On receiving the start signal, DHT22 will indicate it’s presence by pulling the line low for 80us and than high for 80us.
NOTE:- You might need to connect pull-up resistance to the data line or else DHT22 will not be able to pull it HIGH.
To initialize the sensor, the steps are as follows:-
- Set the pin (data) as output
- Pull the pin low and wait for > 1 ms
- Pull the pin high and wait for 30 us
- Release the pin by setting it as input
DHT22 will now send the response as you can see in the figure above. To check the response, steps are as follows:-
- wait for 40us
- Check if the pin is low, than wait for 80 us. This will totally be a delay of 120 us and the pin should be high now
- Check if the pin is high. If it is, than the response is OK
- Now wait for the pin to go LOW
DATA Transmission
Now DHT22 will send 40 bits of data. Each bit’s transmission begins with low-voltage-level that last 50 us, the following high-voltage-level signal’s length decides whether the bit is “1” or “0”.
- If the length of high-voltage-level is around 26-28 us, the bit is “0”
- And if the length is around 70 us, 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”.
Following are the steps to READ DATA from the sensor
- Wait for the pin to go high
- 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”
- write the respective values to the variable
Connection
Some Insight into the CODE
INITIALIZATION
void DHT22_Start (void)
{
Set_Pin_Output(DHT22_PORT, DHT22_PIN); // set the pin as output
HAL_GPIO_WritePin (DHT22_PORT, DHT22_PIN, 0); // pull the pin low
HAL_Delay(1200); // wait for > 1ms
HAL_GPIO_WritePin (DHT22_PORT, DHT22_PIN, 1); // pull the pin high
delay (20); // wait for 30us
Set_Pin_Input(DHT22_PORT, DHT22_PIN); // set as input
}
- Set the pin (data) as output
- Pull the pin low and wait for > 1 ms
- set the pin as input for receiving the data
RESPONSE
uint8_t DHT22_Check_Response (void)
{
Set_Pin_Input(DHT22_PORT, DHT22_PIN); // set as input
uint8_t Response = 0;
delay (40); // wait for 40us
if (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))) // if the pin is low
{
delay (80); // wait for 80us
if ((HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))) Response = 1; // if the pin is high, response is ok
else Response = -1;
}
while ((HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))); // wait for the pin to go low
return Response;
}
- wait for 40 us
- check if the pin is low, than wait for 80 us. This will totally be a delay of 120 us and the pin should be high now
- Check if the pin is high. If it is, than the response is OK
READ DATA
uint8_t DHT22_Read (void)
{
uint8_t i,j;
for (j=0;j<8;j++)
{
while (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))); // wait for the pin to go high
delay (40); // wait for 40 us
if (!(HAL_GPIO_ReadPin (DHT22_PORT, DHT22_PIN))) // 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 (DHT22_PORT, DHT22_PIN))); // wait for the pin to go low
}
return i;
}
- Wait for the pin to go high
- Wait for 40 us. This is because the length of “0” bit is 26-28 us and if the pin is high after 40 us, it indicates that the bit is “1”
- write the respective values to the variable