消费机 水控机 售饭机 电梯门禁 门禁机
快速寻找产品(请输入产品型号或名称的关键词):
首页> 技术文档

技术文档

解决Python串口通讯时数据接收不全分包传送的问题

发布者:广州荣士电子有限公司         发布时间: 2023-3-25 
import serial
import time
import sys
import serial.tools.list_ports
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QDateTime
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget,QMessageBox

selecom=0
ser = serial.Serial()
ComIsOpen=False
OrderCode=0
RcvBuff=b''

class SerialListenThread(QThread):       # 串口侦听线程
    serial_data = pyqtSignal(int,str)    # 创建一个信号,触发时传递显示信息给槽函数

    def run(self):
        global ComIsOpen
        global OrderCode
        global RcvBuff
        while ComIsOpen:
            try:
                rcvdata = ser.read_all()  #接收串口数据
                if (len(rcvdata) > 0):
                    if (OrderCode<=1):  #非发送指令后的返回数据
                        GetData = '接收数据:'
                        for num in range(0, len(rcvdata)):
                            GetData = GetData + '%02X ' % (rcvdata[num])
                        self.serial_data.emit(1, GetData)
                    else:       # 发送读卡扇区数据令的返回数据
                        RcvBuff = RcvBuff + rcvdata  #将本次接收到的数据加入到未处理的接收数据缓冲
                        if (len(RcvBuff)>=RcvBuff[0]+2): # 缓冲首字节为一条完整信息的总长度,如缓冲内数据长度+1字节检验位+1字节的长度等于首字节表示本条数据接收完整可以解析
                            deldata=RcvBuff[0:RcvBuff[0]+2]
                            GetData = '接收数据:'
                            for num in range(0, len(deldata)):
                                GetData = GetData + '%02X ' % (deldata[num])
                            self.serial_data.emit(1, GetData)

                            crc = 0  # 计算返回数据的校验位
                            for num in range(1, len(deldata) - 1):
                                crc = crc ^ deldata[num]
                            if (crc == deldata[len(deldata) - 1]):
                                if(OrderCode==3):   #轻松读IC卡扇区指令返回数据
                                    if (deldata[0] == 1 and deldata[1] == 8):
                                        self.serial_data.emit(2, '未寻到卡!')
                                    elif (deldata[0] == 1 and deldata[1] == 9):
                                        self.serial_data.emit(2, '两张以上卡片同时在感应区,发生冲突!')
                                    elif (deldata[0] == 5):
                                        if (deldata[1] == 1):
                                            self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证成功,但读取扇区内容失败!')
                                        elif (deldata[1] == 2):
                                            self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!')
                                        elif (deldata[1] == 3):
                                            self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!')
                                        elif (deldata[1] == 10):
                                            self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',无法选择激活卡片!')
                                        elif (deldata[1] == 12):
                                            self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证失败!')
                                        else:
                                            self.serial_data.emit(2, '操作失败,错误代码:' + str(deldata[1]))
                                    elif (deldata[0] == 53):
                                        self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',读取扇区数据成功!')
                                        ReturnInf = ''
                                        for num in range(6, len(deldata) - 1):
                                            ReturnInf = ReturnInf + '%02X ' % (deldata[num])
                                        self.serial_data.emit(3,ReturnInf)

                            RcvBuff = RcvBuff[RcvBuff[0] + 2:]  #将已经解析完的数据从缓冲内切除
                            if(len(RcvBuff)==0):
                                OrderCode=0
            except:
                self.serial_data.emit(1, '串口正在接收数据...')


 
上一篇:B/S结构chrome、Edge、360、UC、火狐等WEB浏览器如何发送指令... 下一篇:解决因断电死机造成的SQL数据库置疑、无法附加等错误
     
Guangzhou Rong Shi Electronics Co., Ltd., China 广州荣士电子有限公司 备案/许可证编号:粤ICP备11063836号
TEL  020-22307058    020-82301718
消费机
隐私政策

消费机 水控机 售饭机 电梯门禁 门禁机

网站地图 xml