赞
踩
可以查看这篇文章:https://blog.csdn.net/weixin_39510813/article/details/115027911?spm=1001.2014.3001.5501
打开Qt creator后在示例中搜索Modbus,可以看到Modbus主/从的两个示例。
我们将master和slave都运行起来,可以看到Modbus\TCP协议的Port是502,本地使用的127.0.0.1的IP地址,然后我们点击connect开始server,下面的勾选是输入和接收输出的回调,右侧客户端的Holding Registers输入要发送的值,左侧服务端我们将各个字节勾选上,然后左侧Input Registers的各个字节输入要发送的内容,之后点击客户端的Read-Write进行读写测试即可:
我们通过tree /f查看文件树:
C:\Qt\Qt5.9.1\Examples\Qt-5.9.1\serialbus\modbus\slave>tree /f 文件夹 PATH 列表 卷序列号为 00000087 0856:6C30 C:. │ main.cpp │ mainwindow.cpp │ mainwindow.h │ mainwindow.ui │ settingsdialog.cpp │ settingsdialog.h │ settingsdialog.ui │ slave.pro │ slave.pro.user │ slave.qrc │ ├─doc │ ├─images │ │ modbusserver.png │ │ │ └─src │ modbusslave.qdoc │ └─images application-exit.png connect.png disconnect.png settings.png
可以看出来基本就是main、mainwindow、settingsdialog(settingdialog是对串口属性的设置,所以这里也不用看了)相关的内容,所以我们只需要看两个cpp文件就差不多可以掌握Qt5关于Modbus/TCP的接口使用了,此外可能就是检查一下.pro里面如何添加modbus相关的模块到我们的项目中。
main.cpp(注意一下如何获取modbus的日志即可,其它的没有啥特别的):
#include "mainwindow.h" #include <QApplication> #include <QLoggingCategory> int main(int argc, char *argv[]) { // TODO uncomment this line before release // right now we always need it QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true")); QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.cpp:
初始化->建立连接:通看的话基本上就是initActions->on_connectButton_clicked来确认进行modbus类型选择以及判断是否已连接,如果是modbus/tcp的话则设置端口和url即可,一般来说端口就是502,url则需要根据我们局域网配置的url来定。
读写:setRegister、updateWidgets两个槽函数中有读写的接口,在on_connectType_currentIndexChanged方法中我们点击connect建立连接后就可以对server设置读取的信号槽连接。
#include "mainwindow.h" #include "settingsdialog.h" #include "ui_mainwindow.h" #include <QModbusRtuSerialSlave> #include <QModbusTcpServer> #include <QRegularExpression> #include <QStatusBar> #include <QUrl> enum ModbusConnection { Serial, Tcp }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , modbusDevice(nullptr) { ui->setupUi(this); setupWidgetContainers(); ui->connectType->setCurrentIndex(0); on_connectType_currentIndexChanged(0); m_settingsDialog = new SettingsDialog(this); initActions(); } MainWindow::~MainWindow() { if (modbusDevice) modbusDevice->disconnectDevice(); delete modbusDevice; delete ui; } void MainWindow::initActions() { ui->actionConnect->setEnabled(true); ui->actionDisconnect->setEnabled(false); ui->actionExit->setEnabled(true); ui->actionOptions->setEnabled(true); connect(ui->actionConnect, &QAction::triggered, this, &MainWindow::on_connectButton_clicked); connect(ui->actionDisconnect, &QAction::triggered, this, &MainWindow::on_connectButton_clicked); connect(ui->actionExit, &QAction::triggered, this, &QMainWindow::close); connect(ui->actionOptions, &QAction::triggered, m_settingsDialog, &QDialog::show); } void MainWindow::on_connectType_currentIndexChanged(int index) { if (modbusDevice) { modbusDevice->disconnect(); delete modbusDevice; modbusDevice = nullptr; } ModbusConnection type = static_cast<ModbusConnection> (index); if (type == Serial) { modbusDevice = new QModbusRtuSerialSlave(this); } else if (type == Tcp) { modbusDevice = new QModbusTcpServer(this); if (ui->portEdit->text().isEmpty()) ui->portEdit->setText(QLatin1Literal("127.0.0.1:502")); } ui->listenOnlyBox->setEnabled(type == Serial); if (!modbusDevice) { ui->connectButton->setDisabled(true); if (type == Serial) statusBar()->showMessage(tr("Could not create Modbus slave."), 5000); else statusBar()->showMessage(tr("Could not create Modbus server."), 5000); } else { QModbusDataUnitMap reg; reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 }); reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 }); reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 }); reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 }); modbusDevice->setMap(reg); connect(modbusDevice, &QModbusServer::dataWritten, this, &MainWindow::updateWidgets); connect(modbusDevice, &QModbusServer::stateChanged, this, &MainWindow::onStateChanged); connect(modbusDevice, &QModbusServer::errorOccurred, this, &MainWindow::handleDeviceError); connect(ui->listenOnlyBox, &QCheckBox::toggled, this, [this](bool toggled) { if (modbusDevice) modbusDevice->setValue(QModbusServer::ListenOnlyMode, toggled); }); emit ui->listenOnlyBox->toggled(ui->listenOnlyBox->isChecked()); connect(ui->setBusyBox, &QCheckBox::toggled, this, [this](bool toggled) { if (modbusDevice) modbusDevice->setValue(QModbusServer::DeviceBusy, toggled ? 0xffff : 0x0000); }); emit ui->setBusyBox->toggled(ui->setBusyBox->isChecked()); setupDeviceData(); } } void MainWindow::handleDeviceError(QModbusDevice::Error newError) { if (newError == QModbusDevice::NoError || !modbusDevice) return; statusBar()->showMessage(modbusDevice->errorString(), 5000); } void MainWindow::on_connectButton_clicked() { bool intendToConnect = (modbusDevice->state() == QModbusDevice::UnconnectedState); statusBar()->clearMessage(); if (intendToConnect) { if (static_cast<ModbusConnection> (ui->connectType->currentIndex()) == Serial) { modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, ui->portEdit->text()); modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, m_settingsDialog->settings().parity); modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_settingsDialog->settings().baud); modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, m_settingsDialog->settings().dataBits); modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, m_settingsDialog->settings().stopBits); } else { const QUrl url = QUrl::fromUserInput(ui->portEdit->text()); modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port()); modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host()); } modbusDevice->setServerAddress(ui->serverEdit->text().toInt()); if (!modbusDevice->connectDevice()) { statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000); } else { ui->actionConnect->setEnabled(false); ui->actionDisconnect->setEnabled(true); } } else { modbusDevice->disconnectDevice(); ui->actionConnect->setEnabled(true); ui->actionDisconnect->setEnabled(false); } } void MainWindow::onStateChanged(int state) { bool connected = (state != QModbusDevice::UnconnectedState); ui->actionConnect->setEnabled(!connected); ui->actionDisconnect->setEnabled(connected); if (state == QModbusDevice::UnconnectedState) ui->connectButton->setText(tr("Connect")); else if (state == QModbusDevice::ConnectedState) ui->connectButton->setText(tr("Disconnect")); } void MainWindow::coilChanged(int id) { QAbstractButton *button = coilButtons.button(id); bitChanged(id, QModbusDataUnit::Coils, button->isChecked()); } void MainWindow::discreteInputChanged(int id) { QAbstractButton *button = discreteButtons.button(id); bitChanged(id, QModbusDataUnit::DiscreteInputs, button->isChecked()); } void MainWindow::bitChanged(int id, QModbusDataUnit::RegisterType table, bool value) { if (!modbusDevice) return; if (!modbusDevice->setData(table, id, value)) statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000); } void MainWindow::setRegister(const QString &value) { if (!modbusDevice) return; const QString objectName = QObject::sender()->objectName(); if (registers.contains(objectName)) { bool ok = true; const int id = QObject::sender()->property("ID").toInt(); if (objectName.startsWith(QStringLiteral("inReg"))) ok = modbusDevice->setData(QModbusDataUnit::InputRegisters, id, value.toInt(&ok, 16)); else if (objectName.startsWith(QStringLiteral("holdReg"))) ok = modbusDevice->setData(QModbusDataUnit::HoldingRegisters, id, value.toInt(&ok, 16)); if (!ok) statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(), 5000); } } void MainWindow::updateWidgets(QModbusDataUnit::RegisterType table, int address, int size) { for (int i = 0; i < size; ++i) { quint16 value; QString text; switch (table) { case QModbusDataUnit::Coils: modbusDevice->data(QModbusDataUnit::Coils, address + i, &value); coilButtons.button(address + i)->setChecked(value); break; case QModbusDataUnit::HoldingRegisters: modbusDevice->data(QModbusDataUnit::HoldingRegisters, address + i, &value); registers.value(QStringLiteral("holdReg_%1").arg(address + i))->setText(text .setNum(value, 16)); break; default: break; } } } // -- private void MainWindow::setupDeviceData() { if (!modbusDevice) return; for (int i = 0; i < coilButtons.buttons().count(); ++i) modbusDevice->setData(QModbusDataUnit::Coils, i, coilButtons.button(i)->isChecked()); for (int i = 0; i < discreteButtons.buttons().count(); ++i) { modbusDevice->setData(QModbusDataUnit::DiscreteInputs, i, discreteButtons.button(i)->isChecked()); } bool ok; for (QLineEdit *widget : qAsConst(registers)) { if (widget->objectName().startsWith(QStringLiteral("inReg"))) { modbusDevice->setData(QModbusDataUnit::InputRegisters, widget->property("ID").toInt(), widget->text().toInt(&ok, 16)); } else if (widget->objectName().startsWith(QStringLiteral("holdReg"))) { modbusDevice->setData(QModbusDataUnit::HoldingRegisters, widget->property("ID").toInt(), widget->text().toInt(&ok, 16)); } } } void MainWindow::setupWidgetContainers() { coilButtons.setExclusive(false); discreteButtons.setExclusive(false); QRegularExpression regexp(QStringLiteral("coils_(?<ID>\\d+)")); const QList<QCheckBox *> coils = findChildren<QCheckBox *>(regexp); for (QCheckBox *cbx : coils) coilButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt()); connect(&coilButtons, SIGNAL(buttonClicked(int)), this, SLOT(coilChanged(int))); regexp.setPattern(QStringLiteral("disc_(?<ID>\\d+)")); const QList<QCheckBox *> discs = findChildren<QCheckBox *>(regexp); for (QCheckBox *cbx : discs) discreteButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt()); connect(&discreteButtons, SIGNAL(buttonClicked(int)), this, SLOT(discreteInputChanged(int))); regexp.setPattern(QLatin1String("(in|hold)Reg_(?<ID>\\d+)")); const QList<QLineEdit *> qle = findChildren<QLineEdit *>(regexp); for (QLineEdit *lineEdit : qle) { registers.insert(lineEdit->objectName(), lineEdit); lineEdit->setProperty("ID", regexp.match(lineEdit->objectName()).captured("ID").toInt()); lineEdit->setValidator(new QRegExpValidator(QRegExp(QStringLiteral("[0-9a-f]{0,4}"), Qt::CaseInsensitive), this)); connect(lineEdit, &QLineEdit::textChanged, this, &MainWindow::setRegister); } }
同样我们先查看文件树:
C:\Qt\Qt5.9.1\Examples\Qt-5.9.1\serialbus\modbus\master>tree /f 文件夹 PATH 列表 卷序列号为 000000E4 0856:6C30 C:. │ main.cpp │ mainwindow.cpp │ mainwindow.h │ mainwindow.ui │ master.pro │ master.pro.user │ master.qrc │ settingsdialog.cpp │ settingsdialog.h │ settingsdialog.ui │ writeregistermodel.cpp │ writeregistermodel.h │ ├─doc │ ├─images │ │ modbusmaster.png │ │ │ └─src │ modbusmaster.qdoc │ └─images application-exit.png connect.png disconnect.png settings.png
基本和slave的接口类似,主要modbus\tcp相关的操作都是在mainwindow下,settingsdialog还是对串口的设置,writeregistermodel是对QAbstractTableModel的继承和部分接口重写,完成双击输入内容的功能。
建立连接:
modbusDevice = new QModbusTcpClient(this); if (ui->portEdit->text().isEmpty()) ui->portEdit->setText(QLatin1Literal("127.0.0.1:502")); modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port()); modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host()); void MainWindow::on_readWriteButton_clicked() { if (!modbusDevice) return; ui->readValue->clear(); statusBar()->clearMessage(); QModbusDataUnit writeUnit = writeRequest(); QModbusDataUnit::RegisterType table = writeUnit.registerType(); for (uint i = 0; i < writeUnit.valueCount(); i++) { if (table == QModbusDataUnit::Coils) writeUnit.setValue(i, writeModel->m_coils[i + writeUnit.startAddress()]); else writeUnit.setValue(i, writeModel->m_holdingRegisters[i + writeUnit.startAddress()]); } if (auto *reply = modbusDevice->sendReadWriteRequest(readRequest(), writeUnit, ui->serverEdit->value())) { if (!reply->isFinished()) connect(reply, &QModbusReply::finished, this, &MainWindow::readReady); else delete reply; // broadcast replies return immediately } else { statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); } } if (modbusDevice) modbusDevice->disconnectDevice(); delete modbusDevice;
打开Assistant,搜索QModbusTcp来查看QModbusTcpClient和QModbusTcpServer相关的内容(首先可以确定的是从Qt 5.8开始支持的):
下面是所有的实现的方法:
This is the complete list of members for QModbusTcpServer, including inherited members. enum ConnectionParameter enum Error enum Option enum State QModbusTcpServer(QObject *) ~QModbusTcpServer() blockSignals(bool ) childEvent(QChildEvent *) children() const close() close() connect(const QObject *, const char *, const QObject *, const char *, Qt::ConnectionType ) connect(const QObject *, const QMetaMethod &, const QObject *, const QMetaMethod &, Qt::ConnectionType ) connect(const QObject *, const char *, const char *, Qt::ConnectionType ) const connect(const QObject *, PointerToMemberFunction , const QObject *, PointerToMemberFunction , Qt::ConnectionType ) connect(const QObject *, PointerToMemberFunction , Functor ) connect(const QObject *, PointerToMemberFunction , const QObject *, Functor , Qt::ConnectionType ) connectDevice() : bool connectNotify(const QMetaMethod &) connectionParameter(int ) const : QVariant customEvent(QEvent *) d_ptr : data(QModbusDataUnit *) const : bool data(QModbusDataUnit::RegisterType , quint16 , quint16 *) const : bool dataWritten(QModbusDataUnit::RegisterType , int , int ) deleteLater() destroyed(QObject *) disconnect(const QObject *, const char *, const QObject *, const char *) disconnect(const QObject *, const QMetaMethod &, const QObject *, const QMetaMethod &) disconnect(const QMetaObject::Connection &) disconnect(const char *, const QObject *, const char *) const disconnect(const QObject *, const char *) const disconnect(const QObject *, PointerToMemberFunction , const QObject *, PointerToMemberFunction ) disconnectDevice() disconnectNotify(const QMetaMethod &) dumpObjectInfo() const dumpObjectTree() const dynamicPropertyNames() const error() const : Error errorOccurred(QModbusDevice::Error ) errorString() const : QString event(QEvent *) eventFilter(QObject *, QEvent *) findChild(const QString &, Qt::FindChildOptions ) const findChildren(const QString &, Qt::FindChildOptions ) const findChildren(const QRegExp &, Qt::FindChildOptions ) const findChildren(const QRegularExpression &, Qt::FindChildOptions ) const inherits(const char *) const installEventFilter(QObject *) isSignalConnected(const QMetaMethod &) const isWidgetType() const isWindowType() const killTimer(int ) metaObject() const moveToThread(QThread *) objectName() const objectNameChanged(const QString &) open() : bool open() : bool parent() const processPrivateRequest(const QModbusPdu &) : QModbusResponse processRequest(const QModbusPdu &) : QModbusResponse processRequest(const QModbusPdu &) : QModbusResponse processesBroadcast() const : bool property(const char *) const readData(QModbusDataUnit *) const : bool receivers(const char *) const removeEventFilter(QObject *) sender() const senderSignalIndex() const serverAddress() const : int setConnectionParameter(int , const QVariant &) setData(const QModbusDataUnit &) : bool setData(QModbusDataUnit::RegisterType , quint16 , quint16 ) : bool setError(const QString &, QModbusDevice::Error ) setMap(const QModbusDataUnitMap &) : bool setObjectName(const QString &) setParent(QObject *) setProperty(const char *, const QVariant &) setServerAddress(int ) setState(QModbusDevice::State ) setValue(int , const QVariant &) : bool signalsBlocked() const startTimer(int , Qt::TimerType ) startTimer(std::chrono::milliseconds , Qt::TimerType ) state() const : State stateChanged(QModbusDevice::State ) staticMetaObject : staticQtMetaObject : thread() const timerEvent(QTimerEvent *) tr(const char *, const char *, int ) value(int ) const : QVariant writeData(const QModbusDataUnit &) : bool
可以针对性的了解一些方法。
基本上对于上位机来说作为modbus/tcp服务器的情况比较多。
.pro中添加:
QT += core gui sql serialport serialbus
主要创建内容和读写操作(结合example和这里的例子):
#ifndef MODBUSSERVER_H #define MODBUSSERVER_H #include <QObject> #include <QModbusServer> #include <QModbusRtuSerialSlave> #include <QModbusTcpServer> #include <QSerialPort> /* * * * modbus slave 从站 * * modbusSlove_* m_slave = new modbusSlove_(this); * * initModbusSerialSlove() * * connectDevice() * * //寄存器值发生改变,连接这个信号 void registerData_signal(int address,int value); * */ class ModbusServer : public QObject { Q_OBJECT public: explicit ModbusServer(QObject *parent = nullptr); /** * @projectName testMyClass * @brief 初始化串口modbusSlave * 其他参数 波特率 数据位 校验位 停止位 * @author SMY * @date 2019-03-27 */ bool initModbusSerialServer(QString portName, qint32 baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits); /** * @projectName testMyClass * @brief 初始化网口modbusSlave * ip地址,端口号 * @author SMY * @date 2019-03-27 */ bool initModbusNetworkServer(QString address,int port); /** * @projectName testMyClass * @brief 连接设备 * @author SMY * @date 2019-03-27 */ bool connectDevice(); /** * @projectName testMyClass * @brief 网口还是串口连接 * @author SMY * @date 2019-03-26 */ enum modbusConnection { Serial, Tcp }; signals: //寄存器值发生改变 void registerData_signal(int address,int value); //发生错误 void error_signal(QString errorString); /*state :1 connect ,0:unconnect *状态发生改变 */ void stateChanged_signal(int state); public slots: private slots: /** * @projectName testMyClass * @brief 更新寄存器数据 * @author SMY * @date 2019-03-26 */ void updateData(QModbusDataUnit::RegisterType table, int address, int size); /** * @projectName testMyClass * @brief device error * @author SMY * @date 2019-03-27 */ void handleDeviceError(QModbusDevice::Error newError); /** * @projectName testMyClass * @brief 连接状态改变 * @author SMY * @date 2019-03-27 */ void onStateChanged(int state); private: modbusConnection m_mode; QModbusServer* modbusServer; }; #endif // MODBUSSERVER__H
#include "modbusserver.h" #include <QDebug> ModbusServer::ModbusServer(QObject *parent) : QObject(parent) { } bool ModbusServer::initModbusSerialServer(QString portName, qint32 baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits) { //串口 modbusServer = new QModbusRtuSerialSlave(this); m_mode = Serial; if(!modbusServer) { qDebug()<<"could not create modbus slave"; return 0; } QModbusDataUnitMap reg; reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 }); reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 }); reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 }); reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 }); modbusServer->setMap(reg); modbusServer->setConnectionParameter(QModbusDevice::SerialPortNameParameter, portName); modbusServer->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); modbusServer->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); modbusServer->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); modbusServer->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); //更新寄存器值 connect(modbusServer,&QModbusServer::dataWritten,this, &ModbusServer::updateData); //更新连接状态 connect(modbusServer, &QModbusServer::stateChanged, this, &ModbusServer::onStateChanged); //错误发生 connect(modbusServer, &QModbusServer::errorOccurred, this, &ModbusServer::handleDeviceError); return 1; } bool ModbusServer::initModbusNetworkServer(QString address, int port) { // if(modbusServer) // { // modbusServer->disconnect(); // delete modbusServer; // modbusServer = nullptr; // } //网口 modbusServer = new QModbusTcpServer(this); m_mode = Tcp; if(!modbusServer) { qDebug()<<"could not create modbus slave"; return false; } QModbusDataUnitMap reg; reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 }); reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 }); reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 }); reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 }); modbusServer->setMap(reg); modbusServer->setConnectionParameter(QModbusDevice::NetworkAddressParameter,address); modbusServer->setConnectionParameter(QModbusDevice::NetworkPortParameter,port); //更新寄存器值 connect(modbusServer,&QModbusServer::dataWritten,this, &ModbusServer::updateData); //更新连接状态 connect(modbusServer, &QModbusServer::stateChanged, this, &ModbusServer::onStateChanged); //错误发生 connect(modbusServer, &QModbusServer::errorOccurred, this, &ModbusServer::handleDeviceError); return true; } bool ModbusServer::connectDevice() { //设置modbusServer的modbus地址固定为1 modbusServer->setServerAddress(1); return modbusServer->connectDevice(); } void ModbusServer::updateData(QModbusDataUnit::RegisterType table, int address, int size) { for (int i = 0; i < size; ++i) { quint16 value; QString text; switch (table) { case QModbusDataUnit::Coils: modbusServer->data(QModbusDataUnit::Coils, address + i, &value); break; case QModbusDataUnit::HoldingRegisters: modbusServer->data(QModbusDataUnit::HoldingRegisters, address + i, &value); break; default: break; } emit registerData_signal(address+i,value); } } void ModbusServer::handleDeviceError(QModbusDevice::Error newError) { if(newError == QModbusDevice::NoError || !modbusServer) return; emit error_signal(modbusServer->errorString()); } void ModbusServer::onStateChanged(int state) { if(state == QModbusDevice::UnconnectedState) emit stateChanged_signal(0); else if(state == QModbusDevice::ConnectedState) emit stateChanged_signal(1); }
main.cpp中添加modbus协议调试(参考示例):
QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true"));
调用我们封装的modbusServer类:
ModbusServer *modbusServer = new ModbusServer(this);
modbusServer->initModbusNetworkServer("127.0.0.1", 502);
modbusServer->connectDevice();
其实还应该添加析构方法断开连接释放资源,自己加一下哦~
接收成功了,我们可以根据需求再进行一些修改:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。