首页 > 其他分享 >qt实现实时抓取串口数据,并对数据做解密处理

qt实现实时抓取串口数据,并对数据做解密处理

时间:2024-04-09 11:33:23浏览次数:21  
标签:qt mSerialPort void QSerialPort 抓取 SerialWorker 串口 data string

效果:

        1.实时抓取串口数据,并对串口数据做解密,解密后显示在QTextEdit上。

        2.对显示的内容做特殊关键字标记处理,比如对出现的Error关键字标红

                高亮另一个版本

        3.对显示的明文进行查询,类似编辑文件中的Ctrl+F

        4.对串口抓取到的数据存储到本地

实现:

        1.在mainwindow中使用串口类子线程对象,其中mHexEdit是显示hex进制数据的自定义控件

MainWindow::~MainWindow()
{
    mSerialWork->quitWork();
    delete  mSerialWork;
}


void MainWindow::initConnect()
{
    mSerialWork = new SerialWorker;
    connect(mSerialWork, &SerialWorker::readData, this, [&](const QByteArray &data){
    mHexEdit->appenData(data);
});

    connect(mSerialWork,&SerialWorker::sendparserslt, this, [&](const QString& data){
    mSerialEdit->append(data); //mSerialEdit是普通的QTextEdit控件
});
}

//dict是解密用的字典文件, serial是串口的属性,比如波特率、停止位等
void MainWindow::startWork(bool start, const QString &dict, const QVariantMap &serial)
{
    if(!start)
    {
        mPortList->setEnabled(true);
        mSerialWork->startWork(0, "", false);
        return;
    }

    auto port = mPortList->currentItem();
    if(nullptr== port)
    {
        QMessageBox::warning(this, tr("Warning"),
                tr("Please select a serial port"));
        return;
    }

    if(dict.isEmpty())
        return;

    QVariantMap data = serial;
    data["port"] = port->text();
    dicUartParseFilePath = dict;
    mSerialWork->setProperty(data);
    mHexEdit->setData(QByteArray());
    mSerialEdit->clear();
    mSerialWork->startWork(mProductType, dicUartParseFilePath);
}


void MainWindow::saveHexDataToLocal(const QString& path)
{
    const auto& data = mHexEdit->data();
    if(data.isEmpty())
        return;

    bool ret = false;
    QString result = tr("Save serial port data failed!");
    auto lastPath = ParseWork::Instance().getLogFilePath();
    if(path.isEmpty())
        return;

    QFile file(path);
    if(file.open(QIODevice::WriteOnly|QIODevice::Truncate))
    {
        ret = true;
        file.write(data);
        file.close();
        result = tr("Save serial port data successful!");
    }

    statusMessage(ret, result);
    ParseWork::Instance().setLogFilePath(path);
}

        2.关于SerialWorker的具体实现,部分无用代码需自己删减

#ifndef SERIALWORKER_H
#define SERIALWORKER_H

#include "parse/parsework.h"
#include "utils/utility.h"
#include <QObject>

class QThread;
class QSerialPort;
class SerialWorker : public QObject
{
    Q_OBJECT
public:
    explicit SerialWorker(QObject *parent = nullptr);
    ~SerialWorker();

    void setProperty(const QVariantMap& data);
    void setPortName(const QString& name);
    void setBaudrate(qint32 rate);
    void setDataBit(ushort);
    void setStopBit(ushort bit);
    void setParity(ushort parity);

    void startWork(uint product, const QString& dictPath, bool start=true);
    void quitWork();

signals:
    void openStatus(bool open);
    void readData(const QByteArray& data);
    void sendparserslt(QString parseStr);

private slots:
    void readSerialData();

private:
    QThread* mThread;
    QSerialPort* mSerialPort;

    QString mPortName;
    qint32 mBaudrate;
    ushort mDataBit;
    ushort mStopBit;
    ushort mParity;

    uint mProductType;
    QString mDictPath;

private:
    unsigned long long dataHasParsedSize = 0;
    deque<unsigned char> parsedatalist;
    unsigned int curFileLen = 0;                                    //base on the current file len to split file
    std::ofstream *outputBinFile = NULL;
    FILE *outputTxtFile = NULL;
    unsigned long saveFileNum = 1;
    string subFolderName;
    unsigned int singleFileSize = 20;

public:
    string CreateSaveFolder();
    bool CreateTextFile(string subFolderName);
    bool CreateBinaryFile(string subFolderName);
    string GetProjectName(ProjectItem project);
};

#endif // SERIALWORKER_H

  

#include "serialworker.h"

#include <QDebug>
#include <QThread>
#include <QSerialPort>
#include <QVariantMap>
#define GET_ENUM_NAME(value) case value:return (#value);
unsigned int parsedcnt = 0;
SerialWorker::SerialWorker(QObject *parent)
    : QObject(parent)
{
    mSerialPort = new QSerialPort(this);
    mThread = new QThread;
    moveToThread(mThread);

    connect(mSerialPort, &QSerialPort::readyRead, this, &SerialWorker::readSerialData);
    mThread->start();
}

SerialWorker::~SerialWorker()
{
    quitWork();
    delete mThread;
    delete mSerialPort;
}

void SerialWorker::setProperty(const QVariantMap &data)
{
    if(data.isEmpty())
        return;

    mPortName = data["port"].toString();
    mBaudrate = data["buadrate"].toLongLong();
    mParity   = data["pority"].toUInt();
    mDataBit  = data["dataBit"].toUInt();
    mStopBit  = data["stopBit"].toUInt();
}

void SerialWorker::setPortName(const QString &name)
{
    mPortName = name;
}

void SerialWorker::setBaudrate(qint32 rate)
{
    mBaudrate = rate;
}

void SerialWorker::setDataBit(ushort bit)
{
    mDataBit = bit;
}

void SerialWorker::setStopBit(ushort bit)
{
    mStopBit = bit;
}

void SerialWorker::setParity(ushort parity)
{
    mParity = parity;
}

void SerialWorker::startWork(uint product, const QString& dictPath, bool start)
{
    if(!start)
    {
        mSerialPort->flush();
        mSerialPort->close();
        return;
    }
    curFileLen = 0;
    parsedatalist.clear();
    subFolderName.clear();
    dataHasParsedSize = 0;

    mDictPath = dictPath;
    mProductType = product;
    QSerialPort::BaudRate baudrate = (QSerialPort::BaudRate)mBaudrate;
    mSerialPort->setBaudRate(baudrate,QSerialPort::AllDirections);
    QSerialPort::DataBits dataBits = (QSerialPort::DataBits)mDataBit;
    mSerialPort->setDataBits(dataBits);
    mSerialPort->setFlowControl(QSerialPort::NoFlowControl);
    QSerialPort::Parity parity = (QSerialPort::Parity)mParity;
    QSerialPort::StopBits stopBits = (QSerialPort::StopBits)mStopBit;

    mSerialPort->setPortName(mPortName);
    mSerialPort->setBaudRate(baudrate,QSerialPort::AllDirections);
    mSerialPort->setDataBits(dataBits);
    mSerialPort->setParity(parity);
    mSerialPort->setStopBits(stopBits);
    mSerialPort->setFlowControl(QSerialPort::NoFlowControl);
    if(start && !mSerialPort->isOpen())
    {
        mSerialPort->open(QIODevice::ReadWrite);
    }
    string folderPath = CreateSaveFolder();
    CreateTextFile(folderPath);
    CreateBinaryFile(folderPath);
    openStatus(mSerialPort->isOpen());
}

void SerialWorker::quitWork()
{
    saveFileNum = 1;                 //reset file number

    dataHasParsedSize += parsedatalist.size();

    for(uint i=0;i<parsedatalist.size();i++)
    {
        outputBinFile->write((char *)&parsedatalist.at(i),1);
    }

    if(outputBinFile)
    {
        outputBinFile->close();
        outputBinFile = NULL;
    }

    if(outputTxtFile)
    {
        fclose(outputTxtFile);
        outputTxtFile = NULL;
    }

    parsedatalist.clear();
    parsedcnt = 0;
    mSerialPort->close();
    mThread->quit();
    mThread->wait();
}

void SerialWorker::readSerialData()
{
    const auto& data = mSerialPort->readAll();
    for(int i=0;i<data.size();i++)
    {
        parsedatalist.push_back(data.at(i));
    }
    QString parseStr;
    int value1 = parsedatalist.size();
    switch (mProductType)
    {
        case TypeO:
            ParseWork::Instance().ParseTypeOSerialData(parsedatalist,
                mDictPath,parseStr, outputTxtFile,outputBinFile);
        case TypeT:
            ParseWork::Instance().ParseTypeTSerialData(parsedatalist,
                mDictPath,parseStr, outputTxtFile,outputBinFile);
        default:
            break;
    }
    if(parseStr.size())
    {
        emit sendparserslt(parseStr);
    }

    int value2 = parsedatalist.size();

    parsedcnt += (value1 - value2);
    if(parsedcnt >= (saveFileNum * singleFileSize * 1024 * 1024))
    {
        saveFileNum++;
        CreateTextFile(subFolderName);
        CreateBinaryFile(subFolderName);
    }

    emit readData(data);
}

string SerialWorker::CreateSaveFolder()
{
    string stCurrentTime = GetCurrentTimeStamp();
    std::string comName = mPortName.toStdString();
    string folderName = "SaveInfo_" + comName + "_" +stCurrentTime;
    string rootdir = get_current_directory();
    string path = rootdir + "/" + folderName;
    bool result = CreateFolder(path);
    if (result)
        return path;
    else
        return "";
}

bool SerialWorker::CreateTextFile(string subFolderName)
{
    if(outputTxtFile)
    {
        fclose(outputTxtFile);
        outputTxtFile = NULL;
    }
    string project = GetProjectName((ProjectItem)mProductType);
    char buf[128] = {0};
    sprintf(buf, "/%s_RS232Log_%ld.txt", project.c_str(), saveFileNum);

    string saveFileName;
    saveFileName = subFolderName + buf;
    outputTxtFile = fopen(saveFileName.data(), "w+");
    if(outputTxtFile)
    {
        qDebug()<<"txt file create successfully";

    }
    else
    {
        qDebug()<<"txt file create fail";
    }

    return true;
}

bool SerialWorker::CreateBinaryFile(string subFolderName)
{
    if(outputBinFile)
    {
        delete outputBinFile;
        outputBinFile = NULL;
    }
    string project = GetProjectName((ProjectItem)mProductType);
    char buf[100] = {0};
    sprintf(buf, "/%s_RS232Log_%ld.bin", project.c_str(), saveFileNum);

    string saveFileName;
    saveFileName = subFolderName + buf;

    outputBinFile = new std::ofstream(saveFileName, std::ios::out | std::ios::binary | std::ios::app);
    if(outputBinFile)
    {
        qDebug()<<"raw data file create successfully";
    }
    else
    {
        qDebug()<<"raw data file create fail";
    }

    return true;
}


string SerialWorker::GetProjectName(ProjectItem project)
{
    switch (project)
    {
        GET_ENUM_NAME(PE500 );
        GET_ENUM_NAME(SQ_UFS_2_2);
    default:
        return "";
        break;
    }
}

标签:qt,mSerialPort,void,QSerialPort,抓取,SerialWorker,串口,data,string
From: https://blog.csdn.net/weixin_43935710/article/details/137541093

相关文章

  • Qt中显示hex数据的控件
    效果类似QTextEdit,但是显示十六进制的数据,比如用于显示抓取串口或者bin文件的数据等等chunks.h#ifndefCHUNKS_H#defineCHUNKS_H/**\conddocNever*//*!TheChunksclassisthestoragebackendforQHexEdit.**WhenQHexEditloadsdata,Chunksaccessthe......
  • C++与Qt中回调函数的两种实现方法
    一.回调函数介绍1.概念回调函数是一种在程序运行期间通过函数指针调用的函数,它通常用于实现事件驱动、异步通信、消息传递等功能。在回调函数中,被调用的函数通常称为回调函数(CallbackFunction),而调用回调函数的函数通常称为回调函数容器(CallbackContainer)。回调函数容器可......
  • YOLOv5+PyQT5 果蔬识别检测可视化界面
    一、功能介绍界面里面可以选择图片检测与视频检测,可以用官方yolov5s模型训练出来的权重检测,也可以用自己改进的模型权重检测。二、界面展示三、项目介绍images存放的是界面需要的背景图片,runs存放的是已训练的模型权重,windows.py是运行文件,直接运行该文件即可。四、项......
  • USART串口协议
    一、串口通信1、串口定义•串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信•单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统......
  • FPGA入门笔记011_B——搭建串口收发与存取双口RAM简易应用系统
    1、实验现象​ 通过串口发送数据到FPGA中,FPGA接收到数据后将数据存储在双口ram的一段连续空间中,通过QuartusII软件提供的In-SystemMemoryContentEditor工具查看RAM中接收到的数据。当需要时,按下设计好的按键,则FPGA将RAM中存储的数据通过串口发送出去。2、......
  • PS端通过串口输出helloword
    创建工程:创建一个RTL工程:选择器件:而我用的zedboard的SOC型号:XC7Z020CLG484-1创建PS工程:第1步:对设计进行命名:等待一会后出现如下的界面:第2步:选择sources第3步:添加IP:第4步:搜索ZYNQ的PS部分的IP核:等待一段时间后此界面的放缩方法:①Ctrl+鼠标滚轮②左键......
  • qt之函数重定义
    错误信息:/usr/bin/ld:rknnthread.o:infunction`rknnThread::~rknnThread()':***/rknnthread.cpp:14:multipledefinitionof`rknnThread::~rknnThread()';rknnthread.o:/***/rknnthread.cpp:14:firstdefinedhere/usr/bin/ld:rknnthread.o:infunction`rk......
  • PySide2-QThread创建、终止、暂停、继续、延时功能实现
    程序实现了一个能够显示0-99数字循环进度的功能,并提供了进度查看、暂停、继续及终止操作。importsysimporttimefromPySide2.QtCoreimport(QObject,QThread,Qt,Signal,QTimer,QCoreApplication,QEventLoop,Slot,)fromPy......
  • Qt信号与槽
    我们在使用Qt的时候,不使用QtDesigner的方式进行开发,使用ui文件,信号与槽的连接方式是生成代码之后才能在setupUi函数里才能看到,或者需要进入Ui设计器里的信号槽模式里才能看到信号槽的连接。所以我们最好使用代码绘制界面。一.Qt信号与槽机制信号(Signal)就是在特定情况下被发......
  • burp suit 无法抓取 localhost 的数据包
    burpsuit无法抓取localhost的数据包‍Chorme上:在SwitchyOmega插件的不代理的地址列表中,删除默认的localhost​,添加上<-loopback>​​​‍Firefox上:在地址栏中,输入about:config​,然后搜索配置项network.proxy.allow_hijacking_localhost​,将其值设置为true​......