当前位置:   article > 正文

QT--串口读取数据并展示实时波形图_qt上位机和下位机通信解析数据获取实时数据

qt上位机和下位机通信解析数据获取实时数据

1.串口读取数据

与下位机,单片机通信少不了使用串口进行通信,Qt 也提供了串口通信的类。

使用的时候在 pro 添加这句导入模块

QT += serialport

1.连接串口 第一步就是 要先获取到 可连接的所有的串口的名字

获取到串口名字列表以后,我们需要选择一个需要连接的 (自行根据选择)

  1. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  2. {
  3. QSerialPort serial;
  4. serial.setPort(info);
  5. if (serial.open(QIODevice::ReadWrite))
  6. {
  7. portList.push_back(serial.portName());
  8. serial.close();
  9. }
  10. }

2.根据串口名字 打开串口

进行初始化串口

  1. void frmserialport::inialSerialPort() //初始化串口(串口号、波特率、数据位、停止位、流控制)
  2. {
  3. m_flag = 0;
  4. QList<QString> portList;
  5. QStringList baudList;
  6. QStringList parityList;
  7. QStringList dataBitList;
  8. QStringList stopBitList;
  9. QStringList flowList;
  10. baudList<<"9600"<<"115200"<<"460800";
  11. dataBitList<<"8";
  12. parityList<<"无";
  13. stopBitList<<"1";
  14. flowList<<"无";
  15. }
  16. void frmserialport::on_btn_Open_clicked() //打开串口
  17. {
  18. m_pSerialPort = new QSerialPort(this);
  19. m_pSerialPort->setPortName(ui->cbox_PortName->currentText()); //串口名
  20. m_pSerialPort->setBaudRate(ui->cbox_BaudRate->currentText().toInt()); //波特率
  21. switch (ui->cbox_DataBit->currentIndex()) {
  22. case 0:
  23. m_pSerialPort->setDataBits(QSerialPort::Data8); //数据位为8位
  24. break;
  25. default:
  26. break;
  27. }
  28. switch (ui->cbox_Parity->currentIndex()) {
  29. case 0:
  30. m_pSerialPort->setParity(QSerialPort::NoParity); //无校验位
  31. break;
  32. default:
  33. break;
  34. }
  35. switch (ui->cbox_StopBit->currentIndex()) {
  36. case 0:
  37. m_pSerialPort->setStopBits(QSerialPort::OneStop); //一位停止位
  38. break;
  39. default:
  40. break;
  41. }
  42. switch (ui->cbox_Flow->currentIndex()) {
  43. case 0:
  44. m_pSerialPort->setFlowControl(QSerialPort::NoFlowControl); //无流控制
  45. break;
  46. default:
  47. break;
  48. }
  49. if (!m_pSerialPort->open(QIODevice::ReadWrite)){
  50. QMessageBox::information(this,"提示","串口连接失败");
  51. }
  52. else{
  53. QMessageBox::information(this,"提示",ui->cbox_PortName->currentText() + tr("连接成功"));
  54. ui->btn_Open->setEnabled(false);
  55. ui->btn_Close->setEnabled(true);
  56. ui->btn_Send->setEnabled(true);
  57. }
  58. connect(m_pSerialPort,&QSerialPort::readyRead,this,&frmserialport::serialReadData);

3.发送数据和清除数据

  1. void frmserialport::on_btn_Send_clicked() //发送数据
  2. {
  3. QString strMessage = ui->txt_Send->toPlainText();
  4. sendCMD(strMessage);
  5. }
  6. void frmserialport::on_btn_Clear_clicked() //清除
  7. {
  8. if (!ui->txt_Receive->toPlainText().isEmpty()){
  9. ui->txt_Receive->clear();
  10. ui->btn_Clear->setEnabled(false);
  11. }
  12. }

4.关闭串口

  1. void frmserialport::on_btn_Close_clicked() //关闭串口
  2. {
  3. m_pSerialPort->clear();
  4. m_pSerialPort->close();
  5. delete m_pSerialPort;
  6. m_pSerialPort = nullptr;
  7. m_flag = 0;
  8. ui->btn_Open->setEnabled(true);
  9. ui->btn_Close->setEnabled(false);
  10. ui->btn_Send->setEnabled(false);
  11. }

2.展示实时波形图(使用QCharts)

1.QCharts的使用可以参考《Qt开发技术:QCharts》

链接:Qt开发技术:QCharts

2.想要绘制曲线图需要定义画布 , 线 , 轴 ,我的x轴是用实时时间所以要加多一个定时器

  1. //绘图变量和坐标
  2. QDateTimeAxis *axisX_aX; //用时间表示x轴
  3. QDateTimeAxis *axisX_aY;
  4. QDateTimeAxis *axisX_aZ;
  5. QValueAxis *axisY_aX; //aX数据,表示y轴
  6. QValueAxis *axisY_aY; //aY数据
  7. QValueAxis *axisY_aZ; //aZ数据
  8. QTimer *timer; //图表的计时器
  9. QChart *chart;
  10. QSplineSeries *series_aX; //数据点
  11. QSplineSeries *series_aY;
  12. QSplineSeries *series_aZ;

3.设置数据,定义绘图

  1. axisX_aX->setFormat("hh:mm:ss");
  2. axisY_aX->setRange(-3,3);
  3. chart->addSeries(series_aX);
  4. axisX_aX->setTickCount(10);
  5. axisY_aX->setTickCount(10);
  6. axisX_aX->setTitleText("实时时间");
  7. axisY_aX->setTitleText("加速度A(G):");
  8. series_aX->setPen(QColor(Qt::red));
  9. axisY_aX->setLinePen(peny);
  10. axisX_aX->setLinePen(peny);
  11. chart->addAxis(axisX_aX , Qt::AlignBottom);
  12. chart->addAxis(axisY_aX , Qt::AlignLeft);
  13. series_aX->attachAxis(axisX_aX);
  14. series_aX->attachAxis(axisY_aX);
  15. QDateTime currentTime = QDateTime::currentDateTime(); //实时时间
  16. chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));
  17. chart->axisX()->setMax(QDateTime::currentDateTime().addMSecs(0));
  18. qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
  19. series_aX->append(currentTime.toMSecsSinceEpoch() , aX); //提供x,y轴数据

 

最后就实现啦!

 

我是qt小白,刚开始学习qt不久,如果有问题请大家多多指教,感谢大家阅读,觉得不错的话点个赞收藏下呗!!最后列出几个我写这个项目时遇到的问题吧!

 

1.读取到的串口数据会分段

解决方案:串口延时接收数据

处理思路:创建两个槽函数(SLOT),当串口有数据应答时系统会给一个 readyRead()信号,用槽函数接收一个信号,并处理。在进入到这个槽函数后设置一个定时,当定时走完会有一个timeout()信号,用另一个槽函数处理定时完成后的事情。

这里感谢Humboldt大佬的思路。

  1. //connect(timer,SIGNAL(timeout()),this,SLOT(RealtimeDataSlot())); 没有延时接受数据前的槽函数
  2. connect(timer,SIGNAL(timeout()),this,SLOT(DrawLine()));
  3. //connect(m_pSerialPort,&QSerialPort::readyRead,this,&frmserialport::serialReadData); //没有延时接受数据前的槽函数
  4. //延时接收数据
  5. connect(m_pSerialPort,SIGNAL(readyRead()),this,SLOT(on_serialReadData())); //当有数据来是显示
  6. connect(&timer1,SIGNAL(timeout()),this,SLOT(serialReadData())); //当定时结束时进入

2.分离串口数据

我采用的是字符串分隔的方法

因为串口读取到的数据转成QString后长度是不一定的,所以用到了索引的方法解决。

  1. QByteArray receiveData;
  2. receiveData = m_pSerialPort->readAll();
  3. qDebug()<<"Re:"<<receiveData;
  4. QString str=receiveData;
  5. int x1=str.indexOf(":");
  6. int x=str.indexOf("G");
  7. int x2=x-x1-1;

 

成功截取到后就转成Double类型提供Y轴数据给曲线。

 

如果侵犯版权等问题,私聊马上删除。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/545704
推荐阅读
相关标签
  

闽ICP备14008679号