# -*- 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
上图中,建议连接线长度短于20米时使用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻。
DHT11温湿度传感器类似于DS18B20采用一线制通信协议,所谓“一线制”顾名思义,设备与上位控制器通信使用1根线,这根线同时承担了时钟和数据线的角色。
硬件上的简单势必会带来软件上的复杂,像一线制通信协议,一般都是上位CPU先发开始、复位等电平信号,然后DHT11或DS18B20发送回应信号,然后再发送对应数据,上位CPU接收电平脉冲信号,连续接收固定的字节,然后再进行解析数据。
以DHT11为例其协议如下图所示:
首先主机发送开始信号(一定时间的低电平),然后再拉高延时等待(一定时间的高电平).
DHT11检测到主机的开始、延时信号后,要进行响应,首先是响应信号(一定时间的低电平),然后是延时准备输出信号(一定时间的高电平),然后每隔固定时间的低电平(间隔信号),具体的数据是不同间隔时间的(高电平)代表0和1,信号传输完成后,DHT11拉低电平。
具体通信协议参数,如下图所示:
综上所述,一线制通信设备的核心是精确的时钟信号下,进行按照协议标准进行通信,所以要求按照协议一步一步的进行读数。