DHT11测量温湿度
一、DHT11传感器介绍
1.1DHT11简介
DHT11温湿度传感器是一款含有已校准的数字信号输出的温湿度符合传感器,传感器包括一个电阻式感湿元件和一个NTC感温元件,并于一个高性能8位单片机相连接。像如下图这种都是内置了上拉电阻的,使用的时候不需要自己再接上拉电阻。
1.2DHT11工作原理
DHT11次啊用单总线通信。单总线即只有一根数据线,即为上图out引脚,主机对DHT11的数据交换和控制均由单总线完成。单总线通常要求外接一个约5.1k欧姆的上拉电阻,使得总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果序列混乱,器件将不响应主机。其原理图如下:注意NC引脚是不接出来的。DHT11的供电电压为3~5.5V。传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。
1.3DHT11通信时序
数据总时序 单片机发送一次开始信号后,DHT11从低功耗模式转换到告诉模式,待主机开始信号结束后,DHT11发送响应信号,并发送出5个字节的采样数据,之后结束本次采集任务。
主机发送起始信号 DHT11的out(data)引脚连接单片机GPIO引脚,总线空闲状态是高电平,主机GPIO把总线拉低(>=18ms),以保证DHT11能检测到起始信号,继续延时等待20~40us,切换到输入模式,等待并读取DHT11响应。
从机应答信号 DHT11接收到主机的开始信号后,等待主机发送开始信号到结束,然后向主机发送80us低电平响应信号,之后DHT11再把总线拉高80us,告诉主机准备发送数据。
高低电平的表示 我们要知道的是主机和从机的通信最基本的单位是位(bit),0和1,8个位为一字节,一个字节可以表示一个字符。那如何表示数字0和1呢?在这里,每一bit数据都以50us低电平时隙开始,而高电平的长短决定了数据位是0还是1,格式见下图。如果主机读取响应信号为高电平,则说明DHT11没有响应,检查线路是否正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
数字0信号表示方法:50us低电平+26~28us高电平
数字1信号表示方法:50us低电平+70us高电平
数据传输 DHT11在传输数据时,一次传输4个字节温湿度值数据和1字节的数据校验。其数据格式为:1B湿度整数数据+1B湿度小数数据+1B温度整数数据+1B温度小数数据+1B校验。不过目前温湿度的小数都还没用到。 一次性完整的数据传输为40bit,高位先出:MSB,即大端字节序,高位数存于低地址。 数据传送正确时校验和数据等于“1B湿度整数数据+1B湿度小数数据+1B温度整数数据+1B温度小数数据”所得结果的末8位。
二、DHT11温湿度采样实现
2.1接口说明:
DHT11传感器的工作电压范围为3~5.5V,因此接3.3V和5V都可以,此外将DHT11的I/O口接到单片机的某个GPIO管脚的上(我这里时PA5) 。对于没有内置上拉电阻的DHT11传感器,建议连接线长度短于20米时用5k上拉电阻,大于20米时根据实际情况使用合适上拉电阻。注意:如果传感器上有引脚为S,则表示信号引脚。
GPIO4和GPIO5分别通过跳线帽连接到OLED屏的SDA和SCL引脚。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // 128*64像素,逐行式
#define DHTPIN 14 //定义引脚D5
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup()
{
Serial.begin(115200);
dht.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // 扫描OLED的地址,默认0x3c
{
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
delay(2000);
display.clearDisplay(); // 清屏
display.setTextColor(WHITE); //开像素点发光
}
void loop()
{
delay(5000);
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(h) || isnan(t)) // 如果都没有采集到数据,则打印失败
{
Serial.println("Failed to read from DHT sensor!");
}
Serial.println(t, 2);
display.clearDisplay(); // 清屏
display.setTextSize(1); // 字体
display.setCursor(0, 0); //显示位置在第一行第一个
display.print("Temp: ");
display.setTextSize(2);
display.print(t);
display.print(" ");
display.setTextSize(1);
display.cp437(true); //使用cp437符号集
display.write(167); //对应的温度符号
display.setTextSize(2);
display.print("C"); // display humidity
display.setTextSize(1);
display.setCursor(0, 25);
display.print("Humi: ");
display.setTextSize(2);
display.print(h);
display.print(" %");
display.display();
}
结果: