Modbus-Server
Das Beispiel implementiert eine Modbus-Server-Anwendung.
Das Beispiel fungiert als Modbus-Server. Es empfängt Standard-Modbus-Anfragen, passt seine internen Zustände entsprechend der Anfrage an und sendet die entsprechende Antwort zurück.
Dieses Beispiel muss in Verbindung mit dem Modbus-Client-Beispiel verwendet werden. Dieses Beispiel sollte gestartet und in den Empfangsmodus versetzt werden, bevor das Modbus-Client-Beispiel gestartet wird. Die anschließenden Interaktionen zwischen den beiden Beispielen erfolgen über das Modbus-Protokoll.
Wichtige Klassen, die in diesem Beispiel verwendet werden:

Erstellen eines QModbusServer
Für die Kommunikation ist eine Instanz von ` QModbusServer ` erforderlich. Je nach angegebenem Verbindungstyp kann das Beispiel eine Instanz von ` QModbusRtuSerialServer ` (für serielle Kommunikation) oder von ` QModbusTcpServer ` (für TCP-basierte Kommunikation) erstellen.
auto type = static_cast<ModbusConnection>(index);
if (type == Serial) {
#if QT_CONFIG(modbus_serialport)
modbusDevice = new QModbusRtuSerialServer(this);
// Try to fill in the first available serial port name if the line edit
// is empty, or contains a url (assume that ':' is only a part of url).
const auto ports = QSerialPortInfo::availablePorts();
const auto currentText = ui->portEdit->text();
if (!ports.isEmpty() && (currentText.isEmpty() || currentText.contains(u':')))
ui->portEdit->setText(ports.front().portName());
#endif
} else if (type == Tcp) {
modbusDevice = new QModbusTcpServer(this);
const QUrl currentUrl = QUrl::fromUserInput(ui->portEdit->text());
// Check if we already have <ip address>:<port>
if (currentUrl.port() <= 0)
ui->portEdit->setText(QLatin1String("127.0.0.1:50200"));
}Sobald der Server erstellt ist, wird die Registerzuordnung mithilfe der Methode ` QModbusServer::setMap()` festgelegt. Diese Registerzuordnung wird von Client-Anwendungen zum Lesen und Schreiben von Serverdaten verwendet.
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);Anschließend werden die Kommunikationsparameter und die Serveradresse festgelegt. Die Kommunikationsparameter hängen vom Kommunikationstyp ab:
if (static_cast<ModbusConnection>(ui->connectType->currentIndex()) == Serial) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
ui->portEdit->text());
#if QT_CONFIG(modbus_serialport)
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);
#endif
} 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());Nachdem der Server erstellt und alle Parameter festgelegt wurden, verwenden Sie ` QModbusServer::connectDevice()`, um eine Verbindung zum Modbus-Netzwerk herzustellen.
Lokale Werte ändern
Das Beispiel ermöglicht es, die Werte aller unterstützten „ register types “ mithilfe der bereitgestellten Kombinationsfelder oder Eingabefelder zu ändern. Sobald der Wert in der Benutzeroberfläche aktualisiert wurde, wird die Methode „ QModbusServer::setData()“ verwendet, um den tatsächlichen Wert auf dem Server zu aktualisieren:
void MainWindow::bitChanged(int id, QModbusDataUnit::RegisterType table, bool value)
{
if (!modbusDevice)
return;
if (!modbusDevice->setData(table, quint16(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 quint16 id = quint16(QObject::sender()->property("ID").toUInt());
if (objectName.startsWith(QStringLiteral("inReg"))) {
const auto uval = value.toUShort(&ok, 16);
if (ok)
ok = modbusDevice->setData(QModbusDataUnit::InputRegisters, id, uval);
} else if (objectName.startsWith(QStringLiteral("holdReg"))) {
const auto uval = value.toUShort(&ok, 16);
if (ok)
ok = modbusDevice->setData(QModbusDataUnit::HoldingRegisters, id, uval);
}
if (!ok)
statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),
5000);
}
}Behandlung von Schreibzugriffen aus der Ferne
Die Modbus-Clients können die Werte von „ Coils “ und „ HoldingRegisters “ durch das Senden von Schreibanforderungen aktualisieren. Sobald der Wert auf der Serverseite durch eine solche Anforderung aktualisiert wurde, wird ein Signal „ QModbusServer::dataWritten()“ ausgelöst.
connect(modbusDevice, &QModbusServer::dataWritten,
this, &MainWindow::updateWidgets);Das Modbus-Server-Beispiel bindet dieses Signal ein, extrahiert die aktualisierten Werte und passt die Benutzeroberfläche entsprechend an:
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, quint16(address + i), &value);
coilButtons.button(address + i)->setChecked(value);
break;
case QModbusDataUnit::HoldingRegisters:
modbusDevice->data(QModbusDataUnit::HoldingRegisters, quint16(address + i), &value);
registers.value(QStringLiteral("holdReg_%1").arg(address + i))->setText(text
.setNum(value, 16));
break;
default:
break;
}
}
}Ausführen des Beispiels
Sie können das Beispiel wie folgt ausführen:
- Qt Creator
Öffnen Sie den Modus „ Welcome “ und wählen Sie das Beispiel unter „ Examples “ aus. Weitere Informationen finden Sie unter „Qt Creator “: Tutorial: Erstellen und Ausführen.
- Qt Extension for Visual Studio Code
Führen Sie den Befehl „ Qt: Open Qt examples “ über „ Command Palette “ aus und wählen Sie das Beispiel aus der Liste aus. Weitere Informationen finden Sie unter Qt Extension for Visual Studio Code: Tutorial: Erstellen und Ausführen.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.