Unsolved Modbus RTU: readyRead() not called
-
@J.Hilk You're right. Added and tried. Whenever the "hang" happens also this slot shows nothing, unfortunately.
-
@Mark81 how much time passes between open and the first read request ?
I noticed, on Windows, that when I call immediately after opening the device the first data , then most of the time nothing happens at all.
-
@J.Hilk adding a small delay seems to drastically improve the situation. Occasionally it still happens that the debug messages show a received answer but the slot is not called. That's weird because I can understand if some reasons the answer cannot be received, but this is not the case...
-
UPDATE
I think (not sure, though) I noticed something interesting.
When it works, the debug output from qt.modbus is like this:qt.modbus: (RTU client) Sent Serial PDU: 0x0304270001 qt.modbus.lowlevel: (RTU client) Sent Serial ADU: 0x0103042700013531 qt.modbus: (RTU client) Send successful: 0x0304270001 qt.modbus.lowlevel: (RTU client) Response buffer: "01030200017984" qt.modbus: (RTU client) Received ADU: "01030200017984"
and my slot is correctly called. Instead, when the problem arises the output is like the one reported in the first post or even this one:
qt.modbus: (RTU client) Sent Serial PDU: 0x0304180002 qt.modbus.lowlevel: (RTU client) Sent Serial ADU: 0x010304180002453c qt.modbus.lowlevel: (RTU client) Response buffer: "01030400004080ca53" qt.modbus: (RTU client) Received ADU: "01030400004080ca53" qt.modbus: (RTU client) Send successful: 0x0304180002 qt.modbus: (RTU client) Receive timeout: 0x0304180002 qt.modbus: (RTU client) Sent Serial PDU: 0x0304180002 qt.modbus.lowlevel: (RTU client) Sent Serial ADU: 0x010304180002453c qt.modbus.lowlevel: (RTU client) Response buffer: "01030400004080ca53" qt.modbus: (RTU client) Received ADU: "01030400004080ca53" qt.modbus: (RTU client) Send successful: 0x0304180002 qt.modbus: (RTU client) Receive timeout: 0x0304180002
Here my slot is not called.
I see that every time this happens the "Response buffer" line comes before the "Send successful" one.
I'm looking at the code but I don't understand if this might be a problem.(Sorry for the outdated link but I have difficult to find the actual source code of Qt5 - btw I'm using Qt5.11.1)
-
Perhaps I found it here https://code.woboq.org/qt5/qtserialbus/src/serialbus/qmodbusrtuserialmaster_p.h.html#154:
if (m_state != State::Receive) { qCDebug(QT_MODBUS) << "(RTU server) Ignoring response due to non receive state"; return; }
but https://code.woboq.org/qt5/qtserialbus/src/serialbus/qmodbusrtuserialmaster_p.h.html#351:
qCDebug(QT_MODBUS) << "(RTU client) Send successful:" << m_current.requestPdu; m_state = Receive;
So if the state is not set to
Receive
it discard the response. Anyway I didn't see the debug output "Ignoring response...". -
@Mark81 said in Modbus RTU: readyRead() not called:
(Sorry for the outdated link but I have difficult to find the actual source code of Qt5 - btw I'm using Qt5.11.1)
Then you should really test with a recent version 5.12.x. There has been quite some fixes last year.
-
Update to Qt5.12.2. Now with the very same code and data after a while it crashes with this error:
ASSERT failure in processQueue: "response timer active", file qmodbusrtuserialmaster_p.h, line 302
What should one do in such a case?
-
@Mark81 vote for the issue and pray, like I did
https://bugreports.qt.io/browse/QTBUG-73965
also leave a comment, it helps when people state that they have the same issue.
-
@J.Hilk said in Modbus RTU: readyRead() not called:
@Mark81 vote for the issue and pray, like I did
I'll try to suggest to my customer to pray and wait a fix too.
-
@Mark81
you can download the source code and in qmodbusrtumaster comment that lineQObject::connect(m_serialPort, &QSerialPort;::bytesWritten, q, [this](qint64 bytes) { m_current.bytesWritten += bytes; if (m_state == Send && (m_current.bytesWritten ==m_current.adu.size()) && !m_current.reply.isNull()) { // the if conditions above are copied from processQueue() qCDebug(QT_MODBUS) << "(RTU client) Send successful(quick):" << m_current.requestPdu; m_state = Receive; m_sendTimer.stop(); // m_responseTimer.start(m_responseTimeoutDuration); comment this line } });
thats the quick and dirty fix I made, fixes the unexpected state issue