Servidor Modbus
El ejemplo implementa una aplicación de servidor Modbus.
El ejemplo actúa como servidor Modbus. Recibe peticiones Modbus estándar, ajusta sus estados internos basándose en la petición y responde con la respuesta apropiada.
Este ejemplo debe utilizarse junto con el ejemplo Cliente Modbus. Este ejemplo debe iniciarse y ponerse en estado de escucha antes de iniciar el ejemplo de cliente Modbus. Las interacciones posteriores entre los dos ejemplos utilizan el protocolo Modbus.
Clases clave utilizadas en este ejemplo:

Creación de un QModbusServer
Se requiere una instancia de QModbusServer para realizar cualquier comunicación. Dependiendo del tipo de conexión especificado, el ejemplo puede instanciar un QModbusRtuSerialServer (para comunicación serie) o un QModbusTcpServer (para comunicación basada en TCP).
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")); }
Una vez creado el servidor, el mapa de registros se establece utilizando el método QModbusServer::setMap(). Este mapa de registros es utilizado por las aplicaciones cliente para leer y escribir los datos del servidor.
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);
Después se especifican los parámetros de comunicación y la dirección del servidor. Los parámetros de comunicación dependen del tipo de comunicación:
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());
Una vez creado el servidor y especificados todos los parámetros, utilice QModbusServer::connectDevice() para conectarse a la red Modbus.
Cambio de valores locales
El ejemplo permite cambiar los valores de todos los register types soportados utilizando los cuadros combinados proporcionados o ediciones de línea. Una vez que el valor se actualiza en la interfaz de usuario, el método QModbusServer::setData() se utiliza para actualizar el valor real en el servidor:
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); } }
Manejo de escrituras remotas
Los clientes Modbus son capaces de actualizar Coils y HoldingRegisters enviando peticiones de escritura. Una vez que el valor se actualiza en el lado del servidor utilizando dicha solicitud, se emite una señal QModbusServer::dataWritten().
connect(modbusDevice, &QModbusServer::dataWritten, this, &MainWindow::updateWidgets);
El ejemplo de servidor Modbus se conecta a esta señal, extrae los valores actualizados y actualiza la interfaz de usuario en consecuencia:
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; } } }
Ejecución del ejemplo
Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, ver Qt Creator: Tutorial: Construir y ejecutar.
© 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.