Dth11温湿度传感器

Dth11温湿度传感器

元件:该传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。

引脚说明

  1. VDD:供电3-5.5V
  2. DATA:串行数据,单总线
  3. NC:空脚,请悬空
  4. GND:接地,电源负极

工作流程

DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零。操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:
8bit湿度整数数据 + 8bit湿度小数数据 + 8bit温度整数数据 + 8bit温度小数数据 +8 bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
bits[0]+bits[1]+bits[2]+bits[3]=bits[4]

主机请求:总线拉低至少18ms,之后总线拉高延时等待20-40us,切换到输入模式;
DHT响应:接收到开始信号后,等待主机信号结束,然后发送80us低电平响应信号,之后把总线拉高80us准备发送数据,每一bit数据以50us低电平时隙开始,高电平的长短决定数据位为0或1,当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

代码说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
float dht11::dec2f(uint8_t x)
{
float result = 0.0;
while (x != 0)
{
result = ((float)x) / 10;
x /= 10;
}
return result;
}
int dht11::read(int pin)
{
// BUFFER TO RECEIVE
uint8_t bits[5];
uint8_t cnt = 7;
uint8_t idx = 0;
int tmp = 0;
float decpart = 0.0;
float intpart = 0.0;

// EMPTY BUFFER
for (int i = 0; i < 5; i++)
bits[i] = 0;

pinMode(pin, OUTPUT); //输出模式
digitalWrite(pin, LOW); //拉低点位
delay(18); //主机发送开始信号
digitalWrite(pin, HIGH); //拉高点位
delayMicroseconds(40); //延时等待
pinMode(pin, INPUT); //切换为输入模式,接收信号

// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = 10000;
while (digitalRead(pin) == LOW) //接收DHT响应信号
if (loopCnt-- == 0)
return DHTLIB_ERROR_TIMEOUT;

loopCnt = 10000;
while (digitalRead(pin) == HIGH) //DHT准备发送数据
if (loopCnt-- == 0)
return DHTLIB_ERROR_TIMEOUT;

// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
for (int i = 0; i < 40; i++)
{
loopCnt = 10000;
while (digitalRead(pin) == LOW)
if (loopCnt-- == 0)
return DHTLIB_ERROR_TIMEOUT;

unsigned long t = micros();

loopCnt = 10000;
while (digitalRead(pin) == HIGH)
if (loopCnt-- == 0)
return DHTLIB_ERROR_TIMEOUT;

if ((micros() - t) > 40)
bits[idx] |= (1 << cnt); //高点位维持26us-28us代表‘0’,维持70us代表‘1’,这里以40us为界限判断
if (cnt == 0) // 判断8bit是否结束
{
cnt = 7; // 重置准备下一8bit读取
idx++;
}
else
cnt--;
}

decpart = dec2f(bits[1]); //第二个8bit,转换湿度float小数部分(湿度的小数确实无数据)
tmp = bits[0];
intpart = (float)(tmp); //第一个8bit,转换湿度float整数部分
humidity = intpart + decpart;

decpart = dec2f(bits[3]); //第四个8bit,转换温度float小数部分(测试温度的小数是有数据的)
tmp = bits[2];
intpart = (float)(tmp); //第三个8bit,转换温度float整数部分
temperature = intpart + decpart;

uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];

if (bits[4] != sum)
return DHTLIB_ERROR_CHECKSUM; //校验和
return DHTLIB_OK;
}