Python 救救我!如何连接串口实现一个报警灯报警器

关于具体实现效果,在本文末尾会有效果演示,需要相关产品型号等信息可以私聊我获取,欢迎关注。

 

目录

1. 背景说明

2.环境物料准备

3.前期调试测试

3.1 硬件产品测试

3.2 Python串口调试

4.源码开发

5.打包

6.效果演示


1. 背景说明

我们一个项目已经在实施阶段,客户提出了一个新的要求:即在一个特定紧急情况下,在他们(客户)的电脑设备上连接一个报警器发出报警信号(报警灯闪光+发出蜂鸣警告)。

关于硬件的开发已经可以追溯到我的大学生活了,那时的我们刚开始时使用汇编和C做单片机开发,再往后一点使用C++进行ARM开发,最后使用Z-Stack做物联网开发。可以距今已经太遥远了,当初掌握的知识早已献祭给时间了。

这个小小的要求摆在我的面前,蛮大的压力,我必须攻克它,但是我也并不准备为了它付出很大的代价。所以我最后的决定是这样的:硬件设备部分,直接采购成型产品(暴露API或者类似串口之类的调用方式);软件部分,和服务端建立websocket连接,接收到服务端推送的紧急信息时,调用硬件发出报警信息。

2.环境物料准备

当我在某宝搜索关键词【报警灯 二次开发】、【报警灯 api】这样的关键词,找到的适合的产品寥寥,仅有的几个外形、价格都不让人满意,最后当把关键词换为【报警灯 串口 开发】之后,我找到了我想要的东西(售价60米)。内建USB转串口,提供相应的串口指令集。



火速网购,物流,快!硬件到手,为了开发简单,我准备使用Python进行串口通信和程序开发。

鉴于此次开发使用Python,特在此列出开发环境:

  1. Windows7 64

  2. Python3.6

  3. python依赖模块包括:websocket-client(websocket)、pyserial(串口)、pyinstaller(打包exe)

3.前期调试测试

3.1 硬件产品测试

首先需要测试一下收到的产品是否正常运行,并且可以使用串口发送指令控制。

第一步、将硬件设备的usb插口插入电脑

第二步、安装驱动:卖家提供了该驱动程序

第三步、找到具体串口号(右键计算机->管理->设备管理器->端口),我的串口是COM10(注意,此串口号不同设备会有不同,同设备不同插口也会有所不同)

第四步、使用产品附带控制软件进行测试,打开串口之后,测试无异常



3.2 Python串口调试

接下来进行使用Python控制该硬件的调试。

01 05 00 00 ff 00 8C 3A 打开红灯(常亮) 01 05 00 00 00 00 CD CA 关闭红色

01 05 00 03 ff 00 7C 3A 打开蜂鸣器(一直响) 01 05 00 03 00 00 3D CA 关闭蜂鸣器


01 05 00 00 f0 00 89 CA 红灯闪烁(2Hz)

01 05 00 00 f1 00 88 5A 红灯闪烁(1Hz)

01 05 00 00 f2 00 88 AA 红灯闪烁(0.5Hz)

01 05 00 00 f3 00 89 3A 红灯闪烁(0.25Hz)


01 05 00 03 f0 00 79 CA 蜂鸣器模式1(2Hz)

01 05 00 03 f1 00 78 5A 蜂鸣器模式2(1Hz)

01 05 00 03 f2 00 78 AA 蜂鸣器模式2(0.5Hz)

01 05 00 03 f3 00 79 3A 蜂鸣器模式2(0.25Hz)

该设备提供了上述指令集,并且串口和指令要求如下

串口设置: 9600,8,n,1。
控制命令,HEX格式发送(不能以ASCII格式发送)

Python实现Demo如下

import serial
import time

#### 串口号,右键计算机->点击设备->点击端口->查看获取
SERIAL_PORT = 'COM10'
ser=serial.Serial(SERIAL_PORT,9600,timeout=0.5)

######## 指令声明
## 红灯常亮
RED_LIGHT_CMD_ALWAYS = b'\x01\x05\x00\x00\xff\x00\x8C\x3A'
## 关闭红灯
RED_LIGHT_CMD_CLOSE = b'\x01\x05\x00\x00\x00\x00\xCD\xCA'
## 红灯闪烁2HZ
RED_LIGHT_CMD_2HZ = b'\x01\x05\x00\x00\xf0\x00\x89\xCA'
## 红灯闪烁1HZ
RED_LIGHT_CMD_1HZ = b'\x01\x05\x00\x00\xf1\x00\x88\x5A'
## 红灯闪烁0.5HZ
RED_LIGHT_CMD_0_5HZ = b'\x01\x05\x00\x00\xf2\x00\x88\xAA'
## 红灯闪烁0.25HZ
RED_LIGHT_CMD_0_25HZ = b'\x01\x05\x00\x00\xf3\x00\x89\x3A'
## 蜂鸣器常响
BUZZ_CMD_ALWAYS = b'\x01\x05\x00\x03\xff\x00\x7C\x3A'
## 关闭蜂鸣器
BUZZ_CMD_CLOSE = b'\x01\x05\x00\x03\x00\x00\x3D\xCA'
## 蜂鸣器模式2HZ
BUZZ_CMD_2HZ = b'\x01\x05\x00\x03\xf0\x00\x79\xCA'
## 蜂鸣器模式1HZ
BUZZ_CMD_1HZ = b'\x01\x05\x00\x03\xf1\x00\x78\x5A'
## 蜂鸣器模式0.5HZ
BUZZ_CMD_0_5HZ = b'\x01\x05\x00\x03\xf2\x00\x78\xAA'
## 蜂鸣器模式0.25HZ
BUZZ_CMD_0_25HZ = b'\x01\x05\x00\x03\xf3\x00\x79\x3A'

####
#   打开端口
####
def openSerial():
    if not ser.isOpen():
        ser.close()
        ser.open()
    print('成功连接到串口!')

####
#   向设备发送指令
####
def sendCmdToDevice(cmd, t=0.1):
    openSerial()
    ser.write(cmd)
    ##默认延时0.1秒,防止指令叠加发送导致指令失效,也可以控制指令持续时间,如希望红灯亮10秒,可传t=10
    time.sleep(t)
    ser.close()

if __name__ == '__main__':
    #sendCmdToDevice(RED_LIGHT_CMD_ALWAYS)
    sendCmdToDevice(RED_LIGHT_CMD_CLOSE)
    #sendCmdToDevice(RED_LIGHT_CMD_2HZ)
    #sendCmdToDevice(RED_LIGHT_CMD_1HZ)
    #sendCmdToDevice(RED_LIGHT_CMD_0_5HZ)
    #sendCmdToDevice(RED_LIGHT_CMD_0_25HZ)
    #sendCmdToDevice(BUZZ_CMD_ALWAYS)
    #sendCmdToDevice(BUZZ_CMD_CLOSE)
    #sendCmdToDevice(BUZZ_CMD_2HZ)
    #sendCmdToDevice(BUZZ_CMD_1HZ)
    #sendCmdToDevice(BUZZ_CMD_0_5HZ)
    #sendCmdToDevice(BUZZ_CMD_0_25HZ)

如上,对所有的指令进行16进制转换后,使用open函数打开端口,使用write函数向端口写指令,发送指令后close掉。对所有操作都测试无误后进入下阶段的开发。

4.源码开发

websocket的服务端使用Java开发,不再赘述。

接下来使用Python开发websocket客户端,监听到报警信息,调用设备发出报警。源码如下:

config.json

{
	"USER_ID": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
	"WARN_TIME": "3",
	"WEB_SOCKET_URL": "wss://{{DOMAIN}}/websocket/websocket/",
	"SERIAL_PORT": "COM10",
	"IF_BUZZ": "True"
}
  • USER_ID:用于区分socket的中的不同用户

  • WARN_TIME:警报持续时间(单位秒)

  • WEB_SOCKET_URL:websocket的服务端地址

  • SERIAL_PORT:串口号

  • IF_BUZZ:是否开启蜂鸣警报(True/False)

daemon.py

import websocket
import threading
import time
import serial
import json

#### 读取配置文件
jsonConfigStr = ''
with open("config.json", "r") as f:
    jsonConfigStr = f.read()
configData = json.loads(jsonConfigStr)

#### !!!!用户ID
DEPT_ID = configData['USER_ID']
#### !!!!警报持续时长(秒)
WARN_TIME = int(configData['WARN_TIME'])
WEB_SOCKET_URL = configData['WEB_SOCKET_URL']
WS_URL = WEB_SOCKET_URL + DEPT_ID + '-' + str(int(time.time()))

#### !!!!串口号,右键计算机->点击设备->点击端口->查看获取
SERIAL_PORT = configData['SERIAL_PORT']
ser=serial.Serial(SERIAL_PORT,9600,timeout=0.5)

#### !!!!是否开启蜂鸣
IF_BUZZ = configData['IF_BUZZ'] == 'True'

######## 指令声明
## 红灯常亮
RED_LIGHT_CMD_ALWAYS = b'\x01\x05\x00\x00\xff\x00\x8C\x3A'
## 关闭红灯
RED_LIGHT_CMD_CLOSE = b'\x01\x05\x00\x00\x00\x00\xCD\xCA'
## 红灯闪烁2HZ
RED_LIGHT_CMD_2HZ = b'\x01\x05\x00\x00\xf0\x00\x89\xCA'
## 红灯闪烁1HZ
RED_LIGHT_CMD_1HZ = b'\x01\x05\x00\x00\xf1\x00\x88\x5A'
## 红灯闪烁0.5HZ
RED_LIGHT_CMD_0_5HZ = b'\x01\x05\x00\x00\xf2\x00\x88\xAA'
## 红灯闪烁0.25HZ
RED_LIGHT_CMD_0_25HZ = b'\x01\x05\x00\x00\xf3\x00\x89\x3A'
## 蜂鸣器常响
BUZZ_CMD_ALWAYS = b'\x01\x05\x00\x03\xff\x00\x7C\x3A'
## 关闭蜂鸣器
BUZZ_CMD_CLOSE = b'\x01\x05\x00\x03\x00\x00\x3D\xCA'
## 蜂鸣器模式2HZ
BUZZ_CMD_2HZ = b'\x01\x05\x00\x03\xf0\x00\x79\xCA'
## 蜂鸣器模式1HZ
BUZZ_CMD_1HZ = b'\x01\x05\x00\x03\xf1\x00\x78\x5A'
## 蜂鸣器模式0.5HZ
BUZZ_CMD_0_5HZ = b'\x01\x05\x00\x03\xf2\x00\x78\xAA'
## 蜂鸣器模式0.25HZ
BUZZ_CMD_0_25HZ = b'\x01\x05\x00\x03\xf3\x00\x79\x3A'

####
#   延时
####
def delay(s):
    try:
        time.sleep(s)
    except:
        delay(s)

####
#   打开端口
####
def openSerial():
    if not ser.isOpen():
        ser.close()
        ser.open()
    print('成功连接到串口!')

####
#   向设备发送指令
####
def sendCmdToDevice(cmd, t=0.1):
    openSerial()
    ser.write(cmd)
    delay(t)
    ser.close()

#####
#   心跳线程
#####
class heartBeatThread (threading.Thread):
    def __init__(self, ws):
        threading.Thread.__init__(self)
        self.ws = ws
    def run(self):
        while True:
            ws.send('ping')
            print('ping!')
            delay(3)

#####
#   警报线程:红灯2HZ闪烁
#####
class warnThread (threading.Thread):
    def __init__(self, ws):
        threading.Thread.__init__(self)
        self.ws = ws
    def run(self):
        sendCmdToDevice(RED_LIGHT_CMD_2HZ)
        if IF_BUZZ:
            sendCmdToDevice(BUZZ_CMD_2HZ)
        delay(WARN_TIME)
        sendCmdToDevice(RED_LIGHT_CMD_CLOSE)
        if IF_BUZZ:
            sendCmdToDevice(BUZZ_CMD_CLOSE)

###
#   websocket-client:接受消息回调
###
def on_message(ws, message):
    if 'warninfo' in message:
      	print('检测到报警信息')
        warnThread(ws).start()
    else:
        print(message)

###
#   websocket-client:发生错误回调
###
def on_error(ws, error):
    print("链接出现错误")

###
#   websocket-client:链接断开回调
###
def on_close(ws):
    print("链接已经断开")

###
#   websocket-client:链接建立回调
###
def on_open(ws):
    print('检测到链接建立')
    heartBeatThread(ws).start()
    

if __name__ == '__main__':
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(WS_URL, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close)
    try:
        ws.run_forever()
    except:
        ws.close()

 

截止到此,开发全部完成

以上涉及到的源码其实还是有不足和缺陷的,如果你发现的话,不妨在讨论区交流哦~

5.打包

pyinstaller -D -i i.ico daemon.py

在dist下生成了可执行文件和相关依赖

6.效果演示





收到报警信息后红灯闪烁并蜂鸣,点击查看视频效果

已标记关键词 清除标记
简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始化一个EJB实例 5个目标文件,演示Address EJB的实现 ,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口函数得到远程接口的引用,用远程接口的引用访问EJB。 EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上直接地使用它,但是它的主要作用是供程序使用的。本规范尝试满足大型主机、微型主机、个人工作站、和TACs 的不同需求。例如,容易实现协议的设计。 Java EJB中有、无状态SessionBean的两个例子 两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密   Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。   设定字符串为“张三,你好,我是李四”   产生张三的密钥对(keyPairZhang)   张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节   通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥   Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从文件中得到公钥编码的字节数组、如何从字节数组解码公钥。 Java数据压缩与传输实例 1个目标文件 摘要:Java源码,文件操作,数据压缩,文件传输   Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲
相关推荐
程序员的必经之路! 【限时优惠】 现在下单,还享四重好礼: 1、教学课件免费下载 2、课程案例代码免费下载 3、专属VIP学员群免费答疑 4、下单还送800元编程大礼包 【超实用课程内容】  根据《2019-2020年中国开发者调查告》显示,超83%的开发者都在使用MySQL数据库。使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能!   套餐中一共包含2门MySQL数据库必学的核心课程(共98课时)   课程1:《MySQL数据库从入门到实战应用》   课程2:《高性能MySQL实战课》   【哪些人适合学习这门课程?】  1)平时只接触了语言基础,并未学习任何数据库知识的人;  2)对MySQL掌握程度薄弱的人,课程可以让你更好发挥MySQL最佳性能; 3)想修炼更好的MySQL内功,工作中遇到高并发场景可以游刃有余; 4)被面试官打破沙锅问到底的问题问到怀疑人生的应聘者。 【课程主要讲哪些内容?】 课程一:《MySQL数据库从入门到实战应用》 主要从基础篇,SQL语言篇、MySQL进阶篇三个角度展开讲解,帮助大家更加高效的管理MySQL数据库。 课程二:《高性能MySQL实战课》主要从高可用篇、MySQL8.0新特性篇,性能优化篇,面试篇四个角度展开讲解,帮助大家发挥MySQL的最佳性能的优化方法,掌握如何处理海量业务数据和高并发请求 【你能收获到什么?】  1.基础再提高,针对MySQL核心知识点学透,用对; 2.能力再提高,日常工作中的代码换新貌,不怕问题; 3.面试再加分,巴不得面试官打破沙锅问到底,竞争力MAX。 【课程如何观看?】  1、登录CSDN学院 APP 在我的课程中进行学习; 2、移动端:CSDN 学院APP(注意不是CSDN APP哦)  本课程为录播课,课程永久有效观看时长 【资料开放】 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化。  下载方式:电脑登录课程观看页面,点击右侧课件,可进行课程资料的打包下载。
<p> <strong><span style="font-size:16px;color:#003399;">手工测试中遇到的坑 你踩过几个?</span></strong><strong><span style="font-size:16px;color:#003399;"></span></strong> </p> <p> <br /> </p> <p> <img src="https://img-bss.csdnimg.cn/202012171208356126.png" alt="" /> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">解锁自动化测试技能 打破手工测试局限</span></strong> </p> <p> <br /> </p> <p> <span style="font-size:14px;">自动化测试是测试工作的一部分,是对手工测试的一种补充。自动化测试是相对手工测试而存在的,通过所开发</span><span style="font-size:14px;">的软件测试工具、脚本等来实现,具有良好的可操作性、可重复使用和高效率等特点。</span> </p> <p> <span style="font-size:14px;"><br /> </span> </p> <p> <span style="font-size:14px;"><img src="https://img-bss.csdnimg.cn/202012171212024924.png" alt="" /><br /> </span> </p> <p> <span style="font-size:14px;"><br /> </span> </p> <p> <br /> </p> <p> <br /> </p> <p> <span style="font-size:16px;color:#003399;"><strong>Python自动化测试</strong></span> </p> <p> <span style="font-size:14px;"><strong><span style="font-size:16px;color:#003399;">系统教学+实战分析 简单易上手</span></strong><strong><span style="font-size:16px;color:#003399;"></span></strong><strong><span style="font-size:16px;color:#003399;"></span></strong><br /> </span> </p> <p> <span style="font-size:14px;"><br /> </span> </p> <p> <span style="font-size:14px;">课程使用的是语法简洁、提供丰富的测试库和框架的Python语言,并从测试人员的角度,梳理当前最热门的自动化测试框架和常用库,并通过实战,带你快速建立自动化测试技术体系,让测试工作更高效!<br /> </span> </p> <p> <span style="font-size:14px;"><br /> </span> </p> <p> <span style="font-size:14px;"><img src="https://img-bss.csdnimg.cn/202012171223546601.png" alt="" /><br /> </span> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">3个项目实战</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">全程手敲代码演示 听得懂 更要会用</span></strong><strong><span style="font-size:16px;color:#003399;"></span></strong> </p> <p> <br /> </p> <p> <img src="https://img-bss.csdnimg.cn/202012171224069333.png" alt="" /> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">3大购课福利</span></strong> </p> <p> <br /> </p> <p> <img src="https://img-bss.csdnimg.cn/202012180149359103.png" alt="" /> </p>
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付 39.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值