想用Python+QT做个串口数据解析的工具,于是有了下面这些东西
随便拿个北斗模块测试下
串口功能是基于pyserial库实现的
pyserial库文档链接
英语不好可以用浏览器翻译插件辅助(没错就是本人)
pip安装pyserial
pip install pyserial
然后导入
import serial
import serial.tools.list_ports
from serial import PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE, STOPBITS_ONE, \
STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
使用pyserial的工具类获取串口列表
def get_serial():
__plist = list(serial.tools.list_ports.comports())
__ports = [p.name for p in __plist]
return __ports
获取到串口列表之后便可以选择串口进行设置及打开
先看文档
可以通过Serial()进行设置串口参数
可以在创建对象是设置,也可以在创建对象完成之后再进行设置,此处采取第二种方式
因为是与界面进行结合使用,所以参数大多在界面选择,这里只做为默认初始化使用
参数设置完成后可通过open()方法打开串口
代码如下
class SerialPort:
def __init__(self):
self.__serial_list = get_serial()
self.ser = serial.Serial() # pyserial串口对象
self.port = None # 端口选择
self.bps = 6 # 波特率选择
self.byte_size = 3 # 数据位选择
self.parity = 0 # 校验位选择
self.stop_bits = 0 # 停止位选择
self.flow_control = 0 # 流控选择
# 连接串口
def connect_serial(self):
# 校验位
serial_parity = [PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE]
serial_stopbits = [STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO]
serial_bps = [4800, 9600, 19200, 38400,
57600, 74800, 115200, 230400,
460800, 576000, 1152000]
serial_bytesize = [5, 6, 7, 8]
timeout = None # 超时时间
xonxoff = False # 软件流控
rtscts = False # 硬件流控(RTS/CTS)
dsrdtr = None # 硬件流控(DSR/DTR)
if self.flow_control != 0:
xonxoff = True
# 填充串口参数
self.ser.port = self.port
self.ser.baudrate = serial_bps[self.bps]
self.ser.bytesize = serial_bytesize[self.byte_size]
self.ser.parity = serial_parity[self.parity]
self.ser.stopbits = serial_stopbits[self.stop_bits]
self.ser.xonxoff = xonxoff
# 打开串口
print(self.ser)
print("端口:", self.port, "波特率:", serial_bps[self.bps],
"数据位:", serial_bytesize[self.byte_size], "校验位:", serial_parity[self.parity],
"停止位:", serial_stopbits[self.stop_bits], "流控:", xonxoff)
try:
self.ser.open()
return True
except:
return False
pyserial读取数据方式有多种,可以按字节读取也可以按行读取
本程序中使用行读取方式,方法为readlen()
根据文档中所提示,这种方式与按字节读取类似,在未读到换行符时是阻塞状态,按字节读取是未读到指定字节数时为阻塞状态
所以如果想要持续读取数据可以开个子线程,把读取循环跑在子线程内
代码如下
读串口
def __readThread(self):
while self.__connectBuf:
try:
# 阻塞式读串口
buf = self.serialBuf.ser.readline()
if buf is not None:
buf_gbk = buf.decode("GBK")
print(buf_gbk)
except Exception as e:
print(e.args[0])
return 0
创建线程
def __runReadThread(self):
self.__textThread = threading.Thread(target=self.__textUpdateThread)
self.__textThread.setDaemon(True)
self.__textThread.start()
完整工程放在了Gitee
软件全部功能还未完成,慢慢更新中,此文串口是摘自其中一部分
仓库链接