树莓派3 dth11温度湿度 python代码。原理。

  • Post author:
  • Post category:python


原理说明

原始的DHT11模块有4根引脚,长成这个样子:




原始DHT11模块



由图可以看出4根引脚里除了VCC,GND,DATA以外,还有一个引脚是N/A,也就是不使用。(不使用引出来干嘛?好看吗?不解)


本文使用的是又被封装了一次的模块,去掉了无用的引脚。其他3个引脚保留。功能完全一样,所以如果你手头上的DHT11是有4根引脚的请忽略N/A针脚,其他的跟我使用的这种完全通用。3个针脚分别连接到3.3v电源,GND和任意GPIO口上。根据数据手册(文末提供下载)的说明,总线(DATA引脚)在空闲状态需要保持高电平状态,所以我们除了将DATA引脚接到一个GPIO口上,还要通过一个4.7K(经实测2K左右的就够了)的电阻将DATA引脚并联到VCC上。这个电阻也称上拉电阻,电阻就是一般的电阻,只是在这里起的作用是上拉电平的作用所以称之为上拉电阻。


与DHT11通信时,发送和接收信息都在一根DATA口上,这种只用1根总线的数据传输方式称为单总线模式。


向DHT11发送数据时,GPIO口需要设置为OUTPUT模式,从DHT11接收数据时GPIO口需要切换成INPUT模式。


具体通信的时序如下:

  1. 由于有上拉电阻存在,总线(DATA)空闲状态为高电平。
  2. 树莓派GPIO口设置为OUTPUT模式。
  3. 树莓派向DHT11发送起始信号。方式是GPIO口设置低电平并持续一段时间,根据数据手册的说明,这段时间必须大于18毫秒,保证DHT11能检测到起始信号。
  4. 树莓派起始信号输出完毕,切换到输入模式,等待DHT11响应。一旦切换到输入模式GPIO口就不再输出电平信号,总线处于释放状态,由于有上拉电阻的存在,总线被拉回高电平。
  5. 在总线被拉回至高电平通知DHT11主机已经准备好接受数据以后,DHT11还会继续等待20-40us左右以后才会开始发送反馈信号。
  6. DHT11开始发送反馈信号,总线被DHT11拉低,持续80us左右。
  7. 这个持续了80us左右的低电平的反馈信号结束以后,DHT11又会将DATA口拉回高电平并再次持续80us左右。
  8. DHT11开始正式传输40bit的二进制数据(0或1)。每一个bit的数据(0或者1)总是由一段持续50us的低电平信号开始,再由一段持续26us-28us(数据0)或者持续70us(数据1)的高电平结束。一直到40位数据传输完毕。这40位的数据内容是:


    8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据 + 8bit校验和。而校验和数据应该等于“湿度整数数据+湿度小数数据+温度整数数据+温度小数数据”所得结果的末8位。

    我们的程序就应该遵循上述时序来与DHT11进行数据通信。






建py代码:



输入 nano ./wendu.py



然后复制以下代码,注意

channel = 4 #gpi 4 是你插上树梅派的针脚,如果不知道插哪里,可以输入”gpio readall”查看针脚说明。










#!/usr/bin/python

import RPi.GPIO as GPIO

import time

while 1:

channel = 4 #gpi 4

data = []

j = 0

GPIO.setmode(GPIO.BCM)

time.sleep(1)

GPIO.setup(channel, GPIO.OUT)

GPIO.output(channel, GPIO.LOW)

time.sleep(0.02)

GPIO.output(channel, GPIO.HIGH)

GPIO.setup(channel, GPIO.IN)

while GPIO.input(channel) == GPIO.LOW:

continue

while GPIO.input(channel) == GPIO.HIGH:

continue

while j < 40:

k = 0

while GPIO.input(channel) == GPIO.LOW:

continue

while GPIO.input(channel) == GPIO.HIGH:

k += 1

if k > 100:

break

if k < 8:

data.append(0)

else:

data.append(1)

j += 1

#print “sensor is working.”

#print data

humidity_bit = data[0:8]

humidity_point_bit = data[8:16]

temperature_bit = data[16:24]

temperature_point_bit = data[24:32]

check_bit = data[32:40]

humidity = 0

humidity_point = 0

temperature = 0

temperature_point = 0

check = 0

for i in range(8):

humidity += humidity_bit[i] * 2 ** (7-i)

humidity_point += humidity_point_bit[i] * 2 ** (7-i)

temperature += temperature_bit[i] * 2 ** (7-i)

temperature_point += temperature_point_bit[i] * 2 ** (7-i)

check += check_bit[i] * 2 ** (7-i)

tmp = humidity + humidity_point + temperature + temperature_point

if check == tmp:

print “temperature :”, temperature, “*C, humidity :”, humidity, “%”

else:

print “wrong data:temperature :”, temperature, “*C, humidity :”, humidity, “% check :”, check, “, tmp :”, tmp

GPIO.cleanup()


保存后,输入chmod 777 ./wendu.py

然后输入python ./wendu.py

看看是不是有输出温度和湿度了。



版权声明:本文为bbs2003原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。