Extend modbus tcp class
This commit is contained in:
parent
8f281ed304
commit
f8bc078437
@ -34,13 +34,15 @@
|
|||||||
NYMEA_LOGGING_CATEGORY(dcModbusTCP, "ModbusTCP")
|
NYMEA_LOGGING_CATEGORY(dcModbusTCP, "ModbusTCP")
|
||||||
|
|
||||||
ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent) :
|
ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent),
|
||||||
|
m_hostAddress(hostAddress),
|
||||||
|
m_port(port)
|
||||||
{
|
{
|
||||||
m_modbusTcpClient = new QModbusTcpClient(this);
|
m_modbusTcpClient = new QModbusTcpClient(this);
|
||||||
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
|
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, m_port);
|
||||||
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, hostAddress.toString());
|
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, m_hostAddress.toString());
|
||||||
m_modbusTcpClient->setTimeout(1000);
|
m_modbusTcpClient->setTimeout(m_timeout);
|
||||||
m_modbusTcpClient->setNumberOfRetries(3);
|
m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
|
||||||
|
|
||||||
connect(m_modbusTcpClient, &QModbusTcpClient::stateChanged, this, &ModbusTCPMaster::onModbusStateChanged);
|
connect(m_modbusTcpClient, &QModbusTcpClient::stateChanged, this, &ModbusTCPMaster::onModbusStateChanged);
|
||||||
connect(m_modbusTcpClient, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusTCPMaster::onModbusErrorOccurred);
|
connect(m_modbusTcpClient, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusTCPMaster::onModbusErrorOccurred);
|
||||||
@ -52,38 +54,87 @@ ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QOb
|
|||||||
|
|
||||||
ModbusTCPMaster::~ModbusTCPMaster()
|
ModbusTCPMaster::~ModbusTCPMaster()
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (m_reconnectTimer) {
|
||||||
m_modbusTcpClient->disconnectDevice();
|
|
||||||
m_modbusTcpClient->deleteLater();
|
|
||||||
}
|
|
||||||
if (!m_reconnectTimer) {
|
|
||||||
m_reconnectTimer->stop();
|
m_reconnectTimer->stop();
|
||||||
m_reconnectTimer->deleteLater();
|
delete m_reconnectTimer;
|
||||||
|
m_reconnectTimer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_modbusTcpClient) {
|
||||||
|
m_modbusTcpClient->disconnectDevice();
|
||||||
|
delete m_modbusTcpClient;
|
||||||
|
m_modbusTcpClient = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress ModbusTCPMaster::hostAddress() const
|
||||||
|
{
|
||||||
|
return m_hostAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ModbusTCPMaster::port() const
|
||||||
|
{
|
||||||
|
return m_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModbusTCPMaster::setPort(uint port)
|
||||||
|
{
|
||||||
|
m_port = port;
|
||||||
|
return connectDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
||||||
|
{
|
||||||
|
m_hostAddress = hostAddress;
|
||||||
|
return connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusTCPMaster::connectDevice() {
|
bool ModbusTCPMaster::connectDevice() {
|
||||||
// TCP connection to target device
|
// TCP connection to target device
|
||||||
qCDebug(dcModbusTCP()) << "Setting up TCP connecion";
|
qCDebug(dcModbusTCP()) << "Setting up TCP connecion" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
|
||||||
|
|
||||||
if (!m_modbusTcpClient)
|
if (!m_modbusTcpClient)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, m_port);
|
||||||
|
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, m_hostAddress.toString());
|
||||||
|
m_modbusTcpClient->setTimeout(m_timeout);
|
||||||
|
m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
|
||||||
|
|
||||||
return m_modbusTcpClient->connectDevice();
|
return m_modbusTcpClient->connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusTCPMaster::connected()
|
void ModbusTCPMaster::disconnectDevice()
|
||||||
|
{
|
||||||
|
if (!m_modbusTcpClient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_modbusTcpClient->disconnectDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModbusTCPMaster::connected() const
|
||||||
{
|
{
|
||||||
return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState);
|
return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ModbusTCPMaster::numberOfRetries() const
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->numberOfRetries();
|
||||||
|
}
|
||||||
|
|
||||||
void ModbusTCPMaster::setNumberOfRetries(int number)
|
void ModbusTCPMaster::setNumberOfRetries(int number)
|
||||||
{
|
{
|
||||||
|
m_numberOfRetries = number;
|
||||||
m_modbusTcpClient->setNumberOfRetries(number);
|
m_modbusTcpClient->setNumberOfRetries(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ModbusTCPMaster::timeout() const
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->timeout();
|
||||||
|
}
|
||||||
|
|
||||||
void ModbusTCPMaster::setTimeout(int timeout)
|
void ModbusTCPMaster::setTimeout(int timeout)
|
||||||
{
|
{
|
||||||
|
m_timeout = timeout;
|
||||||
m_modbusTcpClient->setTimeout(timeout);
|
m_modbusTcpClient->setTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,74 +148,51 @@ QModbusDevice::Error ModbusTCPMaster::error() const
|
|||||||
return m_modbusTcpClient->error();
|
return m_modbusTcpClient->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint ModbusTCPMaster::port()
|
|
||||||
{
|
|
||||||
return m_modbusTcpClient->connectionParameter(QModbusDevice::NetworkPortParameter).toUInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
|
||||||
{
|
|
||||||
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, hostAddress.toString());
|
|
||||||
return connectDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModbusTCPMaster::setPort(uint port)
|
|
||||||
{
|
|
||||||
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
|
|
||||||
return connectDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModbusTCPMaster::onReconnectTimer()
|
void ModbusTCPMaster::onReconnectTimer()
|
||||||
{
|
{
|
||||||
if(!m_modbusTcpClient->connectDevice()) {
|
if (!m_modbusTcpClient->connectDevice()) {
|
||||||
m_reconnectTimer->start(10000);
|
m_reconnectTimer->start(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHostAddress ModbusTCPMaster::hostAddress()
|
|
||||||
{
|
|
||||||
return QHostAddress(m_modbusTcpClient->connectionParameter(QModbusDevice::NetworkAddressParameter).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
|
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
QUuid requestId = QUuid::createUuid();
|
|
||||||
|
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size);
|
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size);
|
||||||
|
|
||||||
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
||||||
if (!reply->isFinished()) {
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||||
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
||||||
|
|
||||||
if (reply->error() == QModbusDevice::NoError) {
|
if (reply->error() == QModbusDevice::NoError) {
|
||||||
emit readRequestExecuted(requestId, true);
|
emit readRequestExecuted(requestId, true);
|
||||||
const QModbusDataUnit unit = reply->result();
|
const QModbusDataUnit unit = reply->result();
|
||||||
uint modbusAddress = unit.startAddress();
|
uint modbusAddress = unit.startAddress();
|
||||||
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.values());
|
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.values());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit readRequestExecuted(requestId, false);
|
emit readRequestExecuted(requestId, false);
|
||||||
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
||||||
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
||||||
emit readRequestError(requestId, reply->errorString());
|
emit readRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(200, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(200, reply, &QModbusReply::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -172,51 +200,70 @@ QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint si
|
|||||||
QUuid ModbusTCPMaster::writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
|
QUuid ModbusTCPMaster::writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid requestId = QUuid::createUuid();
|
QUuid requestId = QUuid::createUuid();
|
||||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, values.length());
|
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, values.length());
|
||||||
request.setValues(values);
|
request.setValues(values);
|
||||||
|
|
||||||
if (QModbusReply *reply = m_modbusTcpClient->sendWriteRequest(request, slaveAddress)) {
|
if (QModbusReply *reply = m_modbusTcpClient->sendWriteRequest(request, slaveAddress)) {
|
||||||
if (!reply->isFinished()) {
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||||
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
||||||
|
|
||||||
if (reply->error() == QModbusDevice::NoError) {
|
if (reply->error() == QModbusDevice::NoError) {
|
||||||
writeRequestExecuted(requestId, true);
|
emit writeRequestExecuted(requestId, true);
|
||||||
const QModbusDataUnit unit = reply->result();
|
const QModbusDataUnit unit = reply->result();
|
||||||
uint modbusAddress = unit.startAddress();
|
uint modbusAddress = unit.startAddress();
|
||||||
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.values());
|
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.values());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
writeRequestExecuted(requestId, false);
|
emit writeRequestExecuted(requestId, false);
|
||||||
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
||||||
}
|
}
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
||||||
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
|
||||||
emit writeRequestError(requestId, reply->errorString());
|
emit writeRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModbusReply *ModbusTCPMaster::sendRawRequest(const QModbusRequest &request, int serverAddress)
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->sendRawRequest(request, serverAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModbusReply *ModbusTCPMaster::sendReadRequest(const QModbusDataUnit &read, int serverAddress)
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->sendReadRequest(read, serverAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModbusReply *ModbusTCPMaster::sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress)
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->sendReadWriteRequest(read, write, serverAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
QModbusReply *ModbusTCPMaster::sendWriteRequest(const QModbusDataUnit &write, int serverAddress)
|
||||||
|
{
|
||||||
|
return m_modbusTcpClient->sendWriteRequest(write, serverAddress);
|
||||||
|
}
|
||||||
|
|
||||||
QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress, uint size)
|
QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress, uint size)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
QUuid requestId = QUuid::createUuid();
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
|
||||||
@ -226,33 +273,32 @@ QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress
|
|||||||
if (!reply->isFinished()) {
|
if (!reply->isFinished()) {
|
||||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||||
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
|
||||||
|
|
||||||
if (reply->error() == QModbusDevice::NoError) {
|
if (reply->error() == QModbusDevice::NoError) {
|
||||||
emit readRequestExecuted(requestId, true);
|
emit readRequestExecuted(requestId, true);
|
||||||
const QModbusDataUnit unit = reply->result();
|
const QModbusDataUnit unit = reply->result();
|
||||||
uint modbusAddress = unit.startAddress();
|
uint modbusAddress = unit.startAddress();
|
||||||
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.values());
|
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.values());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit readRequestExecuted(requestId, false);
|
emit readRequestExecuted(requestId, false);
|
||||||
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [requestId, this] (QModbusDevice::Error error){
|
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::errorOccurred, this, [requestId, this] (QModbusDevice::Error error){
|
||||||
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
|
||||||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
||||||
emit readRequestError(requestId, reply->errorString());
|
emit readRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -260,10 +306,10 @@ QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress
|
|||||||
QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress, uint size)
|
QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress, uint size)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
QUuid requestId = QUuid::createUuid();
|
|
||||||
|
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, size);
|
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, size);
|
||||||
|
|
||||||
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
||||||
@ -276,26 +322,27 @@ QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress
|
|||||||
const QModbusDataUnit unit = reply->result();
|
const QModbusDataUnit unit = reply->result();
|
||||||
uint modbusAddress = unit.startAddress();
|
uint modbusAddress = unit.startAddress();
|
||||||
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.values());
|
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.values());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit readRequestExecuted(requestId, false);
|
emit readRequestExecuted(requestId, false);
|
||||||
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
||||||
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
||||||
emit readRequestError(requestId, reply->errorString());
|
emit readRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -303,10 +350,10 @@ QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress
|
|||||||
QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddress, uint size)
|
QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddress, uint size)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
QUuid requestId = QUuid::createUuid();
|
|
||||||
|
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, size);
|
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, size);
|
||||||
|
|
||||||
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
|
||||||
@ -327,20 +374,22 @@ QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddre
|
|||||||
}
|
}
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
||||||
|
|
||||||
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
||||||
emit readRequestError(requestId, reply->errorString());
|
emit readRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -353,10 +402,10 @@ QUuid ModbusTCPMaster::writeCoil(uint slaveAddress, uint registerAddress, bool v
|
|||||||
QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
|
QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
QUuid requestId = QUuid::createUuid();
|
|
||||||
|
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, values.length());
|
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, values.length());
|
||||||
request.setValues(values);
|
request.setValues(values);
|
||||||
|
|
||||||
@ -377,20 +426,21 @@ QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const
|
|||||||
}
|
}
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
});
|
});
|
||||||
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
|
||||||
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
|
||||||
emit writeRequestError(requestId, reply->errorString());
|
emit writeRequestError(requestId, reply->errorString());
|
||||||
reply->finished(); // To make sure it will be deleted
|
emit reply->finished(); // To make sure it will be deleted
|
||||||
});
|
});
|
||||||
|
|
||||||
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
|
||||||
} else {
|
} else {
|
||||||
delete reply; // broadcast replies return immediately
|
delete reply; // broadcast replies return immediately
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
|
||||||
return "";
|
return QUuid();
|
||||||
}
|
}
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -400,19 +450,20 @@ QUuid ModbusTCPMaster::writeHoldingRegister(uint slaveAddress, uint registerAddr
|
|||||||
return writeHoldingRegisters(slaveAddress, registerAddress, QVector<quint16>() << value);
|
return writeHoldingRegisters(slaveAddress, registerAddress, QVector<quint16>() << value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error)
|
void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error)
|
||||||
{
|
{
|
||||||
qCWarning(dcModbusTCP()) << "An error occured" << error;
|
qCWarning(dcModbusTCP()) << "An error occured" << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
|
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
|
||||||
{
|
{
|
||||||
|
qCDebug(dcModbusTCP()) << "Connection state changed for" << m_hostAddress << state;
|
||||||
|
|
||||||
bool connected = (state == QModbusDevice::ConnectedState);
|
bool connected = (state == QModbusDevice::ConnectedState);
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
//try to reconnect in 10 seconds
|
//try to reconnect in 10 seconds
|
||||||
m_reconnectTimer->start(10000);
|
m_reconnectTimer->start(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit connectionStateChanged(connected);
|
emit connectionStateChanged(connected);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,8 +37,6 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcModbusTcp)
|
|
||||||
|
|
||||||
class ModbusTCPMaster : public QObject
|
class ModbusTCPMaster : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -46,9 +44,21 @@ public:
|
|||||||
explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr);
|
explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr);
|
||||||
~ModbusTCPMaster();
|
~ModbusTCPMaster();
|
||||||
|
|
||||||
|
QHostAddress hostAddress() const;
|
||||||
|
bool setHostAddress(const QHostAddress &hostAddress);
|
||||||
|
|
||||||
|
uint port() const;
|
||||||
|
bool setPort(uint port);
|
||||||
|
|
||||||
bool connectDevice();
|
bool connectDevice();
|
||||||
bool connected();
|
void disconnectDevice();
|
||||||
|
|
||||||
|
bool connected() const;
|
||||||
|
|
||||||
|
int numberOfRetries() const;
|
||||||
void setNumberOfRetries(int number);
|
void setNumberOfRetries(int number);
|
||||||
|
|
||||||
|
int timeout() const;
|
||||||
void setTimeout(int timeout);
|
void setTimeout(int timeout);
|
||||||
|
|
||||||
QString errorString() const;
|
QString errorString() const;
|
||||||
@ -65,14 +75,20 @@ public:
|
|||||||
QUuid writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value);
|
QUuid writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value);
|
||||||
QUuid writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values);
|
QUuid writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values);
|
||||||
|
|
||||||
QHostAddress hostAddress();
|
// Generic requests
|
||||||
uint port();
|
QModbusReply *sendRawRequest(const QModbusRequest &request, int serverAddress);
|
||||||
bool setHostAddress(const QHostAddress &hostAddress);
|
QModbusReply *sendReadRequest(const QModbusDataUnit &read, int serverAddress);
|
||||||
bool setPort(uint port);
|
QModbusReply *sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress);
|
||||||
|
QModbusReply *sendWriteRequest(const QModbusDataUnit &write, int serverAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer *m_reconnectTimer = nullptr;
|
QTimer *m_reconnectTimer = nullptr;
|
||||||
QModbusTcpClient *m_modbusTcpClient;
|
QModbusTcpClient *m_modbusTcpClient = nullptr;
|
||||||
|
|
||||||
|
QHostAddress m_hostAddress;
|
||||||
|
uint m_port;
|
||||||
|
int m_timeout = 1000;
|
||||||
|
int m_numberOfRetries = 3;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onReconnectTimer();
|
void onReconnectTimer();
|
||||||
|
|||||||
Reference in New Issue
Block a user