gpt4 book ai didi

c++ - QSerialPort 的 readAll() 不包括最后发送的响应

转载 作者:行者123 更新时间:2023-11-28 00:02:08 29 4
gpt4 key购买 nike

我正在使用 Qt 来控制串行设备。如果我向串行设备发送命令,我会执行类似 serial->write("command\r\n") 的操作。我制作了一个按钮,将纯文本小部件中的文本更改为串行端口的响应。为了获得串行端口的响应,我使用了 serial->readAll()。问题是它显示了倒数第二个响应,而不是我期望的响应。 Qt 是否有某种缓冲区来保存此响应?

编辑我通过使用递归来搞砸它并比较收到的字符串

最佳答案

您可能在响应可用之前调用了 readAll。您应该将代码挂接到 readyRead 信号,以便在每次准备好读取新数据 block 时收到通知。请记住,readyRead 可以发出任意数量的可读字节 - 至少,它只是一个字节。您不能期望数据以任何特定方式分块/阻塞,因为串行端口不充当基于消息的通信设备。您的接收器代码必须能够将数据从小块拼凑在一起,并在获得所需的所有数据时采取相应的行动。

例如,假设设备响应具有固定的已知长度。您只想在收到完整响应时使用react。例如:

class Protocol : public QObject {
Q_OBJECT
QBasicTimer m_timer;
QPointer<QIODevice> m_port;
int m_responseLength = 0;
int m_read = 0;
void timerEvent(QTimerEvent * ev) override {
if (ev->timerId() != m_timer.timerId()) return;
m_timer.stop();
emit timedOut();
}
void onData() {
m_read += m_port->bytesAvailable();
if (m_read < m_responseLength)
return;
m_timer.stop();
emit gotResponse(m_port->read(m_responseLength));
m_read -= m_responseLength;
m_responseLength = 0;
}
public:
Q_SIGNAL void gotResponse(const QByteArray &);
Q_SIGNAL void timedOut();
Q_SLOT void sendCommand(const QByteArray & cmd, int responseLength, int cmdTimeout) {
m_responseLength = responseLength;
m_port->write(cmd);
m_timer.start(cmdTimeout, this);
}
explicit Protocol(QIODevice * port, QObject * parent = nullptr) :
QObject(parent), m_port(port) {
connect(m_port, &QIODevice::readyRead, this, &Protocol::onData);
}
};

...
Protocol protocol(0,0);
protocol.sendCommand({"foo"}, 10, 500);
QMetaObject::Connection cmd1;
cmd1 = QObject::connect(&protocol, &Protocol::gotResponse, [&]{
QObject::disconnect(cmd1);
qDebug() << "got response to foo";
});
QObject::connect(&protocol, &Protocol::timedOut, []{ qDebug() << "timed out :("; });

关于c++ - QSerialPort 的 readAll() 不包括最后发送的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38103405/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com