使用温湿度传感器DHT11和光敏传感器在树莓派上使用itchat库实现微信自动回复当前温湿度和光照信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stynis/article/details/80522391

一、目的:

1.用python实现DHT11的驱动实现
2.使用itchat封装库实现微信回复当前温湿度

二、内容和原理:

树莓派本身集成了RPI.GPIO控制库,实验中直接使用RPI.GPIO控制库函数实现管脚的分配和控制。

1.RPI.GPIO库
1.1导入RPI.GPIO模块
使用以下代码导入RPI.GPIO模块

import RPi.GPIO as GPIO

引入之后,就可以使用GPIO模块的函数了,可以使用以下代码来测试是否引入成功:

try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("import failed")

1.2针脚编号
在RPi.GPIO中,同时支持树莓派上的两种GPIO引脚编号。第一种编号是BOARD编号,这和树莓派电路板上的物理引脚编号相对应。使用这种编号的好处是,你的硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在电路板升级后,你不需要重写连接器或代码。
第二种编号是BCM规则,是更底层的工作方式,它和Broadcom的片上系统中信道编号相对应。在使用一个引脚时,你需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件也可能是无法通用的。
你可以使用下列代码(强制的)指定一种编号规则:

GPIO.setmode(GPIO.BOARD) #BOARD mode
GPIO.setmode(GPIO.BCM)   #BCM mode

BCM映射对应GPIO编号,BOARD对应针脚序号。
1.3警告
如果RPi.GRIO检测到一个引脚已经被设置成了非默认值,那么你将看到一个警告信息。你可以通过下列代码禁用警告:

GPIO.setwarnings(False)

1.4引脚设置
在使用一个引脚前,你需要设置这些引脚作为输入还是输出。配置一个引脚的代码如下:

# 将引脚设置为输入模式
GPIO.setup(channel, GPIO.IN)

# 将引脚设置为输出模式
GPIO.setup(channel, GPIO.OUT)

# 为输出的引脚设置默认值
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

1.5释放
一般来说,程序到达最后都需要释放资源,这个好习惯可以避免偶然损坏树莓派。释放脚本中的使用的引脚:

GPIO.cleanup()
注意,GPIO.cleanup()只会释放掉脚本中使用的GPIO引脚,并会清除设置的引脚编号规则。

1.6输出
要想点亮一个LED灯,或者驱动某个设备,都需要给电流和电压他们,这个步骤也很简单,设置引脚的输出状态就可以了,代码如下:

GPIO.output(channel, state)

状态可以设置为0 / GPIO.LOW / False / 1 / GPIO.HIGH / True。如果编码规则为,GPIO.BOARD,那么channel就是对应引脚的数字。
如果想一次性设置多个引脚,可使用下面的代码:

chan_list = [11,12]
GPIO.output(chan_list, GPIO.LOW)
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW))

还可以使用Input()函数读取一个输出引脚的状态并将其作为输出值,例如:

GPIO.output(12, not GPIO.input(12))

1.7读取
常常需要读取引脚的输入状态,获取引脚输入状态如下代码:

GPIO.input(channel)

低电平返回0 / GPIO.LOW / False,高电平返回1 / GPIO.HIGH / True。
如果输入引脚处于悬空状态,引脚的值将是漂动的。换句话说,读取到的值是未知的,因为它并没有被连接到任何的信号上,直到按下一个按钮或开关。由于干扰的影响,输入的值可能会反复的变化。
使用如下代码可以解决问题:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  # or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

需要注意的是,上面的读取代码只是获取当前一瞬间的引脚输入信号。
如果需要实时监控引脚的状态变化,可以有两种办法。最简单原始的方式是每隔一段时间检查输入的信号值,这种方式被称为轮询。如果你的程序读取的时机错误,则很可能会丢失输入信号。轮询是在循环中执行的,这种方式比较占用处理器资源。另一种响应GPIO输入的方式是使用中断(边缘检测),这里的边缘是指信号从高到低的变换(下降沿)或从低到高的变换(上升沿)。

2 itchat
2.1 环境的搭建
在树莓派联网的情况下,可以直接使用命令安装itchat:

import itchat

@itchat.msg_register(itchat.content.TEXT)
def text_reply(msg):
    return msg.text

itchat.auto_login()
itchat.run()

三、主要仪器设备:
VMware Ubuntu
树莓派2b
DHT11传感器
安装了微信的智能手机一部
USB无线网卡一枚
带HDMI的显示器

四、操作方法和实验步骤:
1首先完成DHT11传感器的python代码实现,由于已经有过C语言的编写经验,并且有RPI.GPIO库函数的简化操作,代码实现简洁了很多。实现代码如下:

channel = 5            #pin 16  
data = []           #temperature and humidity  
j = 0               #counter  

GPIO.setmode(GPIO.BCM)      #BCM mode  

time.sleep(1)           #delay 1s 

GPIO.setup(channel, GPIO.OUT)  

GPIO.output(channel, GPIO.LOW)  
time.sleep(0.02)        #remind the sensor to work 
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]        #divide into groups  
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)              #trans to Decimal 
    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       #add Decimal datas  

if check == tmp:                                #check data, if equals than output  
    print "temperature : ", temperature, ", humidity : " , humidity  
else:                                       #ouput the wrong message  
    print "wrong"  
print "temperature : ", temperature, ", humidity : " , humidity, " check : ", check, " tmp : ", tmp
GPIO.cleanup()

2 利用微信传送温湿度数据
先安装itchat包,由于树莓派使用网线与电脑连接,利用电脑ssh登陆树莓派操作时,树莓派无法连上因特网(只能实现电脑和树莓派之间的通信,却无法连上因特网),所以使用无线网卡让树莓派连接上手机开的热点,这样就可以连接上因特网了。
使用sudo pip itchat可以直接实现安装。
实现的目的如下:利用python登陆微信,之后向登陆账号发送文本信息,则登陆账户自动回复当前温湿度的数值。
为了实现以上功能,可以使用itchat.auto_login(hotReload=True)来简化登陆操作,这样登陆可以免去每次加载二维码的时间,可以直接在微信上收到登陆确认。
将驱动所得数据进行转化,使用字符串连接的方法,可以在回复中发送当前温湿度。
框架如下:

humi = str(humidity)
temper = str(temperature)
checki = str(check)
tmpi = str(tmp)
@itchat.msg_register(itchat.content.TEXT)
def tuling_reply(msg):
    defaultReply = 'yourtext '
    return defaultReply
itchat.run()

3 协同实现
以每次向登陆账号发送信息为触发事件,重新读取温湿度数据,并回复温湿度数据。则需要将读取温湿度数据的过程嵌套在自动回复的函数里,并将计算得出的int数据转化为字符串从而成为文本信息回复发送的用户。
由于python运行需要一定的时间,虽然写起来简介但在准确度的把握上不如C精准,所以计算读取DHT11的数据并进行换算中的过程可能会出错,之前略去的校验此时就显得有必要了,如果错误,则需要重新读取。
完整实现代码如下:

#python
import RPi.GPIO as GPIO  
import itchat
import time  

itchat.auto_login(hotReload=True) 
#no need to scan QRcode again once login

@itchat.msg_register(itchat.content.TEXT)#autoreply when get any msg
def tuling_reply(msg):
    channel = 5            #pin 5  
    data = []           #temperature and humidity  
    j = 0               #counter  

    GPIO.setmode(GPIO.BCM)      #BCM mode  

    time.sleep(1)           #delay 1s 

    GPIO.setup(channel, GPIO.OUT)  

    GPIO.output(channel, GPIO.LOW)  
    time.sleep(0.02)        #remind the sensor to work 
    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]        #divide into groups  
    humidity_point_bit = data[8:16]  
    temperature_bit = data[16:24]  
    temperature_point_bit = data[24:32]  
    check_bit = data[32:40]  
    #trans these int datas to string so can be sent as text
    humidity = 0  
    humidity_point = 0  
    temperature = 0  
    temperature_point = 0  
    check = 0  

    for i in range(8):  
        humidity += humidity_bit[i] * 2 ** (7 - i)              #trans to Decimal 
        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       #add Decimal datas 

    GPIO.setup(26,GPIO.IN) #detect if the light is on
    humi = str(humidity)
    temper = str(temperature)  
    checki = str(check)
    tmpi = str(tmp)
    if check == tmp:                                #check data, if equals than output  
        print "temperature : ", temperature, ", humidity : " , humidity 
        if GPIO.input(26) == 0:
            defaultReply = 'temperature: ' + temper + 'C humidity: ' + humi + '% light is ON'
        else :
            defaultReply = 'temperature: ' + temper + 'C humidity: ' + humi + '% light is OFF'
    else:                                       #ouput the wrong message  
        print "wrong"  
        print "temperature : ", temperature, ", humidity : " , humidity, " check : ", check, " tmp : ", tmp
        defaultReply = 'WRONG! Please try again. '    
    GPIO.cleanup()   
    return defaultReply
itchat.run()

运行程序后提示登陆成功后,后显示start auto replying,则可以使用微信发送任意文本信息给登陆账号,可以自动得到温湿度和光照的回复信息。示意图如下:


注:DHT11驱动代码参考网上已有python代码,itchat库函数详见itchat说明。

猜你喜欢

转载自blog.csdn.net/Stynis/article/details/80522391