前些天写了篇文章是利用树莓派制作一个开关门监控设备的雏形《Python+树莓派 是谁在开门?》,但是这个设备运行的前提是需要树莓派正常供电并已经连接了网络,但是如果需要在没有电、没有宽带网络的户外实现随时掌控开关门的状态该怎么办?今天就和大家分享一个正在制作的物联网开关门监控设备。
因为考虑需要在户外使用这套物联网门控设备,所以利用树莓派完成这个设备有两个问题需要解决,
第一是需要解决树莓派和相关模块的供电问题。
第二就是需要户外没有宽带网络情况下的信号传输问题。
只要解决这两个问题那么剩下来的问题就是编程方面的了,针对以上两个问题,这里我们采用比较大众化的方式解决,设备的供电问题我们使用太阳能配合蓄电池进行实现7X24小时供电,信号的传输问题我们使用一块叫做SIM868的通讯模块来实现。下面来介绍一下设备制作的材料准备、制作过程以及程序的编写和调试。
1.准备材料及工具
1.树莓派(Raspberry Pi 3B) 数量:1块
2.SIM868通讯模块(这里使用的是适配树莓派的微雪电子的SIM868通讯模块) 数量:1块
3.电磁感应磁条(常开常闭型) 数量:1组
4.SIM868模块外接天线 数量:1根(根据现场安设实际情况确定)
5.树莓派T型扩展板 数量:1块
6.实验面包板 数量:1块
7.杜邦线(公对公,公对母) 数量:若干
8.太阳能板 数量:1块
9.带保护板的锂电池 数量:2组(根据电池使用的性能情况可适当增加)
10.电压电流转换板 数量:1块
11.连接电线 数量:(根据现场安设实际情况确定)
12.两芯屏蔽线 数量:10米(0.3粗即可根据现场安设实际情况确定)
13.防爆箱 (防尘、防雾) 数量:1个(规格根据实际情况确定)
14.Micro USB充电线 数量:2根
15.SIM卡(移动和联通均可,模块暂不支持电信CDMA) 数量:1张
16.电烙铁及焊锡
2.设备供电及模块链接说明
(1)供电原理:设备的供电依靠太阳能板配合锂电池进行供电,需要一块可以将太阳能板和锂电池的输出电压和电流转换成树莓派和SIM868通讯模块工作电压和电流的转换板,设备供电链接图如图。
实现效果,白天可以通过太阳能负责给树莓派及通讯模块供电并同时给锂电池充电。晚上将由充电完毕的锂电池负责给设备供电。
(2)设备链接:树莓派的GPIO PIN# 2针脚(5V)和 PIN# 23针脚 链接电磁感应模块的引线。负责接收电磁感应模块的开关状态,树莓派的GPIO PIN# 4(5V),PIN# 6(Ground) ,PIN# 8(TX),PIN# 10(RX)分别链接SIM868通讯模块的5V,ground,串口TX和RX,负责实现模块的树莓派与SIM868通讯模块的串口通讯和供电链接,并将信号树莓派的接收到的电磁感应磁条开关信号,通过SIM868通讯模块出输出去(这里采用的是http传输协议,具体实现方法见程序编码部分)
3.程序代码:
(1)python程序源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | import RPi.GPIO as GPIO import time import serial def gpio_init(): GPIO.setwarnings( False ) GPIO.setmode(GPIO.BOARD) GPIO.setup( 23 ,GPIO.OUT) def send_data(param): W_http_6 = 'AT+HTTPPARA="URL","http://**************/iot.php?status=' + param + '"\r\n' ser.write(W_http_6) time.sleep( 2 ) W_http_7 = 'AT+HTTPACTION=0\r\n' ser.write(W_http_7) time.sleep( 3 ) if __name__ = = '__main__' : ser = serial.Serial( "/dev/ttyS0" , 115200 ) W_http_1 = 'AT+HTTPTERM\r\n' ser.write(W_http_1) time.sleep( 3 ) W_http_2 = 'AT+SAPBR=3,1,"CONTYPE","GPRS"\r\n' ser.write(W_http_2) time.sleep( 3 ) W_http_3 = 'AT+SAPBR=3,1,"APN","CMNET"\r\n' ser.write(W_http_3) time.sleep( 3 ) W_http_4 = 'AT+SAPBR=1,1\r\n' ser.write(W_http_4) time.sleep( 3 ) W_http_5 = 'AT+HTTPINIT\r\n' ser.write(W_http_5) time.sleep( 3 ) gpio_init() status = 1 while True : if GPIO. input ( 23 ) = = True : if status = = 1 : send_data( 2 ) status = 2 print "门的状态:关闭" else : pass else : if status = = 2 : send_data( 1 ) status = 1 print "门的状态:打开" else : pass time.sleep( 3 ) GPIO.cleanup() |
(2)php程序源码:
1 2 3 4 5 6 7 8 | require_once ( "../../func/dbaccess.php" ); if (doConnect( $cn ) == false) { return false; } $strSQL = "insert into iot_tbl (position,status,create_time) values (" '.第一号门.' ",'" . $_GET [ 'status' ]. "',now())" ; doInsertUpdate( $strSQL ); doClose( $cn ); |
4.代码解析:
这里使用的Python版本号为2.7.9
1 2 3 | import RPi.GPIO as GPIO import time import serial |
引用了python的3个类库GPIO,time以及串口调试库serial,为实现程序的调试可编写,在使用serial串口调试库前,要实现树莓派的串口配置和Linux系统下的串口调试工具minicom的安装。具体方法可参考之前的文章《树莓派串口配置及minicom的安装》
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ser = serial.Serial( "/dev/ttyS0" , 115200 ) W_http_1 = 'AT+HTTPTERM\r\n' ser.write(W_http_1) time.sleep( 3 ) W_http_2 = 'AT+SAPBR=3,1,"CONTYPE","GPRS"\r\n' ser.write(W_http_2) time.sleep( 3 ) W_http_3 = 'AT+SAPBR=3,1,"APN","CMNET"\r\n' ser.write(W_http_3) time.sleep( 3 ) W_http_4 = 'AT+SAPBR=1,1\r\n' ser.write(W_http_4) time.sleep( 3 ) W_http_5 = 'AT+HTTPINIT\r\n' ser.write(W_http_5) time.sleep( 3 ) |
以上代码实在通过调用serial库,设置树莓派串口通信的波特率为115200,并使用 ser.write()函数向串口写入可操作SIM868模块进行通讯的AT指令,这里的AT指令是对SIM868进行HTTP通讯前的配置,具体AT指令的含义在这里不再赘述,可自行百度查找。这是使用time.sleep()函数控制程序执行的等待时间,确保串口写入数据成功。
1 2 3 4 | def gpio_init(): GPIO.setwarnings( False ) GPIO.setmode(GPIO.BOARD) GPIO.setup( 23 ,GPIO.OUT) |
gpio_init()函数是实现对接收电磁感应模块的GPIO PIN#23针脚的初始化配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | status = 1 while True : if GPIO. input ( 23 ) = = True : if status = = 1 : send_data( 2 ) status = 2 print "门的状态:关闭" else : pass else : if status = = 2 : send_data( 1 ) status = 1 print "门的状态:打开" else : pass time.sleep( 3 ) |
这里使用status变量初始化门的状态为1表示门已打开,并使用while True循环分割三秒钟(time.sleep(3))检测GPIO PIN#23 号针脚的电流状态,从而判断门的开关状态,并调用send_data()函数进行数据的发送。
1 2 3 4 5 6 7 | def send_data(param): W_http_6 = 'AT+HTTPPARA="URL","http://**************/iot.php?status=' + param + '"\r\n' ser.write(W_http_6) time.sleep( 2 ) W_http_7 = 'AT+HTTPACTION=0\r\n' ser.write(W_http_7) time.sleep( 3 ) |
这里将门的状态status变量的值当做参数传送给你个send_data()函数,在添加到HTTP请求的URL中,在服务器端写了个PHP程序iot.php(程序源码j解析如下)用以接收SIM868通讯模块发送过来的HTTP请求,并使用GET的方式获得到HTTP请求URL中传入的status值,并插入到MySQL数据库中。
1 2 3 4 5 6 7 8 | require_once ( "../../func/dbaccess.php" ); //封装链接操作MySQL数据库的函数 if (doConnect( $cn ) == false) { //链接数据库 return false; } $strSQL = "insert into iot_tbl (position,status,create_time) values (" '.第一号门.' ",'" . $_GET [ 'status' ]. "',now())" ; //将数据插入MySQL数据库的SQL语句 doInsertUpdate( $strSQL ); //执行SQL doClose( $cn ); //关闭数据库链接 |
4.程序拓展:
以上程序完成的是对开关门信号的检测、发送和接收数据,属于整个设备接收和处理数据的核心部分,对接收到的数据,还要做进一步的展示,这里我采用了HTML+JQuery+AJAX的方式,并配合在HTML中播放音频文件和刷新开关门状态图表,来动态展示开关门的效果。实现原理是使用AJAX操作PHP程序循环实时读取MySQL数据库,查看当前门的开关状态,并循环局部刷新HTML页面播放音频和刷新html页面图标,对门的开关效果进行动态展示。每个人的需求不同,展示部分的代码就不做说明,也参照上诉方案自行编写。
作者:高杆python
链接:http://www.jianshu.com/p/c470f2ab739d
门开关信号每触发一次都改变status的值,那么怎样才能准确监控到门状态是关闭还是打开?