基于uFUN开发板的心率计(三)Qt上位机的实现

前言



上两周利用周末的时间,分别写了基于uFUN开发板的心率计(一)DMA方式获取传感器数据(二)动态阈值算法获取心率值,介绍了AD采集传感器数据和数据的滤波处理获取心率值。这篇文章主要是介绍Qt上位机如何实现波形的显示,串口数据的解析,以及一些小细节实现。这篇文章写完,uFUN心率计这个小项目就算结束了,最近又做了个uFUN开发板的扩展板,在微信群里的朋友都已经看到了,后面会做一些好玩的东西,大家要保持关注哈!
关于Qt
Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚旗下的编程语言工具。2012年,Qt被Digia收购。2014年4月,跨平台集成开发环境Qt Creator 3.1.0正式发布,实现了对于iOS的完全支持,新增WinRT、Beautifier等插件,废弃了无Python接口的GDB调试支持,集成了基于Clang的C/C++代码模块,并对Android支持做出了调整,至此实现了全面支持iOS、Android、WP,它提供给应用程序开发者建立艺术级的图形用户界面所需的所有功能。基本上,Qt 同 X Window 上的 Motif,Openwin,GTK 等图形界 面库和 Windows 平台上的 MFC,OWL,VCL,ATL 是同类型的东西。——来自百度百科
串口数据的解析和显示
pro文件添加串口支持:
  1. QT += serialport
头文件包含:
  1. #include <QSerialPort>
  2. #include <QSerialPortInfo>
串口对象的定义:
  1. QSerialPort serial;
启动自动搜索本机串口并添加到下拉框:
  1. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  2. {
  3.     ui->cbb_com->addItem(info.portName());  //串口号下拉菜单,增加一个条目,为串口号COM4
  4.     qDebug() << "串口搜索完成";
  5. }
串口的打开:
   
  1. serial.setPortName(ui->cbb_com->currentText());     //设置串口号、
  2.     serial.setBaudRate(ui->cbb_baud->currentText().toInt());    //设置波特率
  3.     serial.setDataBits(QSerialPort::Data8);     //设置串口数据位8
  4.     serial.setParity(QSerialPort::NoParity);    //无校验位
  5.     serial.setStopBits(QSerialPort::OneStop);   //1位停止位
  6.     serial.setFlowControl(QSerialPort::NoFlowControl);
  7.     if(!serial.open(QIODevice::ReadWrite))
  8.     {
  9.         QMessageBox::critical(NULL, "提示", "串口打开失败");
  10.         return;
  11.     }
串口的关闭:
  1.     serial.close();
关联信号与槽函数:
  1. connect(&serial, & QSerialPort::readyRead, this, &Pulse::serialPort_readyRead);
串口通讯协议:
  1. 电压值的显示:S+传感器数值+\r\n
  2. 心率值的显示:B+心率值+\r\n
槽函数里进行串口数据的解析:
  1. //串口数据接收并解析
  2. void Pulse::serialPort_readyRead()
  3. {
  4.     bool ok1, ok2;
  5.     static double x;
  6.     double SensorValue;
  7.     QByteArray rx_buf= serial.readAll();;
  8.     int len = rx_buf.length();
  9.     //    qDebug() << rx_buf << " - " << len;
  10.     x += 0.1;
  11.     if(rx_buf.startsWith("S") && rx_buf.endsWith("\r\n"))
  12.     {
  13.         int indx1 = rx_buf.indexOf("\r\n");
  14.         QString str1 = rx_buf.mid(1, indx1 - 1);
  15.         SensorValue = str1.toDouble(&ok1) * 3.3 / 4096 ;
  16.         if(ok1 && !stopFlag)
  17.         {
  18.             if(SensorValue > 2.5)
  19.                 SensorValue = 2.5;
  20.             if(SensorValue < 1.4)
  21.                 SensorValue = 1.4;
  22.             //            qDebug() << " 电压值: "<< SensorValue;
  23.             QString dis_SIG;
  24.             dis_SIG.sprintf("%.2f v", SensorValue);
  25.             ui->lbe_SIG->setText(dis_SIG);
  26.             ui->widget->graph(0)->addData(x, SensorValue);
  27.             ui->widget->xAxis->setRange(x, 40, Qt::AlignRight);
  28.             ui->widget->replot();
  29.             //            ui->widget->replot(QCustomPlot::rpQueuedReplot);
  30.         }
  31.     }
  32.     else if(rx_buf.startsWith("B") && rx_buf.endsWith("\r\n"))
  33.     {
  34.         int index2 = rx_buf.indexOf("\r\n");
  35.         QString str2 = rx_buf.mid(1, index2 - 1);
  36.         BMP = str2.toInt(&ok2);
  37.         qDebug() << "心率值: "<< str2;
  38.         if(ok2 && !stopFlag)
  39.         {
  40.             QString dis_BPM;
  41.             ui->lbe_BPM->setText(QString::number(BMP,10) + "/min");
  42.         }
  43.     }
  44.     else
  45.     {
  46.         x = 0;
  47.         serial.close(); //关闭串口
  48.         this->ui->btn_uart_Ctrl->setText("打开串口");
  49.         QMessageBox::warning(this, "警告", "串口数据格式错误!");
  50.     }
  51.     rx_buf.clear();
  52. }
关于串口的详细使用,可以参考最开始学习Qt时做的一个练手项目:Qt小项目之串口助手控制LED( www.wangchaochao.top/2019/03/03/Qt-UART-Ctrl-LED/)
QCustomplot绘图库的使用1.添加库文件到工程
库文件的下载:
QCustomPlot-source.tar.gz (311.66 KB, 下载次数: 5)