代码拉取完成,页面将自动刷新
同步操作将从 moonan/ModbusSlave 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QModbusRtuSerialSlave>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowFlags(windowFlags()& ~Qt::WindowMaximizeButtonHint);
setFixedSize(this->width(), this->height());
this->setWindowTitle("ModbusSlave");
InitialSetting();
InitialInterfaceariables();
InitialSlaveDatas();
}
MainWindow::~MainWindow()
{
delete ui;
}
//初始化配置
void MainWindow::InitialSetting()
{
//填充串口号组合框
SearchSerialPorts();
//填充串口波特率
QStringList baud={"4800","9600","14400","19200","28800","38400","56000","57600","115200","128000","230400","256000"};
ui->comboBoxBaud->addItems(baud);
ui->comboBoxBaud->setCurrentIndex(1);
//填充串口数据位
ui->comboBoxData->addItem("7位");
ui->comboBoxData->addItem("8位");
ui->comboBoxData->addItem("9位");
ui->comboBoxData->setCurrentIndex(1);
//填充串口校验位
ui->comboBoxParity->addItem("无校验");
ui->comboBoxParity->addItem("奇校验");
ui->comboBoxParity->addItem("偶校验");
//填充串口停止位
ui->comboBoxStop->addItem("1位");
ui->comboBoxStop->addItem("1.5位");
ui->comboBoxStop->addItem("2位");
modbusDevice = new QModbusRtuSerialSlave(this);
}
//搜索串口
void MainWindow::SearchSerialPorts()
{
ui->comboBoxPort->clear();
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
ui->comboBoxPort->addItem(info.portName());
}
}
//初始化从站数据
void MainWindow::InitialSlaveDatas()
{
if (!modbusDevice)
return;
QModbusDataUnitMap reg;
reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 16 });
reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 16 });
reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 16 });
reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 16 });
modbusDevice->setMap(reg);
connect(modbusDevice, &QModbusServer::dataWritten,this, &MainWindow::UpdateDisplayBySlave);
connect(modbusDevice, &QModbusServer::stateChanged,this, &MainWindow::SlaveStateChanged);
connect(modbusDevice, &QModbusServer::errorOccurred,this, &MainWindow::HandleDeviceError);
for (quint16 i = 0; i < coilButtons.buttons().count(); ++i)
{
modbusDevice->setData(QModbusDataUnit::Coils, i, coilButtons.button(i)->isChecked());
}
for (quint16 i = 0; i < discreteButtons.buttons().count(); ++i)
{
modbusDevice->setData(QModbusDataUnit::DiscreteInputs, i,discreteButtons.button(i)->isChecked());
}
bool ok;
for (QLineEdit *widget : qAsConst(inputRegisters))
{
modbusDevice->setData(QModbusDataUnit::InputRegisters, quint16(widget->property("ID").toUInt()),widget->text().toUShort(&ok, 16));
}
for (QLineEdit *widget : qAsConst(holdingRegisters))
{
modbusDevice->setData(QModbusDataUnit::HoldingRegisters, quint16(widget->property("ID").toUInt()),widget->text().toUShort(&ok, 16));
}
}
//根据从站的变化更新数据显示
void MainWindow::UpdateDisplayBySlave(QModbusDataUnit::RegisterType table, int address, int size)
{
qDebug()<<"table:"<<table<<"address:"<<address<<"size:"<<size<<endl;
for (int i = 0; i < size; ++i)
{
quint16 value;
QString text;
switch (table)
{
case QModbusDataUnit::Coils:
{
modbusDevice->data(QModbusDataUnit::Coils, quint16(address + i), &value);
coilButtons.button(address + i)->setChecked(value);
break;
}
case QModbusDataUnit::HoldingRegisters:
{
modbusDevice->data(QModbusDataUnit::HoldingRegisters, quint16(address + i), &value);
qDebug()<<value;
holdingRegisters.value(QStringLiteral("holdReg%1").arg(address + i))->setText(text.setNum(value, 16));
break;
}
default:
break;
}
}
}
//设备错误处理
void MainWindow::HandleDeviceError(QModbusDevice::Error newError)
{
if (newError == QModbusDevice::NoError || !modbusDevice)
return;
statusBar()->showMessage(modbusDevice->errorString(), 5000);
}
//从站状态改变响应
void MainWindow::SlaveStateChanged(int state)
{
bool connected = (state != QModbusDevice::UnconnectedState);
ui->pushButtonConnect->setEnabled(!connected);
ui->pushButtonDisconnect->setEnabled(connected);
}
//初始化设定寄存器对应的界面变量
void MainWindow::InitialInterfaceariables()
{
coilButtons.setExclusive(false);
discreteButtons.setExclusive(false);
QRegularExpression regexp(QStringLiteral("coil(?<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("state(?<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("inReg(?<ID>\\d+)"));
const QList<QLineEdit *> inreg = findChildren<QLineEdit *>(regexp);
qDebug()<<inreg.size();
for (QLineEdit *lineEdit : inreg) {
inputRegisters.insert(lineEdit->objectName(), lineEdit);
lineEdit->setProperty("ID", regexp.match(lineEdit->objectName()).captured("ID").toInt());
lineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9a-f]{0,4}"),
QRegularExpression::CaseInsensitiveOption), this));
connect(lineEdit, &QLineEdit::textChanged, this, &MainWindow::setInputRegister);
}
regexp.setPattern(QLatin1String("holdReg(?<ID>\\d+)"));
const QList<QLineEdit *> holdreg = findChildren<QLineEdit *>(regexp);
qDebug()<<holdreg.size();
for (QLineEdit *lineEdit : holdreg) {
holdingRegisters.insert(lineEdit->objectName(), lineEdit);
lineEdit->setProperty("ID", regexp.match(lineEdit->objectName()).captured("ID").toInt());
lineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9a-f]{0,4}"),
QRegularExpression::CaseInsensitiveOption), this));
connect(lineEdit, &QLineEdit::textChanged, this, &MainWindow::setHoldingRegister);
}
}
void MainWindow::coilChanged(int id)
{
if(!modbusDevice)
{
return;
}
QAbstractButton *button = coilButtons.button(id);
if (!modbusDevice->setData(QModbusDataUnit::Coils, quint16(id), button->isChecked()))
{
statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000);
}
}
void MainWindow::discreteInputChanged(int id)
{
if(!modbusDevice)
{
return;
}
QAbstractButton *button = discreteButtons.button(id);
if (!modbusDevice->setData(QModbusDataUnit::DiscreteInputs, quint16(id), button->isChecked()))
{
statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000);
}
}
void MainWindow::setInputRegister(const QString &value)
{
if(!modbusDevice)
{
return;
}
const QString objectName = QObject::sender()->objectName();
if(inputRegisters.contains(objectName))
{
bool ok = true;
const quint16 id = quint16(QObject::sender()->property("ID").toUInt());
if (objectName.startsWith(QStringLiteral("inReg")))
{
if(!modbusDevice->setData(QModbusDataUnit::InputRegisters, id, value.toUShort(&ok, 16)))
{
statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),5000);
}
}
}
}
void MainWindow::setHoldingRegister(const QString &value)
{
if(!modbusDevice)
{
return;
}
const QString objectName = QObject::sender()->objectName();
if(holdingRegisters.contains(objectName))
{
bool ok = true;
const quint16 id = quint16(QObject::sender()->property("ID").toUInt());
qDebug()<<id;
if (objectName.startsWith(QStringLiteral("holdReg")))
{
if(!modbusDevice->setData(QModbusDataUnit::HoldingRegisters, id, value.toUShort(&ok, 16)))
{
statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),5000);
}
}
}
}
void MainWindow::on_pushButtonConnect_clicked()
{
bool intendToConnect = (modbusDevice->state() == QModbusDevice::UnconnectedState);
statusBar()->clearMessage();
if (intendToConnect)
{
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,ui->comboBoxPort->currentText());
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,QSerialPort::NoParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,ui->comboBoxBaud->currentText().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,QSerialPort::OneStop);
modbusDevice->setServerAddress(ui->spinBoxStation->text().toInt());
if (!modbusDevice->connectDevice())
{
statusBar()->showMessage(tr("连接失败: ") + modbusDevice->errorString(), 5000);
}
else
{
ui->pushButtonConnect->setEnabled(false);
ui->pushButtonDisconnect->setEnabled(true);
}
}
}
void MainWindow::on_pushButtonDisconnect_clicked()
{
modbusDevice->disconnectDevice();
ui->pushButtonConnect->setEnabled(true);
ui->pushButtonDisconnect->setEnabled(false);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。