我必须在工作时试用激光,为此我需要与RS232中的串口通信。因为你在使用激光时一定要小心,你需要不断读取激光状态(温度,功率等等)并做到这一点你需要发送很多命令(~20)每1或2秒。
我使用Qt Class QserialPort ,我的问题是,当我发送所有命令时,阻止GUI ,程序变得无法使用。我读了很多关于QSerialPort以及如何使用它的例子:Blocking Master,Blocking Slave,Async reader,Terminal等。我仍然无法理解。
首先我想使用线程,但this guy's answer说这是一个坏主意。然后,我尝试了没有线程,但得到了相同的结果。
我想要的是一种与激光器通信的方式,它不会使整个程序等待发送答案并且相应的答案得到处理。我发送我的第一个命令,激光答案,我处理答案,然后我发送第二个命令,等等...... 所有这些在后台。
我当前的实现是基于线程的,但我有另一个没有线程。
我有GUI的 MainWindow 类,激光类,它知道如何撰写消息以让激光理解并能理解激光的答案,以及 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
}
}
}
现在我的两个问题是:
在不冻结程序的情况下,使用串口进行通信(异步或同步)的正确方法是什么?