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

来源:互联网 发布:数据库一致性错误 编辑:程序博客网 时间:2024/04/28 10:01

原理说明

原始的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
看看是不是有输出温度和湿度了。

    0 0
    原创粉丝点击