|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
自学python,写了个串口工具,但是一旦连续接收数据多了之后,程序就会崩溃。
不知道是何原因,请小伙伴们帮忙找下原因。
另外代码写的不合理的地方,也希望帮忙指出,谢谢。
出错截图如下图。右边是网上找的串口工具,连续不断的给右边(自己写的)程序发数据,两条消息间隔30ms。
没传多久就会出现如图的停止工作的情况。
出错截图
Pthon3 + PyQT
helloU.py
- # -*- coding: utf-8 -*-
- # Form implementation generated from reading ui file 'helloU.ui'
- #
- # Created by: PyQt5 UI code generator 5.9.2
- #
- # WARNING! All changes made in this file will be lost!
- from PyQt5 import QtCore, QtGui, QtWidgets
- class Ui_MainWindow(object):
- def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(562, 437)
- MainWindow.setMinimumSize(QtCore.QSize(562, 437))
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setEnabled(True)
- self.centralwidget.setObjectName("centralwidget")
- self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.gridLayout = QtWidgets.QGridLayout()
- self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
- self.gridLayout.setObjectName("gridLayout")
- self.sendLineEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.sendLineEdit.setObjectName("sendLineEdit")
- self.gridLayout.addWidget(self.sendLineEdit, 2, 0, 1, 7)
- self.dataBits = QtWidgets.QComboBox(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.dataBits.sizePolicy().hasHeightForWidth())
- self.dataBits.setSizePolicy(sizePolicy)
- self.dataBits.setMinimumSize(QtCore.QSize(50, 20))
- self.dataBits.setMaximumSize(QtCore.QSize(50, 20))
- self.dataBits.setObjectName("dataBits")
- self.gridLayout.addWidget(self.dataBits, 0, 4, 1, 1)
- self.sendBtn = QtWidgets.QPushButton(self.centralwidget)
- self.sendBtn.setObjectName("sendBtn")
- self.gridLayout.addWidget(self.sendBtn, 3, 0, 1, 1)
- self.rcvBrowser = QtWidgets.QTextBrowser(self.centralwidget)
- self.rcvBrowser.setObjectName("rcvBrowser")
- self.gridLayout.addWidget(self.rcvBrowser, 1, 0, 1, 7)
- self.parityMode = QtWidgets.QComboBox(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.parityMode.sizePolicy().hasHeightForWidth())
- self.parityMode.setSizePolicy(sizePolicy)
- self.parityMode.setMinimumSize(QtCore.QSize(60, 20))
- self.parityMode.setMaximumSize(QtCore.QSize(60, 20))
- self.parityMode.setObjectName("parityMode")
- self.gridLayout.addWidget(self.parityMode, 0, 3, 1, 1)
- self.stopBits = QtWidgets.QComboBox(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.stopBits.sizePolicy().hasHeightForWidth())
- self.stopBits.setSizePolicy(sizePolicy)
- self.stopBits.setMinimumSize(QtCore.QSize(50, 20))
- self.stopBits.setMaximumSize(QtCore.QSize(50, 20))
- self.stopBits.setObjectName("stopBits")
- self.gridLayout.addWidget(self.stopBits, 0, 5, 1, 1)
- self.baudLineEdit = QtWidgets.QLineEdit(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.baudLineEdit.sizePolicy().hasHeightForWidth())
- self.baudLineEdit.setSizePolicy(sizePolicy)
- self.baudLineEdit.setMinimumSize(QtCore.QSize(80, 20))
- self.baudLineEdit.setMaximumSize(QtCore.QSize(80, 20))
- self.baudLineEdit.setText("")
- self.baudLineEdit.setObjectName("baudLineEdit")
- self.gridLayout.addWidget(self.baudLineEdit, 0, 2, 1, 1)
- spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout.addItem(spacerItem, 0, 6, 1, 1)
- self.openButton = QtWidgets.QPushButton(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.openButton.sizePolicy().hasHeightForWidth())
- self.openButton.setSizePolicy(sizePolicy)
- self.openButton.setMinimumSize(QtCore.QSize(80, 20))
- self.openButton.setMaximumSize(QtCore.QSize(80, 20))
- self.openButton.setObjectName("openButton")
- self.gridLayout.addWidget(self.openButton, 0, 0, 1, 1)
- self.portNum = QtWidgets.QComboBox(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.portNum.sizePolicy().hasHeightForWidth())
- self.portNum.setSizePolicy(sizePolicy)
- self.portNum.setMinimumSize(QtCore.QSize(80, 20))
- self.portNum.setMaximumSize(QtCore.QSize(80, 20))
- self.portNum.setObjectName("portNum")
- self.gridLayout.addWidget(self.portNum, 0, 1, 1, 1)
- spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout.addItem(spacerItem1, 3, 3, 1, 4)
- self.HexCheckBox = QtWidgets.QCheckBox(self.centralwidget)
- self.HexCheckBox.setObjectName("HexCheckBox")
- self.gridLayout.addWidget(self.HexCheckBox, 3, 1, 1, 1)
- self.NewLineCheckBox = QtWidgets.QCheckBox(self.centralwidget)
- self.NewLineCheckBox.setObjectName("NewLineCheckBox")
- self.gridLayout.addWidget(self.NewLineCheckBox, 3, 2, 1, 1)
- self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
- MainWindow.setCentralWidget(self.centralwidget)
- self.menubar = QtWidgets.QMenuBar(MainWindow)
- self.menubar.setGeometry(QtCore.QRect(0, 0, 562, 23))
- self.menubar.setObjectName("menubar")
- MainWindow.setMenuBar(self.menubar)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
- self.retranslateUi(MainWindow)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
- self.sendBtn.setText(_translate("MainWindow", "Send"))
- self.openButton.setText(_translate("MainWindow", "OPEN"))
- self.HexCheckBox.setText(_translate("MainWindow", "HEX"))
- self.NewLineCheckBox.setText(_translate("MainWindow", "NewLine"))
复制代码
SerialHandle.py
- #!/usr/bin/env python
- # _*_ coding:utf-8 _*_
- import sys
- import threading
- import time
- import serial
- import binascii
- import logging
- logging.basicConfig(level=logging.INFO)
- class SerialHandle(object):
- def __init__(self, Port="COM3", BaudRate="9600", ByteSize="8", Parity="N", Stopbits="1"):
- '''
- 初始化一些参数
- :param Port:
- :param BaudRate:
- :param ByteSize:
- :param Parity:
- :param Stopbits:
- :return:
- '''
- self.l_serial = None
- self.alive = False
- self.portNum = Port
- self.baudrate = BaudRate
- self.bytesize = ByteSize
- self.parity = Parity
- self.stopbits = Stopbits
- self.receiveData = ""
- def start(self):
- '''
- 打开串口
- :return:
- '''
- self.l_serial = serial.Serial()
- self.l_serial.port = self.portNum
- self.l_serial.baudrate = self.baudrate
- self.l_serial.bytesize = int(self.bytesize)
- self.l_serial.parity = self.parity
- self.l_serial.stopbits = int(self.stopbits)
- self.l_serial.timeout = 2
- try:
- self.l_serial.open()
- if self.l_serial.isOpen():
- self.alive = True
- except Exception as e:
- self.alive = False
- logging.error(e)
- def stop(self):
- '''
- 关闭串口
- :return:
- '''
- self.alive = False
- if self.l_serial.isOpen():
- self.l_serial.close()
- # 获取COM号列表
- def port_list(self):
- comlist = []
- port_list = list(serial.tools.list_ports.comports())
- for port in port_list:
- comlist.append(port[0])
- return comlist
- def read(self):
- '''
- 循环读取串口的数据
- :return:
- '''
- isRcved = False
- timeRcved = 0
- while self.alive:
- try:
- number = self.l_serial.inWaiting()
- if number:
- isRcved = True
- timeRcved = int(round(time.time() * 1000))
- self.receiveData += self.l_serial.read(number).decode()#.replace(binascii.unhexlify("00"), "")
- #print(self.receiveData)
- #print("rcv data: %s" % self.l_serial.read(number).decode())
- except Exception as e:
- logging.error(e)
- if isRcved == True :
- if (int(round(time.time() * 1000)) - timeRcved)>10:
- print(self.receiveData)
- isRcved = False
- self.receiveData = ""
- def dataReceiveAndProcess(self, func):
- try:
- thread_read = threading.Thread(target=self._dataRecevie, args=(func, ))
- thread_read.setDaemon(True)
- thread_read.start()
- except BaseException as e:
- print("error:",e)
- def _dataRecevie(self, func):
- '''
- 循环读取串口的数据
- :return:
- '''
- isRcved = False
- timeRcved = 0
- while self.alive:
- number = self.l_serial.inWaiting()
- if number:
- logging.info('receive data\n')
- isRcved = True
- timeRcved = int(round(time.time() * 1000))
- self.receiveData += self.l_serial.read(number).decode()#.replace(binascii.unhexlify("00"), "")
- #print(self.receiveData)
- #print("rcv data: %s" % self.l_serial.read(number).decode())
- if isRcved == True :
- if (int(round(time.time() * 1000)) - timeRcved)>10:
- logging.info('process data\n')
- #print(self.receiveData)
- func(self.receiveData)
- isRcved = False
- self.receiveData = ""
- def sendData(self, data, isHex=False, isNewLine=False):
- '''
- 发送数据
- :param data: self.sendLineEdit.text()
- :param isHex: self.HexCheckBox.checkState()
- :param isNewLine: self.NewLineCheckBox.checkState()
- :return:
- '''
- if data != "":
- if (isHex == False):
- # 字符串发送
- if isNewLine:
- data = data + "\r\n"
- inputData = data.encode('utf-8')
- else:
- # 十六进制发送
- data = data.strip() # 删除前后的空格
- sendList = []
- while data != "":
- try:
- # int() 函数用于将一个字符串或数字转换为整型。
- num = int(data[0:2], 16)
- except ValueError:
- print("input hex data!")
- #QMessageBox.critical(self, 'pycom', '请输入十六进制数据,以空格分开!')
- return None
- data = data[2:]
- data = data.strip()
- # 添加到发送列表中
- sendList.append(num)
- if isNewLine:
- sendList.append(0x0d)
- sendList.append(0x0a)
- inputData = bytes(sendList)
- # d = "12abc"
- # d = d.encode("ascii")
- self.l_serial.write(inputData)
- if __name__ == '__main__':
- import threading
- ser = SerialHandle()
- ser.start()
- ser.sendData("12 23 34", True)
- thread_read = threading.Thread(target=ser.read)
- thread_read.setDaemon(True)
- thread_read.start()
- import time
- time.sleep(25)
- ser.stop()
复制代码
main.py
- #!/usr/bin/env python
- # _*_ coding:utf-8 _*_
- import sys
- import threading
- import time
- import datetime
- import helloU
- import SerialHandle
- import serial
- import serial.tools.list_ports
- from PyQt5.QtGui import *
- from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
- class SerialDlg(helloU.Ui_MainWindow):
- def defaultInit(self):
- self.ser = SerialHandle.SerialHandle()
- self.serial_receive_count = 0
- self.portNum.addItems(self.ser.port_list())
- self.baudLineEdit.setText("9600")
- self.parityMode.addItems(['None', 'Even', 'Odd', 'Mark', 'Space'])
- self.dataBits.addItems(['5', '6', '7', '8'])
- self.stopBits.addItems(['1', '1.5', '2'])
- self.dataBits.setCurrentText("8")
- self.openButton.setText("OPEN")
- self.openButton.setStyleSheet("background-color:#4abdac")
- self.openButton.setFont(QFont('SansSerif', 15, QFont.Bold))
- self.openButton.setAutoFillBackground(True)
- self.openButton.clicked.connect(self.OpenSerial)
- self.sendBtn.clicked.connect(self.SendData)
- self.sendBtn.setDisabled(True)
- # 打开串口
- def OpenSerial(self):
- if self.openButton.text() == "OPEN":
- self.portNum.setDisabled(True)
- self.baudLineEdit.setDisabled(True)
- self.parityMode.setDisabled(True)
- self.dataBits.setDisabled(True)
- self.stopBits.setDisabled(True)
- self.sendBtn.setDisabled(False)
- self.port = self.portNum.currentText()
- self.baudrate = self.baudLineEdit.text()
- ParityValue = self.parityMode.currentText()
- self.parity = ParityValue[0]
- self.bytesize = int(self.dataBits.currentText())
- self.stopbits = int(self.stopBits.currentText())
- self.openButton.setText("CLOSE")
- self.openButton.setStyleSheet("background-color:#fc4a1a")
- # self.openButton.setAutoFillBackground(True)
- self.ser.portNum = self.port
- self.ser.baudrate = self.baudrate
- self.ser.bytesize = self.bytesize
- self.ser.parity = self.parity
- self.ser.stopbits = self.stopbits
- self.ser.start()
- self.ser.dataReceiveAndProcess(self.showDataOnQTextBrowser)
- #thread_read = threading.Thread(target=self.ser.read)
- #thread_read.setDaemon(True)
- #thread_read.start()
- elif self.openButton.text() == "CLOSE":
- self.ser.stop()
- self.openButton.setText("OPEN")
- self.openButton.setStyleSheet("background-color:#4abdac")
- # self.openButton.setAutoFillBackground(True)
- self.portNum.setDisabled(False)
- self.baudLineEdit.setDisabled(False)
- self.parityMode.setDisabled(False)
- self.dataBits.setDisabled(False)
- self.stopBits.setDisabled(False)
- self.sendBtn.setDisabled(True)
- # 发送数据
- def SendData(self):
- self.ser.sendData(self.sendLineEdit.text(), self.HexCheckBox.checkState(), self.NewLineCheckBox.checkState())
- # 数据显示
- def showDataOnQTextBrowser(self, data):
- self.serial_receive_count += 1
- self.rcvBrowser.append("[" + str(datetime.datetime.now()) + " - "+ str(self.serial_receive_count) + "]:\n")
- self.rcvBrowser.append(data)
- #QTextCursor cursor = self.rcvBrowser.textCursor()
- self.rcvBrowser.setTextCursor(self.rcvBrowser.textCursor())
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- MainWindow = QMainWindow()
- ui = SerialDlg() #helloU.Ui_MainWindow()
- ui.setupUi(MainWindow)
- ui.defaultInit()
- MainWindow.show()
- sys.exit(app.exec_())
复制代码
对  ,我的archlinux+gnome就没有事,  你再等等吧,python更新后应该会好,还有,别装测试版,bug多 
|
|