玩转树莓派入门系列——4.传感器系列之温湿度DHT11

玩转树莓派入门系列——4.传感器系列之温湿度模块DHT11

一、DHT11介绍

1、DHT11和DHT22

一般的温湿度传感器有DHT11和DHT22,两者的差别在与价格与精确度。DHT11便宜但精度范围大,DHT22贵但精度范围小。
在这里插入图片描述

2、引脚说明

a) VDD 供电3.3-5.5V DC
b) DATA串行数据,单设备
c) NC 空脚
d) GND 接地,电源负极

3、参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、通信原理

DHT11器件只有一根数据线,即单总线通信,所以对于时序要求比较大。由于DHT11是主从结构,所以只有当主机发起通信请求时,从机才会开始应答。
数据格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位

a、起始信号:
主机把SDA(数据总线)拉低18ms
b、响应信号:
从机把SDA拉低83us,再拉高87us响应起始信号
c、数据信号:
“0”的格式为:54微秒的低电平+23到27微秒的高电平
“1”的格式为:54微秒的低电平+68到74微秒的高电平
d、结束信号:
从机的DATA引脚输出40位数据后,继续输出54微秒的低电平后转换为输入状态。
e、数据格式:
收到主机信号后,从机一次性从SDA串出40bit,高位先出
f、温度:
高位为温度整数部分,低位为温度小数部分
g、湿度:
高位为温度整数部分,低位为湿度小数部分
低位第8位1表示负温度,否则位正温度
h、校验位:
校验位=湿度高位+湿度低位+温度高位+温度低位

5、时序图

在这里插入图片描述

a、步骤一:

DHT11上电后,要等待超过1s时间等待电平稳定,同时DHT11的SDA处于高电平,DATA引脚处于输入状态,时刻监测外部信号。

b、步骤二:

主机发送低电平,拉低SDA电平,至少超过18ms(最大不超过30ms),然后主机拉高电平,等待从机做出应答信号。
在这里插入图片描述

c、步骤三:

DHT11的DATA引脚监测到起始信号后,等待起始信号结束,再输出83微秒的低电平作为应答信号,然后输出87微秒的高电平通知外设准备接收数据,然后主机的IO口就处于输入状态等待数据接收。
在这里插入图片描述

d、步骤四:

主机开始接收40位的数据,
“0”的格式为:54微秒的低电平+23到27微秒的高电平
“1”的格式为:54微秒的低电平+68到74微秒的高电平
在这里插入图片描述

e、步骤五:

结束信号,DHT11的DATA引脚输出40位数据后,继续输出54微秒的低电平后转换为输入状态。

二、DHT11接入树莓派4B

刚买回来的DHT11模块集成在一块板子上,提供三个引脚:VCC、DATA和GND。很明显,VCC接3.3V电源,GND接地,DATA引脚接入GPIO口,从树莓派4b的GPIO引脚图。我们把VCC接1脚,DATA接7脚,GND接9脚,其中DATA脚对应GPIO.7(BCM为4,WiringPi为7)。
在这里插入图片描述

在这里插入图片描述

三、DHT11读取数据

1、通过系统功能读取

树莓派有一个Device Tree(DT)功能,即在/boot/overlays发现外设,并加载到系统上去,其操作只要在/boot/config.txt进行对应的外设配置,重启后,就可以在/sys/devices下找对对应的外设。
修改/boot/config.txt

dtparam=i2c_arm=on
dtparam=spi=on
dtoverlay=dht11

重启

reboot

采集数据

DHT11Path="/sys/devices/platform/dht11@4/iio:device0"
HumidityRelative=$(awk '{print $1 / 1000 }' ${DHT11Path}/in_humidityrelative_input)
RoomTemp=$(awk '{print $1 / 1000 }' ${DHT11Path}/in_temp_input)

这个方法经常因为1-write协议本身的缘故,1bit数据丢失,就会导致数据无法读出。
解决方法只能通过多次读值,取正常值。

2、通过Adafruit库读取

更新源软件包

apt update
apt upgrade
apt install build-essential python-dev python3-dev python-pip python3-pip

获取Adafruit库

apt install git
sudo git clone https://github.com/adafruit/Adafruit_Python_DHT.git

修改Adafruit对树莓派4B的支持

vi Adafruit_Python_DHT/Adafruit_DHT/platform_detect.py
#在elif match.group(1) == 'BCM2837': > #Pi 3b+ >return 3后面加入新的分支
elif match.group(1) == 'BCM2711':#Pi 4Breturn 3

安装Adafurit库

python setup.py install
python3 setup.py install

执行demo获取温湿度

#11代表DHT11,4代表gpio4
python AdafruitDHT.py 11 4
#或
python3 AdafruitDHT.py 11 4

3、通过C编程读取

#include 
#include 
#include 
#include #include typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;uint32 databuf;/*
//初始化引脚
//上电1s内不操作,维持电平稳定
*/
void GPIO_init(int gpio_pin)
{pinMode(gpio_pin, OUTPUT); // set mode to outputdigitalWrite(gpio_pin, 1); // output a high levelsleep(1);return;
}/*
//起始信号1.主机初状态是高电平,要超过1s稳定电平2.主机再拉低延时18ms-30ms3.主机末状态是高电平,等待
*/
void DHT11_start(int gpio_pin)
{	pinMode(gpio_pin, OUTPUT);digitalWrite(gpio_pin, 0);delay(25);digitalWrite(gpio_pin, 1);pinMode(gpio_pin, INPUT);pullUpDnControl(gpio_pin, PUD_UP);	//当引脚被配置为输入(INPUT)模式,使用函数pullUpDnControl来激活其内部的上拉电阻或下拉电阻delayMicroseconds(27);return;
}/*
//主机接受数据1.主机接受到从机回复的响应信号2.格式0——54us的低电平+23到27us的高电平格式1——54us的低电平+68到74us的高电平3.思路:从识别到低电平开始,然后去除掉掉前面54秒的低电平还有
*/
uint8 DHT11_read(int gpio_pin)
{uint8 crc, i;if (0 == digitalRead(gpio_pin))			//主机接收到从机发送的响应信号(低电平){while(!digitalRead(gpio_pin));		//主机接收到从机发送的响应信号(高电平)for (i = 0; i < 32; i++){while(digitalRead(gpio_pin));	//数据位开始的54us低电平while(!digitalRead(gpio_pin));	//数据位开始的高电平就开始delayMicroseconds(32);			//跳过位数据,32us已经是数据0和数据1的差距点databuf *= 2;if (digitalRead(gpio_pin) == 1){databuf++;}}for (i = 0; i < 8; i++){while (digitalRead(gpio_pin));while (!digitalRead(gpio_pin));delayMicroseconds(32);crc *= 2;  if (digitalRead(gpio_pin) == 1){crc++;}}return 1;}else{return 0;}
}int main(int argc, char *argv[])
{if (2 != argc){printf("Usge: %s \n", argv[0]);return 0;}if (-1 == wiringPiSetup()){printf("Setup WiringPi failed!\n");return 1;}while(1){GPIO_init(atoi(argv[1]));DHT11_start(atoi(argv[1]));if (DHT11_read(atoi(argv[1]))){printf("RH:%d.%d\n", (databuf >> 24) & 0xff, (databuf >> 16) & 0xff); printf("TMP:%d.%d\n", (databuf >> 8) & 0xff, databuf & 0xff);databuf = 0;}else{printf("Sensor dosent ans!\n");databuf = 0;}sleep(3);}return 0;
}

编译执行
这里要用sudo权限,并且引脚值要对应好,GPIO-7的Wiring值对应7

gcc -o DHT DHT11.c  -lwiringPi
sudo ./DHT 7

4、通过Python编程读取

对Python不熟,暂时无输出。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部