1、更新串口读取缓冲区大小1024

2、优化读取数据丢失问题
3、对识别结果上传使用异步处理,避免接口阻塞导致的界面卡顿
This commit is contained in:
Mr.V 2024-03-27 20:09:46 +08:00
parent 9f90d5c2c1
commit 5abb482d0c
8 changed files with 132 additions and 120 deletions

View File

@ -1,20 +0,0 @@
[base]
com_name=COM2
baud=19200
track_name=2
have_magnet_steel=true
magnet_steel_order=8421
up_result=false
use_socket_server=true
[interface]
http_ip=192.168.137.104
http_port=20004
token_path=/api/token_path
up_result_path=/api/train-carriage/identification/rfid-save
username=guest_01
password=d55b0f642e817eea24725d2f2a31dd08
[socket_server]
server_ip=172.24.192.1
server_port=60001

View File

@ -4,11 +4,11 @@ baud=19200
track_name=2
have_magnet_steel=true
magnet_steel_order=8421
up_result=false
use_socket_server=true
up_result=true
use_socket_server=false
[interface]
http_ip=192.168.137.104
http_ip=192.168.2.108
http_port=20004
token_path=/api/token_path
up_result_path=/api/train-carriage/identification/rfid-save
@ -16,5 +16,5 @@ username=guest_01
password=d55b0f642e817eea24725d2f2a31dd08
[socket_server]
server_ip=172.24.192.1
server_port=60001
server_ip=172.18.160.1
server_port=7000

View File

@ -25,6 +25,7 @@ find_package(Qt5 COMPONENTS
Widgets
Network
SerialPort
Concurrent
REQUIRED)
#QtNetworkproQT+=network
@ -122,6 +123,7 @@ target_link_libraries(Train_RFID
Qt5::Widgets
Qt5::Network
Qt5::SerialPort
Qt5::Concurrent
)
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)

View File

@ -1,19 +0,0 @@
//
// Created by Mr.V on 2024/3/16.
//
#include "DeleteOldLog.h"
void DeleteOldLog::deleteFile() {
QDir dir("./Logs");
QStringList fileList;
QFileInfoList fileInfoList = dir.entryInfoList(fileList, QDir::Files);
for (int i = 0; i < fileInfoList.size(); i++) {
QFileInfo info = fileInfoList.at(i);
if (info.birthTime() < QDateTime::currentDateTime().addDays(-10))
{
QFile::remove(info.absoluteFilePath());
}
}
}

View File

@ -1,20 +0,0 @@
//
// Created by Mr.V on 2024/3/16.
//
#ifndef TRAIN_RFID_DELETEOLDLOG_H
#define TRAIN_RFID_DELETEOLDLOG_H
#include <QDir>
#include <Qobject>
#include <QDateTime>
class DeleteOldLog {
Q_OBJECT
public:
bool readDeleteConfig();
public slots:
void deleteFile();
};
#endif //TRAIN_RFID_DELETEOLDLOG_H

View File

@ -42,10 +42,6 @@ MainWindow::MainWindow(QWidget *parent)
{
this->logError(errorMessage);
}
// 创建菜单栏
// this->initMenu();
// this->ui->testButton->setHidden(true);
// 获取本机串口列表
this->getComList();
@ -71,8 +67,8 @@ MainWindow::MainWindow(QWidget *parent)
connect(m_pSystemTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason)));
this->logRfidRecvName = "./Logs/rfid_data.txt";
recvLog.setFileName(logRfidRecvName);
recvLog.open(QIODevice::ReadWrite | QIODevice::Append);
this->recvLog.setFileName(logRfidRecvName);
this->recvLog.open(QIODevice::ReadWrite | QIODevice::Append);
//初始最小化
//this->showMinimized();//最小化
@ -147,6 +143,7 @@ MainWindow::MainWindow(QWidget *parent)
});
}
ui->openComButton->click();
}
MainWindow::~MainWindow()
@ -174,8 +171,9 @@ void MainWindow::logError(const QString& message) {
}
void MainWindow::initParam() {
this->rfidSourceInfo = "";
this->trainTime = "";
this->recvLog.close();
if (this->recvLog.isOpen()) this->recvLog.close();
this->vecTrain.clear();
this->needIdentify = false;
this->rnameRfidLog();
@ -219,12 +217,25 @@ bool MainWindow::mkRfidLog()
return false;
}
void MainWindow::deleteOldFiles(const QString &path, int days)
{
QDir dir(path);
foreach(QFileInfo fi, dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot))
{
if((fi.lastModified().addDays(days) < QDateTime::currentDateTime()))
{
QFile::remove(fi.absoluteFilePath());
}
}
}
bool MainWindow::rnameRfidLog()
{
try {
this->recvLog.close();
QFile logFile(this->logRfidRecvName);
QFileInfo fileInfo(logFile);
if (fileInfo.size() == 0) return false;
QString newLogFileName = fileInfo.path() + "/";
newLogFileName.append(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss"));
@ -235,6 +246,8 @@ bool MainWindow::rnameRfidLog()
this->logError("读取RFID原始数据存储重命名失败");
return false;
}
this->deleteOldFiles(fileInfo.path(), 3);
} catch (const std::exception &e) {
this->logError("读取RFID原始数据存储重命名失败");
return false;
@ -245,7 +258,6 @@ bool MainWindow::rnameRfidLog()
void MainWindow::saveRfidLog(const QString &value)
{
try {
// QString logValue = "[" + QDateTime::currentDateTime().toString("hh:mm::ss") + "] " + value + "\n";
QString logValue = value + "\n";
if (!this->recvLog.isOpen())
{
@ -334,33 +346,32 @@ QStandardItem* MainWindow::getStandardItem(const QString &value)
/******************************同 web 交互****************************************/
/**
* @brief:Http发送RFID数据
* @paramcarriageType
* @paramcarriageNumber
* @paramcarriageOrder
* @paramtime
* @paramrfidSourceInfoRFID的原始数据
* @return: :true
* :false
*/
bool MainWindow::upWeb(std::string &carriageType, std::string &carriageNumber, std::string &carriageOrder, std::string &time)
bool MainWindow::upWeb(std::string &carriageType,
std::string &carriageNumber,
std::string &carriageOrder,
std::string &time,
std::string &strRfidInfo)
{
try {
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(0, 300 * 1000);
cli.set_read_timeout(1,0);
httplib::Headers header;
httplib::Params params;
Json::Value arrayObj; //构建对象
header.emplace("blade-auth", this->webToken);
//header.emplace("Content-Type", "application/json");
arrayObj["comeTime"] = time;
arrayObj["collectTime"] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz").toStdString();
arrayObj["carriageNumber"] = carriageNumber;
arrayObj["carriageType"] = carriageType;
arrayObj["carriageOrder"] = carriageOrder;
arrayObj["steel"] = strRfidInfo;
Json::Value trainParams;
trainParams["poundNo"] = std::to_string(this->baseConfig_.trackName);
@ -370,6 +381,14 @@ bool MainWindow::upWeb(std::string &carriageType, std::string &carriageNumber, s
this->logInfo("" + QString::fromStdString(carriageOrder) + "发送web: " + QString::fromStdString(str));
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(0, 300 * 1000);
cli.set_read_timeout(1,0);
httplib::Headers header;
httplib::Params params;
header.emplace("blade-auth", this->webToken);
//header.emplace("Content-Type", "application/json");
auto res = cli.Post(this->interfaceConfig_.upResultPath.toStdString(), header, str, "application/json");
if (res)
{
@ -393,9 +412,10 @@ bool MainWindow::upWeb(std::string &carriageType, std::string &carriageNumber, s
if (root["msg"].asString() == "请求未授权") {
this->logWarn("" + QString::fromStdString(carriageOrder) + "因请求未授权而上传识别结果失败重新请求token。");
if (!this->getToken()) return false;
return this->upWeb(carriageType, carriageNumber, carriageOrder, time);
return this->upWeb(carriageType, carriageNumber, carriageOrder, time, strRfidInfo);
}
this->logError("" + QString::fromStdString(carriageOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root.asString()));
this->logError("---");
this->logError("" + QString::fromStdString(carriageOrder) + "节,识别结果上传失败,原因:" + QString::fromStdString(root["msg"].asString()));
}
}
else
@ -409,7 +429,7 @@ bool MainWindow::upWeb(std::string &carriageType, std::string &carriageNumber, s
if (res->status == 401) {
this->logWarn("因请求未授权而上传识别结果失败重新请求token。");
this->getToken();
return this->upWeb(carriageType, carriageNumber, carriageOrder, time);
return this->upWeb(carriageType, carriageNumber, carriageOrder, time, strRfidInfo);
}
}
}
@ -437,7 +457,7 @@ bool MainWindow::getToken()
{
httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
cli.set_connection_timeout(0, 300 * 1000);
cli.set_read_timeout(1,0);
cli.set_read_timeout(0,300*1000);
httplib::Headers header;
httplib::Params params;
@ -470,7 +490,7 @@ bool MainWindow::getToken()
}
else
{
this->logError("获取web token失败原因" + QString::fromStdString(root.asString()));
this->logError("获取web token失败原因" + QString::fromStdString(res->body));
}
}
else
@ -576,7 +596,7 @@ void MainWindow::on_ShowMainAction()
*/
void MainWindow::on_ExitAppAction()
{
// 弹出对话框要求用户输入账号和密码
// 弹出对话框要求用户输入密码
QString password = QInputDialog::getText(this, "密码验证", "请输入密码:", QLineEdit::Password);
// 验证账号和密码是否正确
@ -586,7 +606,6 @@ void MainWindow::on_ExitAppAction()
exit(0);
} else {
QMessageBox::warning(this, "验证失败", "密码不正确!");
//event->ignore(); // 阻止关闭窗口
}
}
@ -631,9 +650,7 @@ void MainWindow::openComClicked()
"background-color: rgba(74, 221, 108, 225);\ "
"border:1px solid rgba(168, 168, 168, 105);");
connect(this->serial_,&QSerialPort::readyRead,this,&MainWindow::readCom);
// QTimer* timer = new QTimer(this);
// connect(timer, &QTimer::timeout, this, &MainWindow::readCom);
// timer->start(10);
connect(this->serial_, &QSerialPort::errorOccurred, this, &MainWindow::serialPort_error);
}
@ -645,16 +662,24 @@ void MainWindow::openComClicked()
}
else
{
if (this->comDetect_.closeCom())
{
if (this->needIdentify == true) this->needIdentify = false;
this->isOpenCom = false;
this->logInfo("串口已关闭!");
this->initParam();
this->ui->openComButton->setText("打开串口");
this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
"background-color: red;\ "
"border:1px solid rgba(168, 168, 168, 105);");
// 弹出对话框要求用户输入密码
QString password = QInputDialog::getText(this, "密码验证", "请输入密码:", QLineEdit::Password);
// 验证账号和密码是否正确
if (password == "matrix") {
if (this->comDetect_.closeCom())
{
if (this->needIdentify == true) this->needIdentify = false;
this->isOpenCom = false;
this->logInfo("串口已关闭!");
this->initParam();
this->ui->openComButton->setText("打开串口");
this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
"background-color: red;\ "
"border:1px solid rgba(168, 168, 168, 105);");
}
} else {
QMessageBox::warning(this, "验证失败", "密码不正确!");
}
}
}
@ -680,7 +705,7 @@ void MainWindow::serialPort_error(QSerialPort::SerialPortError error)
void MainWindow::readCom()
{
try {
if (this->serial_->waitForReadyRead(5)) {
if (this->serial_->waitForReadyRead(10)) {
QByteArray data = this->serial_->readAll(); // 读取数据
if(!data.isEmpty())
{
@ -710,10 +735,9 @@ void MainWindow::getQueueDataThread()
this->tmpRfid.append(strRfidInfo);
if (this->tmpRfid.right(1) != "&")
{
// this->logDebug("--" + this->tmpRfid + " " + this->tmpRfid.right(1));
return;
}
// this->logDebug("--" + this->tmpRfid);
this->tmpRfid = this->tmpRfid.replace("&", "");
QStringList rfidSubList = this->tmpRfid.split("@");
this->tmpRfid = "";
@ -761,30 +785,42 @@ void MainWindow::getQueueDataThread()
int train_order = vecTrain.size();
this->resultTableModel_->setItem(train_order - 1, 0, new QStandardItem(strTrainInfo));
this->logInfo(QString("第%1节 %2").arg(train_order).arg(strTrainInfo));
emit upRfid_signals();
// 将接收到的RFID使用@符拼接起来以待后续上传web
this->rfidSourceInfo.append("@" + i);
QString rfidinfo = this->rfidSourceInfo;
this->rfidSourceInfo = "";
emit upRfid_signals(rfidinfo);
}
}
else if (i.size() == 7)
{
// 不使用磁钢的情况下 过滤掉磁钢信号
if (!this->baseConfig_.havaMagnetSteel) continue;
// 磁钢信号
QString strFirst = i.left(1);
QString strOther = i.mid(1, i.size() - 1);
// 将接收到的RFID使用@符拼接起来以待后续上传web
this->rfidSourceInfo.append("@" + i);
split_lambda(strFirst, strOther);
}
else if (i.size() == 14) // 特殊情况,来车信号少了&符
{
// 不使用磁钢的情况下 过滤掉磁钢信号
if (!this->baseConfig_.havaMagnetSteel) continue;
for (int j = 0; j < i.size(); j+=7) {
QString rfid_cg = i.mid(j, 7);
QString strFirst = rfid_cg.left(1);
QString strOther = rfid_cg.mid(1, 6);
// 将接收到的RFID使用@符拼接起来以待后续上传web
this->rfidSourceInfo.append("@" + rfid_cg);
split_lambda(strFirst, strOther);
}
}
}
}
void MainWindow::upRfid()
void MainWindow::upRfid(QString rfidInfo)
{
if (!this->baseConfig_.upResult) return;
if (!this->needIdentify && this->baseConfig_.havaMagnetSteel)
@ -804,14 +840,29 @@ void MainWindow::upRfid()
info = info.mid(1,info.size() - 1);
std::string carriageType = info.left(6).simplified().toStdString();
std::string carriageNum = info.mid(6, info.size() - 6).simplified().toStdString();
std::string nowTime = this->trainTime.toStdString();
std::string strOrder = QString::number(order).toStdString();
if (!this->upWeb(carriageType, carriageNum, strOrder, nowTime))
{
this->logError("" + QString::fromStdString(strOrder) + "节,识别结果上传失败!");
}
TrainInfo trainInfo;
trainInfo.carriageType = info.left(6).simplified().toStdString();
trainInfo.carriageNum = info.mid(6, info.size() - 6).simplified().toStdString();
trainInfo.strOrder = QString::number(order).toStdString();
trainInfo.nowTime = this->trainTime.toStdString();
trainInfo.strRfidInfo = rfidInfo.toStdString();
this->queueTrainInfo_.push(trainInfo);
auto up = QtConcurrent::run([=](){
while (!this->queueTrainInfo_.isEmpty())
{
TrainInfo trainInfo = this->queueTrainInfo_.pop();
if (!this->upWeb(trainInfo.carriageType,
trainInfo.carriageNum,
trainInfo.strOrder,
trainInfo.nowTime,
trainInfo.strRfidInfo))
{
this->logError("" + QString::fromStdString(trainInfo.strOrder) + "节,识别结果上传失败!");
}
}
return true;
});
}
void MainWindow::IdentifyTypeUpdate() {
@ -821,6 +872,7 @@ void MainWindow::IdentifyTypeUpdate() {
{
this->logInfo("来车了");
this->mkRfidLog();
this->vecTrain.clear();
this->needIdentify = true;
this->trainTime = this->getSystemTime();
this->resultTableModel_->clear();

View File

@ -43,6 +43,7 @@
#include <QListView>
#include <QMenuBar>
#include <QStatusBar>
#include <QtConcurrent>
#include <queue>
#include <mutex>
#include <thread>
@ -52,6 +53,7 @@
#include "ComDetect.h"
#include "TcpClient.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
@ -63,18 +65,24 @@ class MainWindow : public QWidget
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void logDebug(const QString& message);
void logInfo(const QString& message);
void logWarn(const QString& message);
void logError(const QString& message);
bool mkRfidLog();
void deleteOldFiles(const QString &path, int days);
bool rnameRfidLog();
void saveRfidLog(const QString &value);
void initParam();
bool upWeb(std::string &carriageType, std::string &carriageNumber, std::string &carriageOrder, std::string &time);
bool upWeb(std::string &carriageType,
std::string &carriageNumber,
std::string &carriageOrder,
std::string &time,
std::string &rfidSourceInfo);
bool getToken();
QString getSystemTime();
@ -83,8 +91,6 @@ public:
QList<QString> getComList();
// 将所有串口const 展示在下&拉列表
void initComboBox();
// 设置菜单项
void initMenu();
// 创建日志目录
static bool mkLogDir();
// 获取QStandardItem
@ -92,6 +98,13 @@ public:
QStandardItem* getStandardItem(const QString &value);
private:
struct TrainInfo {
std::string carriageType;
std::string carriageNum;
std::string strOrder;
std::string nowTime;
std::string strRfidInfo;
};
QString trainTime;
QString logRfidRecvName;
@ -116,6 +129,8 @@ private:
// 整列车识别结果存储
QStringList vecTrain;
MQueue<QString> queue_{}; // RFID读取的数据队列
MQueue<TrainInfo> queueTrainInfo_{}; // RFID读取的磁钢信息队列
QString rfidSourceInfo;
QString tmpRfid; //临时存储的RFID原始数据用于防止接收的数据不完整
// 识别方向正确标志
@ -149,14 +164,14 @@ private:
signals:
void getRfid_signals();
void upRfid_signals();
void upRfid_signals(QString rfidInfo);
void connect_socket(QString ip, int port);
void IdentifyType();
private slots:
void openComClicked();
void readCom();
void getQueueDataThread();
void upRfid();
void upRfid(QString rfidInfo);
void serialPort_error(QSerialPort::SerialPortError error);
void on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason);
void readTestInfo();

View File

@ -42,6 +42,8 @@ QSerialPort* ComDetect::openCom(const QString &com, int baud)
this->serial_->setDataBits(QSerialPort::Data8); //数据位
this->serial_->setStopBits(QSerialPort::OneStop);//停止位停止位默认选择1位
this->serial_->setFlowControl(QSerialPort::NoFlowControl);// 控制流,默认选择无
this->serial_->setReadBufferSize(1024); // 设置读取的缓冲区1024字节
if (this->serial_->open(QSerialPort::ReadWrite))
{
this->serial_->clear(QSerialPort::AllDirections);