版权声明:DfrY https://blog.csdn.net/dfy1407/article/details/88229807
ui界面
程序结构图
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <QString>
class global
{
public:
global();
static QString ComPortName;
static QString Tor;
};
#endif // GLOBAL_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "plctimerthread.h"
#include "plcthread.h"
#include <QTimer>
#include <QTime>
#include <QDebug>
#include <QString>
#include <QThread>
#include <QDebug>
#include "global.h"
#include <QModbusDataUnit>
#include <QModbusRtuSerialMaster>
#include <QModbusClient>
#include <QModbusReply>
#include <QSerialPort>
#include <QSerialPortInfo>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QThread *thread;
PlcTimerThread *plcThread;
QThread *qthreadPlc;
PlcThread *plc;
signals:
void sendSpinbox(int);
void writeTor(QString);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void showTime(QString);
void on_spinBox_valueChanged();
void on_connectModbus_clicked();
void on_searchPort_clicked();
void on_writeT_clicked();
void on_statusBar(const QString&);
void on_change2Discon();
void on_change2Con();
void on_updateT(QString);
void on_updateS(QString);
};
#endif // MAINWINDOW_H
plcthread.h
#ifndef PLCTHREAD_H
#define PLCTHREAD_H
#include <QObject>
#include <QModbusDataUnit>
#include <QModbusRtuSerialMaster>
#include <QModbusClient>
#include <QModbusReply>
#include <QSerialPort>
#include <QSerialPortInfo>
#include "global.h"
#include <QString>
#include <QDebug>
#include <QThread>
#include <QTimer>
class PlcThread : public QObject
{
Q_OBJECT
public:
explicit PlcThread(QObject *parent = nullptr);
~PlcThread();
void doWork();
void connectPlc();
void readPlc();
void torqReadReady();
void spdReadReady();
void on_writeTor(QString);
signals:
void startWork();
void finishWork();
void statusBar(const QString&);
void change2Discon();
void change2Con();
void updateT(QString);
void updateS(QString);
public slots:
private:
QModbusClient *modbusDevice;
QTimer *dataTimer;
uchar T[4];
uchar S[4];
};
#endif // PLCTHREAD_H
plctimerthread.h
#ifndef PLCTIMERTHREAD_H
#define PLCTIMERTHREAD_H
#include <QObject>
#include <QTimer>
#include <QDebug>
#include <QTime>
#include <QString>
#include "ui_mainwindow.h"
#include <QMainWindow>
#include <QModbusDataUnit>
#include <QModbusRtuSerialMaster>
#include <QModbusClient>
#include <QModbusReply>
#include <QSerialPort>
#include <QSerialPortInfo>
class PlcTimerThread : public QObject
{
Q_OBJECT
public:
explicit PlcTimerThread(QObject *parent = nullptr);
~PlcTimerThread();
public:
void run();
void dowork();
void printSpinBox(int);
signals:
void workStart();
void workFinished();
void upDateTime(QString);
private:
QTimer *timer;
QString str_time;
int spinbox;
public slots:
};
#endif // PLCTIMERTHREAD_H
global.cpp
#include "global.h"
QString global::ComPortName;
QString global::Tor;
global::global()
{
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "plctimerthread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
plcThread = new PlcTimerThread();
thread =new QThread();
plcThread->moveToThread(thread);
plc = new PlcThread;
qthreadPlc =new QThread();
plc->moveToThread(qthreadPlc);
/*********************/
// connect(thread,&QThread::started,plcThread,&PlcTimerThread::run);
connect(plcThread,&PlcTimerThread::workStart,plcThread,&PlcTimerThread::run);
connect(plcThread,&PlcTimerThread::workFinished,thread,&QThread::quit);
connect(thread,&QThread::finished,thread,&QThread::deleteLater);
connect(plcThread,&PlcTimerThread::upDateTime,this,&MainWindow::showTime);
connect(this,&MainWindow::sendSpinbox,plcThread,&PlcTimerThread::printSpinBox);
thread->start();
qDebug()<<"开启线程";
/*******x线程2******/
connect(qthreadPlc,&QThread::started,plc,&PlcThread::doWork);
connect(plc,&PlcThread::startWork,plc,&PlcThread::connectPlc);
connect(plc,&PlcThread::finishWork,qthreadPlc,&QThread::quit);
connect(qthreadPlc,&QThread::finished,qthreadPlc,&QThread::deleteLater);
connect(plc,&PlcThread::statusBar,this,&MainWindow::on_statusBar);
connect(plc,&PlcThread::change2Con,this,&MainWindow::on_change2Con);
connect(plc,&PlcThread::change2Discon,this,&MainWindow::on_change2Discon);
connect(plc,&PlcThread::updateT,this,&MainWindow::on_updateT);
connect(plc,&PlcThread::updateS,this,&MainWindow::on_updateS);
connect(this,&MainWindow::writeTor,plc,&PlcThread::on_writeTor);
qthreadPlc->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()//start
{
qDebug()<<"主线程ID:"<<QThread::currentThread();
emit plcThread->workStart();
}
void MainWindow::on_pushButton_2_clicked()
{
qDebug()<<"主线程ID:"<<QThread::currentThread(); //显示当前线程的数值
}
void MainWindow::on_pushButton_3_clicked()//进入线程
{
plcThread = new PlcTimerThread();
thread =new QThread();
plcThread->moveToThread(thread);
// connect(thread,&QThread::started,plcThread,&PlcTimerThread::run);
connect(plcThread,&PlcTimerThread::workStart,plcThread,&PlcTimerThread::run);
connect(this,&MainWindow::destroyed,plcThread,&PlcTimerThread::workFinished);
connect(plcThread,&PlcTimerThread::workFinished,thread,&QThread::quit);
connect(thread,&QThread::finished,thread,&QThread::deleteLater);
connect(plcThread,&PlcTimerThread::upDateTime,this,&MainWindow::showTime);
thread->start();
qDebug()<<"开启线程";
}
void MainWindow::on_pushButton_4_clicked()//退出线程
{
emit plcThread->workFinished();
qDebug()<<"退出线程";
}
// thread->quit();
void MainWindow::showTime(QString time)
{
ui->lineEdit->setText(time);
}
void MainWindow::on_spinBox_valueChanged()
{
qDebug()<<"changed";
emit sendSpinbox(ui->spinBox->value());
}
void MainWindow::on_connectModbus_clicked()
{
global::ComPortName = ui->serialBox->currentText();
emit plc->startWork();
qDebug()<<"click con";
}
void MainWindow::on_searchPort_clicked()
{
ui->serialBox->clear();
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
ui->serialBox->addItem(info.portName());
}
}
void MainWindow::on_writeT_clicked()
{
QString str1 = ui->torque->text();
QByteArray str2 = QByteArray::fromHex (str1.toLatin1().data());
global::Tor = str2.toHex().data();
qDebug()<<global::Tor;
emit writeTor(global::Tor);
}
void MainWindow::on_statusBar(const QString &message)
{
statusBar()->showMessage(message,5000);
}
void MainWindow::on_change2Discon()
{
ui->connectModbus->setText("disconnectModbus");
}
void MainWindow::on_change2Con()
{
ui->connectModbus->setText("connectModbus");
}
void MainWindow::on_updateT(QString t)
{
ui->readT->setText(t);
}
void MainWindow::on_updateS(QString s)
{
ui->readS->setText(s);
}
plcthread.cpp
#include "plcthread.h"
#include <QSerialPort>
#include <QSerialPortInfo>
PlcThread::PlcThread(QObject *parent) : QObject(parent)
{
}
PlcThread::~PlcThread()
{
}
void PlcThread::doWork()
{
modbusDevice = new QModbusRtuSerialMaster;
dataTimer = new QTimer;
connect(dataTimer,&QTimer::timeout,this,&PlcThread::readPlc);
}
void PlcThread::connectPlc()
{
qDebug()<<"connect";
qDebug()<<"显示plc线程ID:"<<QThread::currentThread(); //显示当前线程的数值
if(!modbusDevice)
{
return;
}
// statusBar()->clearMessage();
if(modbusDevice->state() != QModbusDevice::ConnectedState)
{
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,global::ComPortName);
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,QSerialPort::EvenParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,QSerialPort::Baud9600);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,QSerialPort::OneStop);
modbusDevice->setTimeout(1000);
modbusDevice->setNumberOfRetries(3);
if(!modbusDevice->connectDevice())//连接失败
{
//statusBar()->showMessage(tr("Connect Failed:") + modbusDevice->errorString(),5000);
emit statusBar(tr("Connect Failed:") + modbusDevice->errorString());
}
else//成功连接
{
emit change2Discon();
dataTimer->start(500);
}
}
else
{
modbusDevice->disconnectDevice();
dataTimer->stop();
emit change2Con();
}
qDebug() << modbusDevice->state();
}
void PlcThread::readPlc()
{
qDebug()<<"read";
if (!modbusDevice)
{
return;
}
//statusBar()->clearMessage();
emit statusBar(nullptr);
QModbusDataUnit readUnit = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 2);
if (auto *reply = modbusDevice->sendReadRequest(readUnit, 1)) //1->modbus设备地址
{
if (!reply->isFinished())
{
connect(reply, &QModbusReply::finished, this, &PlcThread::torqReadReady);
}
else
{
delete reply; // broadcast replies return immediately
}
}
else
{
//statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
emit statusBar(tr("Read error: ") + modbusDevice->errorString());
}
/**/
QModbusDataUnit readUnit2 = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 2, 2);
if (auto *reply = modbusDevice->sendReadRequest(readUnit2, 1)) //1->modbus设备地址
{
if (!reply->isFinished())
{
connect(reply, &QModbusReply::finished, this, &PlcThread::spdReadReady);
}
else
{
delete reply; // broadcast replies return immediately
}
}
else
{
//statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
emit statusBar(tr("Read error: ") + modbusDevice->errorString());
}
}
void PlcThread::torqReadReady()
{
auto reply = qobject_cast<QModbusReply *>(sender());
if (!reply)
{
return;
}
if (reply->error() == QModbusDevice::NoError)
{
const QModbusDataUnit unit = reply->result();
for (uint i = 0; i < unit.valueCount(); i++)
{
int ii = static_cast<int>(i);
QString str =QString("%1").arg(unit.value(ii),4,16,QLatin1Char('0'));
qDebug()<<str;
bool ok;
T[3-2*ii]= static_cast<uchar>(str.mid(0,2).toInt(&ok,16));
T[2-2*ii]= static_cast<uchar>(str.mid(2,4).toInt(&ok,16));
}
float f_T;
memcpy_s(&f_T , sizeof(float) , T , 4);
qDebug()<<f_T;
//ui->readT->setText(QString::number(static_cast<double>(f_T) ));
emit updateT(QString::number(static_cast<double>(f_T) ));
}
else if (reply->error() == QModbusDevice::ProtocolError)
{
// statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
// arg(reply->errorString()).
// arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
emit statusBar(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16));
}
else
{
// statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
// arg(reply->errorString()).
// arg(reply->error(), -1, 16), 5000);
emit statusBar(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()).
arg(reply->error(), -1, 16));
}
reply->deleteLater();
}
void PlcThread::spdReadReady()
{
auto reply2 = qobject_cast<QModbusReply *>(sender());
if (!reply2)
{
return;
}
if (reply2->error() == QModbusDevice::NoError)
{
const QModbusDataUnit unit = reply2->result();
for (uint i = 0; i < unit.valueCount(); i++)
{
int ii = static_cast<int>(i);
QString str =QString("%1").arg(unit.value(ii),4,16,QLatin1Char('0'));
qDebug()<<str;
bool ok;
S[3-2*ii]= static_cast<uchar>(str.mid(0,2).toInt(&ok,16));
S[2-2*ii]= static_cast<uchar>(str.mid(2,4).toInt(&ok,16));
}
float f_S;
memcpy_s(&f_S , sizeof(float) , S , 4);
qDebug()<<f_S;
// ui->readS->setText(QString::number(static_cast<double>(f_S) ));
emit updateS(QString::number(static_cast<double>(f_S) ));
}
else if (reply2->error() == QModbusDevice::ProtocolError)
{
// statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
// arg(reply2->errorString()).
// arg(reply2->rawResult().exceptionCode(), -1, 16), 5000);
emit statusBar(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply2->errorString()).
arg(reply2->rawResult().exceptionCode(), -1, 16));
}
else
{
// statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
// arg(reply2->errorString()).
// arg(reply2->error(), -1, 16), 5000);
emit statusBar(tr("Read response error: %1 (code: 0x%2)").
arg(reply2->errorString()).
arg(reply2->error(), -1, 16));
}
reply2->deleteLater();
}
void PlcThread::on_writeTor(QString t)
{
if (!modbusDevice)
return;
//statusBar()->clearMessage();
emit statusBar(nullptr);
//QModbusDataUnit的参数::QModbusDataUnit(QModbusDataUnit::HoldingRegisters, startAddress, numberOfEntries)
QModbusDataUnit writeUnit = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 4, 2);
for (uint i = 0; i < writeUnit.valueCount(); i++)
{
int ii = static_cast<int>(i);
//writeUnit.setValue(ii, holdingRegisters[ii + writeUnit.startAddress()]);
int j = 4*ii;
QString st = t.mid (j,4);
bool ok;
int hex =st.toInt(&ok,16);//将textedit中读取到的数据转换为16进制发送
quint16 qhex =static_cast<quint16>(hex);
// qDebug()<<writeUnit.valueCount();
writeUnit.setValue(ii,qhex);
}
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 1)) {//1->modbus 地址
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, this, [this, reply]() {
if (reply->error() == QModbusDevice::ProtocolError)
{
// statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
// .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
// 5000);
emit statusBar(tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));
} else if (reply->error() != QModbusDevice::NoError)
{
// statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
// arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
emit statusBar(tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16));
}
reply->deleteLater();
});
} else {
// broadcast replies return immediately
reply->deleteLater();
}
} else {
//statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
emit statusBar(tr("Write error: ") + modbusDevice->errorString());
}
}
plctimerthread.cpp
#include "plctimerthread.h"
#include <QThread>
//static int timerCount = 0;
PlcTimerThread::PlcTimerThread(QObject *parent) : QObject(parent)
{
}
PlcTimerThread::~PlcTimerThread()
{
}
void PlcTimerThread::run()
{
// emit workStart();
// timer = new QTimer(this);
// connect(timer,&QTimer::timeout,this,&PlcTimerThread::dowork);
// timer->start(1000);
qDebug()<<"run";
dowork();
}
void PlcTimerThread::dowork()
{
// timerCount ++;
// if (timerCount > 100)
// {
// emit workFinished();
// }
//qDebug()<<QTime::currentTime()<<endl;
qDebug()<<"显示时间线程ID:"<<QThread::currentThread(); //显示当前线程的数值
QDateTime time = QDateTime::currentDateTime();
str_time = time.toString("yyyy-MM-dd hh:mm:ss dddd");
emit upDateTime(str_time);
}
void PlcTimerThread::printSpinBox(int spin)
{
spinbox = spin;
qDebug()<<"changed"<<spin;
qDebug()<<"线程ID:"<<QThread::currentThread(); //显示当前线程的数值
}