树莓派dht22(dht11)温度上传阿里云物联网

# -*- coding: utf-8 -*-
"""
Created on Sun Feb 10 23:45:55 2019

@author: wangz
"""

import paho.mqtt.client as mqtt
import time
import hashlib
import hmac
import random
import json
import Adafruit_DHT

options = {
    'productKey':'a1FCzW9xv1o',
    'deviceName':'temp',
    'deviceSecret':'o7H9e2dnusAD******',   # 保密故隐去
    'regionId':'cn-shanghai'
}

HOST = options['productKey'] + '.iot-as-mqtt.'+options['regionId']+'.aliyuncs.com'
PORT = 1883 
PUB_TOPIC = "/sys/" + options['productKey'] + "/" + options['deviceName'] + "/thing/event/property/post";


# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    # client.subscribe("the/topic")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

def hmacsha1(key, msg):
    return hmac.new(key.encode(), msg.encode(), hashlib.sha1).hexdigest()

def getAliyunIoTClient():
  timestamp = str(int(time.time()))
  CLIENT_ID = "paho.py|securemode=3,signmethod=hmacsha1,timestamp="+timestamp+"|"
  CONTENT_STR_FORMAT = "clientIdpaho.pydeviceName"+options['deviceName']+"productKey"+options['productKey']+"timestamp"+timestamp
  # set username/password.
  USER_NAME = options['deviceName']+"&"+options['productKey']
  PWD = hmacsha1(options['deviceSecret'],CONTENT_STR_FORMAT)
  client = mqtt.Client(client_id=CLIENT_ID, clean_session=False)
  client.username_pw_set(USER_NAME, PWD)
  return client


if __name__ == '__main__':
    
    while True:
       try:  
          
          client = getAliyunIoTClient()
          client.on_connect = on_connect
          client.on_message = on_message
  
          client.connect(HOST, 1883, 305)
          sensor=Adafruit_DHT.DHT22       # Adafruit_DHT.DHT11
          pin=21
          humidity,temperature=Adafruit_DHT.read_retry(sensor,pin)
          payload_json = {
                  'id': int(time.time()),
                  'params': {
                          'temperature': temperature,
                          'humidity': humidity     #random.randint(40, 50)     
                  },
                  'method': "thing.event.property.post"
          }
          print('send data to iot server: ' + str(payload_json))
          client.publish(PUB_TOPIC,payload=str(payload_json),qos=1)
          time.sleep(300)
       except Exception as e:   #异常处理
          print(e)

——————————————————————————————————————————————

阿里物联网部分,请参考如下链接:

https://www.yuque.com/cloud-dev/iot-tech/rz6fpl

——————————————————————————————————————————————

此处DHT22采用网上现成库,参考如下:

【树莓派驱动DHT22 - junjun++ - 博客园】https://www.cnblogs.com/junjun001/p/9335246.html?tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share

(1)输入以下命令,下载安装Adafruit提供的python驱动,

#sudo apt-get update

#sudo apt-get install build-essential python-dev

#git clone https://github.com/adafruit/Adafruit_Python_DHT.git

#cd Adafruit_Python_DHT

#sudo python setup.py install

如果出错,先输入如下:

pip install setuptools  或 pip3 install setuptools

————————————————————————————————————————

有对读取dht11温度感兴趣的也可学习下面的方法,不过不符合python人生苦短的做事原则。

引用高手的,未修改作者名称

#! /usr/bin/env python3
# encoding=utf-8
# power by : FUNCO_小风

import RPi.GPIO as GPIO
import time

# 延时函数
def delay(i):
    while i:
        i -= 1

# 初始化dht11连接引脚
# dht11_pin - dht11连接的引脚号
def init_dht11(dht11_pin):
    # 输出模式 初始状态给高电平
    GPIO.setup(dht11_pin, GPIO.OUT)
    GPIO.output(dht11_pin, 1)

# 用于获取
# dht11_pin - dht11连接的引脚号
# 返回二元组 [ 湿度 , 温度 ]
def get_dht11(dht11_pin):
    buff=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

    GPIO.output(dht11_pin,0)
    time.sleep(0.02)                    # 拉低20ms

    GPIO.output(dht11_pin,1)

    GPIO.setup(dht11_pin,GPIO.IN)        # 这里需要拉高20-40us,但更改模式需要50us,因此不调用延时


    while not GPIO.input(dht11_pin):    # 检测返回信号 检测到启示信号的高电平结束
        pass


    while GPIO.input(dht11_pin):        # 检测到启示信号的高电平则循环
        pass

    i=40

    while i:
        start=time.time()*1000000        # 为了严格时序 循环开始便计时
        i-=1
        while not GPIO.input(dht11_pin):   # 检测返回信号 检测到启示信号的高电平结束
            pass
        while GPIO.input(dht11_pin):
            pass
        buff[i]=time.time()*1000000-start# 为了严格时序 每次测得数据后都不马上处理 先存储
 
    GPIO.setup(dht11_pin,GPIO.OUT)        # 读取结束 复位引脚
    GPIO.output(dht11_pin,1)

    print ("buff - ",buff)

    # 开始处理数据
    for i in range(len(buff)):            # 将时间转换为 0 1
        if buff[i]>100:                    # 上方测试时是测试整个位的时间
                                        # 因此是与100比较 大于100为1(位周期中 低电平50us)
            buff[i]=1
        else:
            buff[i]=0
    print ("After - ",buff)
    i=40
    hum_int=0
    while i>32:                # 湿度整数部分
        i-=1
        hum_int<<=1
        hum_int+=buff[i]
    # print "hum - ",hum_int

    tmp_int=0
    i=24
    while i>16:                # 温度整数部分
        i-=1
        tmp_int<<=1
        tmp_int+=buff[i]
    # print "tmp - ",tmp_int
    return [hum_int,tmp_int]

GPIO.setmode(GPIO.BCM)
init_dht11(21)
print(get_dht11(21))
GPIO.cleanup()
# 注意
# 若非连续测量 可以不延时 但连续测量时建议每次测量间间隔0.2s以上再调用get_dht11(dht11_pin)获取数据(树莓派不稳定)
# DHT11虽然有40位 实际温度和湿度的小数部分读数总为0
# 如果程序无法正常读取,可以考虑是否起始部分的延时不准确,可以参考注释以及实际环境的测量结果调整延时
——————————————————————————————————————

一些dht11的硬件知识

DHT11的读写原理--一线制通信协议解析

转载2015-05-12 09:47:59

树莓派dht22(dht11)温度上传阿里云物联网_第1张图片DHT11硬件电路

    上图中,建议连接线长度短于20米时使用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻。

    DHT11温湿度传感器类似于DS18B20采用一线制通信协议,所谓一线制顾名思义,设备与上位控制器通信使用1根线,这根线同时承担了时钟和数据线的角色。​   ​

    硬件上的简单势必会带来软件上的复杂,像一线制通信协议,一般都是上位CPU先发开始、复位等电平信号,然后DHT11DS18B20发送回应信号,然后再发送对应数据,上位CPU接收电平脉冲信号,连续接收固定的字节,然后再进行解析数据。

     DHT11为例其协议如下图所示:

树莓派dht22(dht11)温度上传阿里云物联网_第2张图片

   首先主机发送开始信号(一定时间的低电平),然后再拉高延时等待(一定时间的高电平).​

   DHT11检测到主机的开始、延时信号后,要进行响应,首先是响应信号(一定时间的低电平),然后是延时准备输出信号(一定时间的高电平),然后每隔固定时间的低电平(间隔信号),具体的数据是不同间隔时间的(高电平)代表01,信号传输完成后,DHT11拉低电平。

    具体通信协议参数,如下图所示:

树莓派dht22(dht11)温度上传阿里云物联网_第3张图片

树莓派dht22(dht11)温度上传阿里云物联网_第4张图片

树莓派dht22(dht11)温度上传阿里云物联网_第5张图片

   综上所述,一线制通信设备的核心是精确的时钟信号下,进行按照协议标准进行通信,所以要求按照协议一步一步的进行读数。

 

你可能感兴趣的:(树莓派,物联网,python,温度传感器)