QSerialPort waitForReadyRead有数据却超时问题
工作中用到Qt串口通讯,使用方法很简单,网上很多都使用的是异步(信号槽)方式,这里记录一下同步方式调用waitForReadyRead阻塞后,明明发送数据却还是返回超时问题。
这里说的是以ASCII形式发送,也就是常见的ABCD字符
十六进制形式发送waitForReadyRead会立即响应,目前还没查到具体原因。
如果是ASCII形式通讯,在调用waitForReadyRead之前,先调用setReadBufferSize设置缓冲区大小。这样waitForReadyRead就不会一直阻塞直到超时了。
Qt缓冲区
QSerialPort 内部维护了一个缓冲区,当有新数据进来后会先写入缓冲区不会立即触发waitForReadyRead,当缓冲区满时waitForReadyRead才会返回true,否则返回false。
可以通过setReadBufferSize函数设置缓冲区大小,需要注意的是在没设置缓冲区大小的情况下,默认缓冲区大小是0代表缓冲区大小没有限制(https://doc.qt.io/qt-5/qserialport.html#setReadBufferSize)。
也就是说在waitForReadyRead没超时的情况下,发送多少数据也不会放开阻塞向下执行,直到最后超时(waitForReadyRead默认超时时间30s,-1表示永不超时https://doc.qt.io/qt-5/qserialport.html#waitForReadyRead)。
虽然waitForReadyRead函数返回false超时,但是还是可以通过readAll()函数读取到接收的数据。
简单示例代码:
qDebug() << argv[1]; qDebug() << "len: " << argc; QString com = argv[1]; if(argc == 1) com = "COM1"; QSerialPort serial; serial.setPortName(com); serial.setBaudRate(QSerialPort::Baud9600); // 设置波特率 serial.setDataBits(QSerialPort::Data8); // 设置数据位 serial.setParity(QSerialPort::NoParity); // 设置校验位 serial.setStopBits(QSerialPort::OneStop); // 设置停止位 serial.setFlowControl(QSerialPort::NoFlowControl); // 设置流控制 if(serial.open(QIODevice::ReadWrite) == false) { qDebug() << com << "打开失败!"; return 1; } qDebug() << com << "打开ok."; serial.setReadBufferSize(10); serial.waitForReadyRead( 10 * 1000); qDebug() << "串口结束." << serial.readAll(); serial.close();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码