Bootstrap

Python 串口工具之数据整理分析

清华园镜像地址: -i https://pypi.tuna.tsinghua.edu.cn/simple

在实际工作中,串口采集数据后,还需要对数据进行整理分析,比如说查找想要的数据,对收到的数据进行校验、加解密,时间间隔等分析操作。因此该工具对这点需求进行了整合,将数据筛选与校验等融入了进来。

一、筛选:

使用步骤是,将想要筛选的内容,输入筛选框,点筛选后,将筛选结果显示在分析窗口中。

程序执行时,将所有接收框的数据,存入文件中,然后用筛选框的内容比对文件的每一行内容,记录行号及结果,并将改行显示在分析窗口中。

def data_ellis(self):
    find_content = self.ui.lineEdit_find.text()
    file_content = self.ui.textBrowserRev.toPlainText()
    with open("ellis_data.txt","w",encoding="utf_8") as fw:
        fw.write(file_content)

    if find_content != "":
        n = 0
        m = 0
        lists = []
        self.tool_receive_timer.stop()
        find_content = find_content.strip()
        self.ui.textBrowser_Ellis.setText("")
        self.ui.pushButton_open.setText("打开串口")
        self.serialTool.close()

        with open("ellis_data.txt", "r", encoding="utf_8") as fr:
            lines = fr.readlines()

            for line in lines:
                n =  n + 1
                if find_content in line:
                    m = m+1

                    list = f"搜索到了第{str(n)}行,第{str(m)}个结果"+"\r\n"+line+"\r\n"
                    lists.append(list)
                else:
                    pass

            if len(lists) == 0 :


                self.ui.textBrowser_Ellis.setText("没有找到想要的内容!")
                self.ui.textBrowser_Ellis.moveCursor(QTextCursor.End)
            else:
                self.ui.textBrowser_Ellis.setText("".join(lists))
                self.ui.textBrowser_Ellis.moveCursor(QTextCursor.End)

            with open("elis_reasult.txt","w",encoding="utf-8") as fz:
                fz.write(self.ui.textBrowser_Ellis.toPlainText())

    else:
        QMessageBox.critical(self,"提示","请输入查找内容!")

  • crc8(8005) 、CRC16(modbus)校验:

数据校验部分,采用了CRC标准库,实现了 crc8 和 crc16 常用的两种校验方式。

使用时,将需要分析的数据放入校验框中,点对应校验,结果展示在分析数据框中,这样就可以和收到的校验进行对比。

def data_crc8(self):
    dv = self.ui.lineEdit_crc8.text()
    dv.strip()
    dat = []
    while dv != "" :
        try:
            sub_number = int(dv[0:2], 16)
        except ValueError:
            QMessageBox.critical(self, "提示", "校验内容不是16进制!")
            return None
        else:
            dv = dv[2:].strip()

            dat.append(sub_number)


    cfg = crc.Configuration(
        width=8,
        polynomial=0x1D,
        init_value=0xFF,
        final_xor_value=0xFF,
        reverse_input=False,
        reverse_output=False
    )
    print(dat)
    print(bytes(dat))
    code = crc.Calculator(cfg).checksum(bytes(dat))

    self.ui.textBrowser_Ellis.setText(f"{hex(code)}")
def data_crc16(self):
    dv = self.ui.lineEdit_crc16.text()
    dv.strip()

    numlist = []

    while dv != "":
        try:
            subdata = int(dv[:2],16)
        except ValueError:
            QMessageBox.critical(self, "提示", "校验内容不是16进制!")
            return None
        else:
           dv = dv[2:].strip()
           numlist.append(subdata)

    cfg = crc.Configuration(
        width=16,
        polynomial=0x8005,
        init_value=0xFFFF,
        final_xor_value=0x0000,
        reverse_input=True,
        reverse_output=True,
    )

    res = crc.Calculator(cfg).checksum(bytes(numlist))

    self.ui.textBrowser_Ellis.setText(f"{hex(res)}")

  • 时间间隔的计算

    

在接收和发送数据时,都将实时时间记录了下来,有时候为了看两端数据的间隔,现在只需要将想分析的内容选中,就可以直接算出间隔时间,同时支持手动输入时间计算。


def data_interval(self):

    par = re.compile(r'\d{4}-\d{1,2}-\d{1,2} \d{2}:\d{2}:\d{2}.\d*')
    con = self.ui.textBrowserRev.textCursor().selectedText()
    # print(con)
    # print(par.findall(con))
    rest = par.findall(con)

    self.tool_receive_timer.stop()
    self.ui.pushButton_open.setText("打开串口")
    self.serialTool.close()


    sts = self.ui.lineEdit_time_start.text()
    ste = self.ui.lineEdit_time_end.text()

    sts = sts.strip()
    ste = ste.strip()

    if (len(par.findall(sts)) != 0) and (len(par.findall(ste)) != 0):

        tsss = datetime.datetime.strptime(sts, "%Y-%m-%d %H:%M:%S.%f")
        tsse = datetime.datetime.strptime(ste, "%Y-%m-%d %H:%M:%S.%f")

        intv = (tsss - tsse).total_seconds()

        tstring = f"时间间隔:{intv}秒"

        self.ui.textBrowser_Ellis.setText(tstring)

    elif len(rest) != 0:

        string = "\r\n".join(rest)
        self.ui.textBrowser_Ellis.setText(string)
        self.ui.lineEdit_time_start.setText(rest[-1])
        self.ui.lineEdit_time_end.setText(rest[0])

        print(rest[-1])
        print(rest[0])
        tsf = datetime.datetime.strptime(rest[-1], "%Y-%m-%d %H:%M:%S.%f")
        tef = datetime.datetime.strptime((rest[0]), "%Y-%m-%d %H:%M:%S.%f")

        intv = (tsf - tef).total_seconds()

        tstring = f"时间间隔:{intv}秒"

        self.ui.textBrowser_Ellis.setText(tstring)

    else:
        QMessageBox.critical(self, "提示",
                             "起始时间时间格式不正确,请按2024-12-12 18:18:18.9999....格式填写时间或在接收框选择")
        return None

至此,我们主体功能全部完成,并且全部测试正常,现在还剩下关闭窗口时,保存设置及保存接收发送的数据。实现如下:

def closeEvent(self, event):
    reply = QMessageBox.question(self, 'Message', "确定要退出吗?",
                                 QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    # 判断返回值,如果点击的是Yes按钮,我们就关闭组件和应用,否则就忽略关闭事件
    if reply == QMessageBox.Yes:
        self.save_cfg()


        with open("recevie.txt",mode="w+",encoding="utf-8") as f:

            f.write(self.ui.textBrowserRev.toPlainText())

        event.accept()
    else:
        event.ignore()

经过几天的完善,我们的工具算是正式完成了。

;