arduino学习系列——DHT11温湿度传感器的使用

arduino学习系列——DHT11温湿度传感器的使⽤
⼀、器材
arduino UNO、⾯包板、DHT11温湿度传感器、连接线
这⾥说⼀下DHT11的基本情况:
(1)引脚说明:
1、VDD 供电 3.5V-5.5V DC
2、DATA 串⾏数据,单总线
3、GND 接地,电源负极。
(2)DHT11data数据格式:
⼀次传输40位数据=8bit湿度整数数据 + 8bit湿度⼩数数据 + 8bint温度整数数据 + 8bit温度⼩数数据 + 8bit校验位3、时序图
⼆、连接图
如图所⽰,将DHT11的正极与5V电源接⼝相连,负极与GND相连,中间的数据接⼝与2号引脚相连。
三、代码
#include <dht11.h>
加权最小二乘法
dht11 DHT11;
#define DHT11PIN 2
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println("/n");
int chk = ad(DHT11PIN);
Serial.print("Read sensor: ");
证件哥switch (chk)
{
case DHTLIB_OK:
Serial.println("OK");
苗建中break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Checksum error");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
混流式风机
}
Serial.print("Humidity (%): ");
Serial.println((float)DHT11.humidity, 2);
Serial.print("Temperature (oC): ");
Serial.println((perature, 2);
delay(2000);
}
四、注意事项
1、代码中引⽤了#include <dht11.h>,这个是操作DHT11的库⽂件,有了它,就可以轻松操作我们这个温湿度传感器了。但是引⽤这个库⽂件的操作步骤是:
(1)在⽹上到并下载该库⽂件,包括⼀个头⽂件和⼀个.cpp⽂件。
(2)在arduinoIDE中点击菜单:程序–导⼊库–add library,然后选择你存放库⽂件的那个⽂件夹。
(3)在代码中引⽤#include <dht11.h>,这样就可以使⽤了。
2、#define DHT11PIN 2,表⽰定义引脚2的名字为DHT11PIN ,注意这个定义语句后⾯没有分号。
五、原理分析
在硬件编程过程中,当你拿到⼀个器件,⾸先要了解他的引脚定义,这会告诉你这个东西应该怎么连接,在⼀个就是要看他的时序图,看了时序图你就知道主从设备之间进⾏数据采集过程中的代码应该怎么写,⽐如怎么启动,如何握⼿,怎么采集真正的数据等等。
在我们这个试验中,DHT11的时序图是这样的:
下⾯对照dht11.cpp源代码说说我们采集温湿度信息的原理(在代码中加了注释,说明相关内容。):
#include "dht11.h"
int dht11::read(int pin)
{
// BUFFER TO RECEIVE
uint8_t bits[5];//这⾥定义了5个⼋位的数组,也就是40位数据,⽤来存储数据采集的结果。
uint8_t cnt = 7;//这个是⽤来给每⼀个数据的每⼀位输⼊值时计数⽤的。
uint8_t idx = 0;//这个是给5个数组计数⽤的。
// EMPTY BUFFER
for (int i=0; i< 5; i++) bits[i] = 0;
//⾸先在这⾥把这5个⼋位的数组全部填0,也就是初始值为0.
// REQUEST SAMPLE
pinMode(pin, OUTPUT);
//将引脚定义为输出,也就是由arduino给DHT11写数据。从上⾯的时序图可以看出,要启动DHT11⾸先要给他发送18毫秒的低电平,再发送20~40微秒的⾼电平,DHT11只有看到了这样的信号,才会采集数据。
digitalWrite(pin, LOW);
delay(18);//这⾥就是发送18毫秒的低电平
digitalWrite(pin, HIGH);
delayMicroseconds(40);//这⾥就是发送40微秒的⾼电平
pinMode(pin, INPUT);
//发送完之后,这就等于把DHT11启动了,这时候我们就要从这个引脚上接受数据了,所以这时候要将这个引脚定义为输⼊引脚。
// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
//从时序图中可以看出,接受数据⼀开始⾸先要读取80微秒的低电平,这⾥是⼀个等待,要把这80微秒等过去,但是有时候也有可能是传感器出现了故障,他⼀直发低电平,如果你持续等待不就相当于死机了,所以在这⾥要设置⼀个超时,也就是说要等待,但时间长了,就认为出问题了,返回⼀个异常信息。
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
//从时序图中可以看出,在80微秒的低电平之后是80微秒的⾼电平,这⾥仍然要等待,超时的原理与上⾯的低电平⼀样。
// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
//根据时序图,从下⾯开始就是40位的真正要读取的数据了,那么这⾥⽤了⼀个for循环来⼀位⼀位的读取这40bit的数据(注意是bite)。
for (int i=0; i<40; i++)
{
//根据时序图,可以看出,对于每⼀个bite位数据,都是由⼀个低电平和⼀个⾼电平组成,区分这⼀位数据是1还是0取决于⾼电平的时常,如果⾼电平的时常为70微秒则表⽰1,如果⾼电平的时常为26~28微秒则表⽰0,因此读取每⼀位数据时,都是先等待把50微秒的低电平等过去,然后判断⾼电平的时常,根据这个时常来判断这bite的数据是1还是0.
loopCnt = 10000;
while(digitalRead(pin) == LOW)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
//这⼀句就是要把低电平等过去。
日本雅乐
unsigned long t = micros();
//这⾥使⽤函数micros()获取了⼀个当前的时间,就是为了⽐较⾼电平的时常⽤的。
loopCnt = 10000;
while(digitalRead(pin) == HIGH)
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
//这⾥就把⾼电平读出来了。
if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
/
/然后再次使⽤micros()函数获取当前时间,减去读取⾼电平之前的时间点,也就是这个⾼电平的时常了,然后看这个时常是否⼤于40微秒,如果⼤于就认为是1,否则就认为这位是0.那么这⾥⼜是怎么运算的呢?分析下:bits[idx]表⽰⼀个8位的数组,假设他是0000 0000,运算符“|=”表⽰按位进⾏或运算,然后再把运算的结果赋给运算符左边的变量。⽽(1 << cnt)表⽰把数字1的⼆进制表⽰法向左移动cnt位,移动后的空位⽤0来填充。因此,对于⼀个⼋位的1可以表⽰为:00 00 0001,刚才的初始化过程中我们知道cnt的值为7,所以,把这个0000 0001左移七位就变成了:1000 0000.然后将这个数与0000 0000进⾏|=运算,之后bits [idx]中的值就是1000 0000。可见这段代码实现的功能就是如果的到的这位数据是1,就将他存储到bits[idx]相应的位上去。
//下⾯这段代码就是在循环的过程中修改cnt和idx的值,然后进⾏⼀位⼀位的读数⽽已。
if (cnt == 0)  // next byte?
//cnt为0表⽰⼀个8位的数组已经装满了,要换到下⼀个⼋位的数组上去,于是就把cnt复原为7,idx++让idx直到bits的下⼀个⼋位的数组上去。
{
cnt = 7;    // restart at MSB
idx++;      // next byte!
}
else cnt--;
//如果cnt不为0就表⽰这个⼋位的数据还没有读完,这时只需要让cnt-1,来填充下⼀位数据就可以了。
//注意,在初始化的过程中我们把这40位的数据都初始化为0了,所以只有当有1出现时才需要进⾏改变。
}
}
// WRITE TO RIGHT VARS
// as bits[1] and bits[3] are allways zero they are omitted in formulas.
//从开始的时候的原理中我们知道这40位数据第1个8位是湿度的整数部分,第3个8位是温度的整数部
分,下⾯这两句代码就是把数据分别放在这两个变量⾥了。
humidity    = bits[0];
temperature = bits[2];
97gabuint8_t sum = bits[0] + bits[2];
if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
return DHTLIB_OK;
//最后再⽤校验和验证⼀下数据是否正确。
}
//
// END OF FILE
//
六、运⾏结果
通电之后,在电脑上打开串⼝就可以看到采集到的温湿度信息。

本文发布于:2024-09-25 22:20:49,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/229320.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   采集   定义   代码   温湿度   电平
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议