我一直在努力通过Qt的串口通信大约两周的项目。首先我尝试了信号/插槽方法,它错过了一些数据。然后我决定使用一个线程,但我得到了相同的结果。当应用程序的窗口正在调整大小或最大化/最小化时,即使在窗口栏上按住鼠标左键,它也会丢失一些数据。请帮我这个条件。
MainWindow构造函数:
SerialPort *serial= new SerialPort();
serial->moveToThread(&cThread);
connect(this , &MainWindow::finished, &cThread, &QThread::quit);
connect(this , &MainWindow::destroyed, this, &SerialPort::deleteLater);
connect(serial, &SerialPort::getData, this, &MainWindow::displayData);
cThread.start();
串口读取线程:
void SerialPort::newData()
{
mutex.lock();
bArray.insert(bArray.length(),serial->readAll());
mutex.unlock();
emit getData(&bArray,&mutex);
}
SerialPort构造函数:
serial = new QSerialPort();
connect(serial, &QSerialPort::readyRead, this, &SerialPort::newData);
bArray.clear();
fill_serial_ports();
portName = find_stm32_port();
serial->setReadBufferSize(20*1024*1024); // it's a huge buffer.
bArray.reserve(20*1024*1024); // it's a huge buffer.
open_serial_port();
另外,我认为这可能是一个错过某些数据并写入错误跟踪器的错误。受让人说,QSerialPort永远不会丢失数据,我的代码是错误的。我很困惑,我不知道在哪里犯错误。拜托,你能检查我的其他解决方案吗?错误在哪里?
我的错误跟踪报告(不接受):https://bugreports.qt.io/browse/QTBUG-61233
答案 0 :(得分:1)
Denis Shienkov在qtbugreports中解决了这个问题。您可以查看带有线程的串口的qsp-no-freeze-workaround-windows.zip示例。
答案 1 :(得分:0)
尝试将内部QSerialPort
对象serial
移动到线程cThread
:
SerialPort *serial = new SerialPort();
serial->moveToThread(&cThread);
serial->serial.moveToThread(&cThread); // move you inner QSerialPort to cThread
在上面的代码中,内部字段serial->serial.moveToTheThread(...)
具有魔力。
答案 2 :(得分:0)
当应用程序的窗口正在调整大小或最大化/最小化时,即使在窗口栏上按住鼠标左键,它也会遗漏一些数据
我编译the code you provided to a bug tracker,使用socat
创建的一对虚拟串口启动它:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
并模拟发送数据块,每秒增加1个字节的大小:
#!/bin/bash
for i in {1..1000}
do
dd if=/dev/urandom of=/dev/pts/25 bs=1 count=$i
sleep 1
done
您的应用程序的日志如下所示:
"bytearray length:1"
"bytearray length:2"
"bytearray length:3"
"bytearray length:4"
"bytearray length:5"
"bytearray length:6"
"bytearray length:7"
...
然后我尝试调整应用程序窗口的大小,移动它,最大化/最小化,按下按钮等等。它没有任何效果:实际上,在一个相当长的测试会话期间,根本没有数据丢失(Ubuntu 16.04 x64)。因此,如果您仍然丢失数据,则问题可能出在您的虚拟COM端口中,其描述为“STMicroelectronics Virtual COM Port”。
答案 3 :(得分:0)
正如the comment中澄清的那样,问题在于
USBCan设备发出无法发送数据的错误,因此其错误导致正在开启。
尝试在创建QSerialPort
实例serial
之后立即添加以下行:
serial->setFlowControl(QSerialPort::HardwareControl);
如果您的设备支持RFC232标准,则应启用RTS(请求发送/ CTS(清除发送)线路,并使您的发送器在发送任何数据之前请求接收方准备就绪。请参阅{{3}有关详细信息。