0

我必须在工作中驾驶激光,为此我需要与 RS232 中的串行端口通信。由于您在使用激光时必须小心,因此您需要不断读取激光状态(温度、功率等...),为此您必须每 1 或 2 秒发送大量命令(~20) .

我使用 Qt 类QserialPort,我的问题是,当我发送所有命令时,我阻塞了 GUI,程序变得不可用。我阅读了很多关于 QSerialPort 以及如何使用它的内容,例如:Blocking Master、Blocking Slave、Async reader、Terminal 等。我仍然无法弄清楚。

首先我想使用线程,但这个人的回答说这是个坏主意。然后,我尝试不使用线程,但得到了相同的结果。

我想要的是一种与激光通信的方式,它不会使整个程序等待发送的答案以及处理相应的答案。我发送我的第一个命令,激光回答,我处理答案,然后我发送第二个命令,等等......所有这些都在后台

我当前的实现是基于线程的,但我还有一个没有线程的实现。

我有用于 GUI的MainWindow类,一个Laser类,它知道如何为激光编写消息以理解并理解激光的答案,以及一个LaserThread类打开与串行端口的连接,写入和读取。

要发送命令,我会:

void LaserThread::writeData(const QByteArray &data)
{
    while(m_serialPort->waitForReadyRead(200)){} //Timeout is 200ms
    m_serialPort->write(data);

}

这意味着我在发送新命令之前等待收到答复。我尝试使用 waitForBytesWritten但无法获得预期结果。我必须连续调用这个函数 20 次。

阅读答案:

void LaserThread::readFromFPGA()
{
    if (m_serialPort->bytesAvailable()>0) {
        if (m_serialPort->waitForReadyRead(20)){

            QByteArray response =  m_serialPort->readAll();

            if(response.size()==0)
                return;

            qDebug() << "response" << toDebug(response); //transforms bytes to QString

            if(m_laser->checkMessage(response)) //check msg conformity
                m_laser->handleMessage(response); //process it
        }
    }
}

现在我的两个问题是:

  1. 或者,我等待发送新命令的时间过长,并且 UI 被冻结
  2. 或者,我不会等待太多,发送 25 条消息,只得到一个回复​​。

在不冻结程序的情况下不断与串行端口通信(异步或同步)的正确方法是什么?

4

0 回答 0