Skip to content

Contributed by WildboarG, organized by Ai-Thinker

Ai-WB2 Reading the DHT11 Temperature and Humidity Sensor

WB2 Reading the DHT11 Temperature and Humidity Sensor


Description


DHT11 can detect both temperature and humidity, but its accuracy and measurement range are lower than those of the DS18B20. Its temperature measurement range is 0~50°C with an error of ±2°C; its humidity measurement range is 20%~90%RH (Relative Humidity — the percentage of water vapor pressure relative to the saturated water vapor pressure in the air), with an error of ±5%RH.

The DHT11 circuit is very simple: you only need to connect the DATA pin to one I/O of the MCU, but this pin requires a 5K pull-up resistor. The DHT11 supply voltage is 3~5.5V.

The data format is: 8bit humidity integer data + 8bit humidity decimal data + 8bit temperature integer data + 8bit temperature decimal data + 8bit checksum, 5 bytes (40bit) in total.

Since the DHT11 resolution is only accurate to single digits, the decimal part is all zeros. The checksum is the sum of the first 4 bytes of data, and its purpose is to ensure the accuracy of data transmission.

The DHT11 only triggers a temperature and humidity measurement after receiving a start signal. If it does not receive the reset signal sent by the host, the DHT11 does not actively measure temperature and humidity. When data acquisition is complete and there is no start signal, the DHT11 automatically switches to low-speed mode.

Note: since the DHT11 timing requirements are very strict, to prevent interrupts from interfering with the bus timing, first disable the global interrupts when handling the timing, and re-enable them after the operation is complete. (One communication takes about 4ms)

Circuit Connection

Communication Timing

Code


Step by step

  • Create a new project dht11
Click to expand: > wb2-cli create
sh
> wb2-cli create
> Create New Project:dht11
> successfuly
  • Write main.c in the project directory
Click to expand full code
c
#
include

<stdio.h>

#
include

<FreeRTOS.h>

#
include

<task.h>

#
include

<bl_gpio.h>

#
include

<bl_timer.h>

#
include

<blog.h>

#
include

<dht11.h>

#
define
 GPIO_DHT 4
//定义工作引脚

extern

unsigned

int
 rec_data[
4
];

int

main
(
void
)
 {

// add your code here

  bl_gpio_enable_output(GPIO_DHT,
0
,
0
);

printf
(
"start DTH11\r\n"
);

while
 (
1
) {
    DHT11_REC_Data();
    bl_timer_delay_us(
1000
 *
1000
);

printf
(
"Temperature:%d°C Humidity:%d%% \r\n"
, rec_data[
2
], rec_data[
0
]);
  }
}
  • Write dht11.h
Click to expand full code
c
#
ifndef
 __DHT11_H__

#
define
 __DHT11_H__

#
include

"bl_timer.h"

#
include

<bl_gpio.h>

#
define
 GPIO_DHT 4

#
define
 dht11_high bl_gpio_output_set(GPIO_DHT, 1)

#
define
 dht11_low bl_gpio_output_set(GPIO_DHT, 0)

#
define
 Read_Data bl_gpio_input_get_value(GPIO_DHT)

void

DHT11_GPIO_Init_OUT
(
void
)
;

void

DHT11_GPIO_Init_IN
(
void
)
;

void

DHT11_Start
(
void
)
;

unsigned

char

DHT11_REC_Byte
(
void
)
;

void

DHT11_REC_Data
(
void
)
;

#
endif
  • Write the driver functions in dht11.c
Click to expand full code
c
#
include

"dht11.h"

// 数据存放

unsigned

int
 rec_data[
4
];

// 做为输出

void

DH11_GPIO_Init_OUT
(
void
)
 { bl_gpio_enable_output(GPIO_DHT,
0
,
0
); }

// 做为输入

void

DH11_GPIO_Init_IN
(
void
)
 { bl_gpio_enable_input(GPIO_DHT,
0
,
0
); }

// 主机发送开始信号

void

DHT11_Start
(
void
)
 {
  DH11_GPIO_Init_OUT();
// 输出模式

  dht11_high;
// 先拉高

  bl_timer_delay_us(
30
);

  dht11_low;
// 拉低电平至少18us

  bl_timer_delay_us(
20
 *
1000
);

  dht11_high;
// 拉高电平20~40us

  bl_timer_delay_us(
30
);

  DH11_GPIO_Init_IN();
// 输入模式

}

// 获取一个字节

char

DHT11_Rec_Byte
(
void
)
 {

unsigned

char
 i =
0
;

unsigned

char
 data =
0
;

for
 (i =
0
; i <
8
; i++)
// 1个数据就是1个字节byte,1个字节byte有8位bit

  {

while
 (Read_Data ==
0
)
      ;
// 从1bit开始,低电平变高电平,等待低电平结束

    bl_timer_delay_us(
30
);
// 延迟30us是为了区别数据0和数据1,0只有26~28us

    data <<=
1
;
// 左移

if
 (Read_Data ==
1
)
// 如果过了30us还是高电平的话就是数据1

    {
      data |=
1
;
// 数据+1

    }

while
 (Read_Data ==
1
)
      ;
// 高电平变低电平,等待高电平结束

  }

return
 data;
}

// 获取数据

void

DHT11_REC_Data
(
void
)
 {

unsigned

int
 R_H =
0
, R_L =
0
, T_H =
0
, T_L =
0
;

unsigned

char
 RH =
0
, RL =
0
, TH =
0
, TL =
0
, CHECK =
0
;

  DHT11_Start();
// 主机发送信号

  dht11_high;
// 拉高电平

if
 (Read_Data ==
0
)
// 判断DHT11是否响应

  {

while
 (Read_Data ==
0
)
      ;
// 低电平变高电平,等待低电平结束

while
 (Read_Data ==
1
)
      ;
// 高电平变低电平,等待高电平结束

    R_H = DHT11_Rec_Byte();
    R_L = DHT11_Rec_Byte();
    T_H = DHT11_Rec_Byte();
    T_L = DHT11_Rec_Byte();
    CHECK = DHT11_Rec_Byte();
// 接收5个数据

    dht11_low;
// 当最后一bit数据传送完毕后,DHT11拉低总线 50us

    bl_timer_delay_us(
55
);
// 这里延时55us

    dht11_high;
// 随后总线由上拉电阻拉高进入空闲状态。

if
 (R_H + R_L + T_H + T_L ==
        CHECK)
// 和检验位对比,判断校验接收到的数据是否正确

    {
      RH = R_H;
      RL = R_L;
      TH = T_H;
      TL = T_L;
    }
  }
  rec_data[
0
] = RH;
  rec_data[
1
] = RL;
  rec_data[
2
] = TH;
  rec_data[
3
] = TL;
}
  • Compile it
Click to expand: make -j32
bash
make -j32
  • Flash it
Click to expand: make flash
bash
make flash

Display

Open the serial assistant and check the result

Connection Diagram

Ran two jumper wires with a little helper gadget, and the result is quite good


Released under the MIT License. Build Time 2026-09-11 14:52:23