解决Qt5中的QSerialPort分多次接收串口数据的问题

本文介绍如何解决Qt中QSerialPort的readyRead信号导致的数据分次接收问题。通过添加自定义延时机制,将分次接收到的数据整合为一组完整数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作中遇到使用Qt在Linux下读取串口信息功能。串口设备是二维码扫码枪。

问题:QSerialPortreadyRead()信号,只要有数据就抛出,这就导致一条数据分多次抛出。由于正常的数据没有固定的开头和结尾,这就导致无法获取正常的一组数据

解决思路:增加接收延时功能,把多次读取的数据保存到缓冲区,延时结束,一次性读取数据
由于QSerialPort没有提供串口接收延时功能,需自己添加

示例

	QSerialPort *com = new QSerialPort();
	QTimer *timer = new QTimer();
	connect(com, SIGNAL(readyRead()), this, SLOT(com_rece()));
	connect(timer, SIGNAL(timeout()), this, SLOT(timeUpdate())));

	void MainWindow::com_rece()
	{
		timer->start(100);//启动定时器,接收100毫秒数据(根据情况设定)
		buf.append(com->readAll());
	} 

	void MainWindow::timeUpdate()
	{
		timer->stop();
		if(buf.length()!=0)
		{
			qDebug()<<buf;
		}
		buf.clear();
	}

本示例源码只为展示原理,省去了串口设置相关代码,请注意

### 实现多组串口数据接收的关键要素 为了在Qt中正确配置并实现接收多组串口数据的功能,需关注几个方面:参数设置、读取方法的选择以及并发处理策略。 #### 参数设置 对于串口通信而言,初始化阶段至关重要。这不仅涉及波特率、停止位等基本属性的设定,还涉及到超时时间等高级选项。具体来说,在创建`QSerialPort`对象实例化后,应当调用相应的方法完成这些必要的配置工作[^1]: ```cpp // 设置串口号 serial->setPortName("COM3"); // 配置波特率, 数据位, 奇偶校验, 停止位 serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); if (!serial->open(QIODevice::ReadWrite)) { qDebug() << "Failed to open port"; } ``` #### 读取方法 针对大容量或多批次的数据传输场景下可能出现的数据丢失现象,建议采用基于事件驱动的方式监听来自硬件层面上的通知——即连接至`readyRead()`信号槽函数来进行增量式的字节流收集操作;与此同时,为了避免因单次回调未能捕获全部预期消息而导致解析失败的问题发生,则可在应用程序内部维护一个缓冲区用于累积临时接收到的内容片段直至满足预定义条件为止(比如检测到了特定终止符),从而确保最终能够组装成完整的消息体供后续逻辑层面进一步析处理[^2]。 ```cpp void MainWindow::onReadyRead() { QByteArray data = serial->readAll(); // 将新到达的数据追加到缓存中 receiveBuffer.append(data); while (true) { int index = receiveBuffer.indexOf(endMarker); // 查找结束标记的位置 if (index != -1) { // 如果找到了结束标记 QString message = QString::fromUtf8(receiveBuffer.left(index)); processMessage(message); // 处理接收到的信息 receiveBuffer.remove(0, index + endMarker.size()); // 移除已处理的部 } else { break; // 当前未找到完整的消息,退出循环等待更多数据到来 } } } private slots: void onReadyRead(); // 定义槽函数响应 readyRead 信号 ``` #### 并发处理 考虑到实际应用场景可能存在的高频率交互需求或者多个设备间的同时通讯情况,合理运用线程技术可以有效提升系统的吞吐能力和稳定性。借助于Qt所提供的多线程支持特性,可考虑为每一个独立的任务单元配专属的工作线程执行相应的I/O密集型任务,进而达到隔离潜在阻塞风险的目的。此外,还可以利用信号槽机制跨线程传递异步通知信息,简化编程模型复杂度的同时增强了程序结构上的清晰性和扩展性。 ```cpp class SerialWorker : public QObject { public slots: void startWork(const QSerialPortInfo &info) { m_serial = new QSerialPort(info, this); connect(m_serial, SIGNAL(errorOccurred(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError))); connect(m_serial, SIGNAL(readyRead()), this, SLOT(onReadyRead())); m_serial->open(QIODevice::ReadOnly | QIODevice::WriteOnly); } signals: void finished(); private slots: void handleError(QSerialPort::SerialPortError error); void onReadyRead(); }; ```
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值