如何使用Qt通过USB转串口读取传感器数据并解决运行异常问题
Qt串口读取传感器数据问题修复方案
核心错误原因
- 代码逻辑结构错误:死循环读取逻辑写在
app.exec()之前,永远不会执行Qt事件循环,QSerialPort依赖事件循环处理IO事件,所以要么卡启动,要么只能用阻塞模式导致延迟 - 串口参数未配置:打开串口后没有设置和传感器匹配的波特率、数据位、停止位、奇偶校验、流控参数,默认参数和传感器不匹配,导致数据接收异常、延迟高
- 行处理逻辑不完善:检测到
\r后直接清空全部缓存,若单次收到多帧数据会丢失后半部分
修复后的完整代码
#include <QCoreApplication> #include <QObject> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <iostream> class SensorReader : public QObject { Q_OBJECT public: explicit SensorReader(QObject *parent = nullptr) : QObject(parent) { // 查找目标串口 const auto portList = QSerialPortInfo::availablePorts(); std::cout << "Number of ports: " << portList.size() << "\n"; QSerialPortInfo targetPort; bool found = false; for (const auto& port : portList) { std::cout << port.portName().toStdString() << " " << port.description().toStdString() << "\n"; if (port.portName() == "ttyUSB0" && port.description() == "USB-Serial Controller D") { targetPort = port; found = true; break; } } if (!found) { std::cerr << "Target sensor port not found\n"; exit(1); } // 配置并打开串口 m_serial.setPort(targetPort); if (!m_serial.open(QIODevice::ReadOnly)) { std::cerr << "Failed to open serial port: " << m_serial.errorString().toStdString() << "\n"; exit(1); } // ************************ // 此处替换为你传感器的实际参数,和你之前Python pyserial配置的参数保持一致 m_serial.setBaudRate(QSerialPort::Baud9600); // 示例波特率,按实际修改 m_serial.setDataBits(QSerialPort::Data8); m_serial.setParity(QSerialPort::NoParity); m_serial.setStopBits(QSerialPort::OneStop); m_serial.setFlowControl(QSerialPort::NoFlowControl); // 必须关闭流控,大部分传感器不支持硬件流控 // ************************ // 绑定数据就绪信号到处理槽 connect(&m_serial, &QSerialPort::readyRead, this, &SensorReader::onDataReceived); std::cout << "Serial port opened successfully: " << m_serial.portName().toStdString() << "\n"; } private slots: void onDataReceived() { // 追加所有新收到的数据到缓存 m_buffer.append(m_serial.readAll()); // 循环处理所有完整行(避免单次收到多行) int crPos; while ((crPos = m_buffer.indexOf('\r')) != -1) { // 提取从开头到\r位置的一行数据 QByteArray lineData = m_buffer.left(crPos); // 移除已处理的部分(包括\r) m_buffer = m_buffer.mid(crPos + 1); // 输出处理 std::cout << "End of line\n"; std::cout << lineData.toStdString() << "\n"; } } private: QSerialPort m_serial; QByteArray m_buffer; }; int main(int argc, char** argv) { QCoreApplication app(argc, argv); SensorReader reader; return app.exec(); } // 单文件用qmake编译时需加此行,cmake或拆分.h/.cpp可删除 #include "main.moc"
使用说明
- 编译时确保Qt项目配置了serialport模块,
.pro文件中添加QT += serialport - 代码中串口参数部分必须修改为和你传感器实际参数一致,波特率等参数和之前测试正常的Python代码保持相同
- 修复后采用Qt原生事件驱动模式,没有阻塞死循环,不会出现QSocketNotifier警告,数据接收实时性和传感器输出同步
- 缓存处理逻辑支持单次接收多帧数据,不会丢包
内容的提问来源于stack exchange,提问作者aavv
相关产品推荐
相关产品推荐

