1 Star 0 Fork 2

liuchaonuaa / ModbusSlave

forked from moonan / ModbusSlave 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
mainwindow.cpp 10.29 KB
一键复制 编辑 原始数据 按行查看 历史
moonan 提交于 2023-10-03 13:39 . 首次发布
#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);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/liuchaonuaa/modbus-slave.git
git@gitee.com:liuchaonuaa/modbus-slave.git
liuchaonuaa
modbus-slave
ModbusSlave
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891