您的位置:首页 > 编程语言 > Python开发

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

2017-03-02 16:59 525 查看

原理说明

原始的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模式。

具体通信的时序如下:

由于有上拉电阻存在,总线(DATA)空闲状态为高电平。
树莓派GPIO口设置为OUTPUT模式。
树莓派向DHT11发送起始信号。方式是GPIO口设置低电平并持续一段时间,根据数据手册的说明,这段时间必须大于18毫秒,保证DHT11能检测到起始信号。
树莓派起始信号输出完毕,切换到输入模式,等待DHT11响应。一旦切换到输入模式GPIO口就不再输出电平信号,总线处于释放状态,由于有上拉电阻的存在,总线被拉回高电平。
在总线被拉回至高电平通知DHT11主机已经准备好接受数据以后,DHT11还会继续等待20-40us左右以后才会开始发送反馈信号。
DHT11开始发送反馈信号,总线被DHT11拉低,持续80us左右。
这个持续了80us左右的低电平的反馈信号结束以后,DHT11又会将DATA口拉回高电平并再次持续80us左右。
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

看看是不是有输出温度和湿度了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: