Я пытаюсь запрограммировать последовательный порт, используя Qt и класс QSerialPort.У меня есть USB / Serial конвертер, подключенный к моему ПК, и к последовательному порту подключено внешнее устройство.Устройство может быть запрошено (например, "ver?\n"
или "meas?\n"
) и отвечает строками;например, ответ на "ver?\n"
может быть "version 1.0"
или ответ на "meas?\n"
может быть разделенным запятыми списком измерений, длина списка заранее неизвестна.Единственное, что я знаю, это то, что каждый ответ завершается символом CR + LF.
Когда нажимается кнопка в моем графическом интерфейсе, я хочу отправить конкретный запрос, дождаться полного ответа и затем обработать данные..
Я уже реализовал слот для сигнала readyRead, он работает нормально, но проблема в том, что он полностью асинхронный.Как я могу решить свою проблему?
Я уже попробовал следующее:
port->write(QString("meas?\n").toLocal8Bit().data());
port->flush();
port->waitForBytesWritten();
port->waitForReadyRead();
QString rxdata = port->readLine();
Однако это не работает надежно, потому что, если мое внешнее устройство не дает ответ достаточно быстро,Внутренний тайм-аут для QSerialPort истекает, и никакие данные не возвращаются вообще, или иногда я получаю только частичные данные (я думаю, это также из-за внутреннего тайм-аута).
Затем я попытался использовать сигнал ислот подход.Я подключил сигнал ReadyRead QSerialPort к следующему слоту
void onReadyRead()
{
static QString buffer;
while(port->bytesAvailable())
{
buffer = buffer.append(port->readAll());
if(buffer.endsWith("\n"))
{
// the reply is received completely
}
}
}
, он действительно получает полные данные правильно, но, к сожалению, это асинхронный подход, и ответ хранится во внутреннем буфере onReadyRead.Но я хочу использовать последовательный порт следующим образом:
port-> write ("measure? \ N");QString reply = receive_reply ();// дождемся \ n получения или тайм-аута