应某人需求,就发到这里来,说不定有人需要
这段代码用了两年了 暂时没发现多大问题
@2022_10 添加一个使用PYQT的方案,供参考
"""
-*- coding: utf-8 -*-
@Author : Link
@Time : 2022/10/21 11:34
@Site :
@File : event_serial.py
@Software: PyCharm
@Remark : 直接使用QT的信号和槽来操作
"""
import sys
from typing import Union
from PySide2.QtCore import QObject, QByteArray
from PySide2.QtSerialPort import QSerialPort, QSerialPortInfo
from PySide2.QtWidgets import QApplication
class EventRs232(QObject):
"""
无query写法
只有写, 和循环读, 读取的数据通过\n来触发事件
"""
connected: bool = False
device: QSerialPort = None
com: str = None
port: int = 115200
receive_data: str = ""
pause = False
def __init__(self, parent=None, **kwargs):
super(EventRs232, self).__init__(parent)
for key, value in kwargs.items():
setattr(self, key, value)
self.set_up_serial()
def __repr__(self):
return '<%s(%s)><connected? -%s>' % (self.device, self.com, self.connected)
def set_up_serial(self):
self.device = QSerialPort()
self.device.readyRead.connect(self.print)
def connect_serial(self):
self.device.setPortName(self.com)
self.device.setBaudRate(self.port)
if not self.device.open(QSerialPort.ReadWrite):
self.connected = False
print("串口打开失败!")
self.connected = True
def disconnect_serial(self):
self.device.close()
self.connected = False
def print(self):
try:
receive = bytes(self.device.readAll())
except Exception as err:
print(err)
return
# 要通过匹配到换行符后, 通过每一行的数据形式来做事件触发
self.receive_data += receive.decode('UTF-8')
split_data = self.receive_data.split("\n", 1)
if split_data.__len__() == 1:
return
else:
line_data = split_data[0]
self.receive_data = split_data[1]
"""
对line_data做处理后用信号来驱动
"""
print(line_data)
def write(self, data: Union[str, bytes]):
if isinstance(data, str):
b_data = data.encode("UTF-8")
else:
b_data = data
self.device.write(QByteArray(b_data))
if __name__ == '__main__':
app = QApplication(sys.argv)
stm32 = EventRs232(com="COM7")
stm32.connect_serial()
sys.exit(app.exec_())
@使用serail的方案, 可以参考
import serial
import time
from threading import RLock
lock = RLock()
from logger_moudle import logger
class RS232_Device():
connected = False
connection = None
busy = False
def __init__(self, device_name=None, com=None, port=19200,
request=False, hello=None, answer=None, termin=None,
timesleep=0.2):
'''
返回一个com连接对象
:param device_name: 设置设备名称
:param com: 设置com口
:param request: 设置是否握手:若 Ture,connected 握手后会改变为True
:param hello: 设置握手发送数据
:param answer: 设置握手返回数据
:param termin: 命令 自动加入结束符
'''
self.com = com
self.device_name = device_name
self.port = port
self.request = request
self.hello = hello
self.answer = answer
self.termin = termin
self.timesleep = timesleep
def __repr__(self):
return '<%s(%s)><connected? -%s>' % (self.device_name, self.com, self.connected)
def connect(self):
if not self.busy:
try:
self.connection = serial.Serial(self.com, self.port, bytesize=8, parity='N', stopbits=1, timeout=1)
if self.request == False:
self.connected = True
logger.warning('%s 打开成功,开启端口为%s,波特率为%s' % (self.device_name, self.com, self.port))
except serial.serialutil.SerialException as e:
self.busy = False
logger.warning('%s 打开失败,端口%s已被开启或无此端口,%s' % (self.device_name, self.com, str(e)))
if all((self.request, self.connection)):
if self.answer in self.query(self.hello).encode('utf-8'):
self.connected = True
logger.warning('%s 握手成功' % self.device_name)
else:
self.connected = False
logger.warning('%s 通讯失败,请确认端口连接及设备状态!' % self.device_name)
return self.connected
def open(self):
if self.connection:
try:
self.connection.open()
logger.warning('%s 打开成功,开启端口为%s,波特率为%s' % (self.device_name, self.com, self.port))
except serial.serialutil.SerialException as e:
self.busy = False
logger.warning('%s 打开失败,端口%s已被开启或无此端口,%s' % (self.device_name, self.com, str(e)))
def close(self):
if self.busy:
self.connection.close()
logger.info('%s 通讯成功关闭!' % self.device_name)
self.busy = False
self.connected = False
def get_in_waiting(self):
time.sleep(self.timesleep)
return self.connection.read(self.connection.in_waiting)
def _query(self, value):
with lock:
self.get_in_waiting()
if self.termin:
value += self.termin
self.connection.write(value.encode())
time.sleep(0.05)
data = self.get_in_waiting().decode('utf-8', 'ignore')
self.busy = False
return data
def query(self, value):
if self.busy:
time.sleep(0.05)
return self.query(value)
return self._query(value)
def _write(self, value):
with lock:
self.busy = True
self.get_in_waiting()
if self.termin:
value += self.termin
self.connection.write(value.encode())
time.sleep(0.05)
self.busy = False
def write(self, value):
if self.busy:
time.sleep(0.05)
return self.write(value)
return self._write(value)