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

前言

上两周利用周末的时间,分别写了基于uFUN开发板的心率计(一)DMA方式获取传感器数据基于uFUN开发板的心率计(二)动态阈值算法获取心率值,介绍了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文件添加串口支持:

QT += serialport

头文件包含:

#include <QSerialPort>
#include <QSerialPortInfo>

串口对象的定义:

QSerialPort serial;

启动自动搜索本机串口并添加到下拉框:

foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
    ui->cbb_com->addItem(info.portName());  //串口号下拉菜单,增加一个条目,为串口号COM4
    qDebug() << "串口搜索完成";
}

串口的打开:

    serial.setPortName(ui->cbb_com->currentText());     //设置串口号、
    serial.setBaudRate(ui->cbb_baud->currentText().toInt());    //设置波特率
    serial.setDataBits(QSerialPort::Data8);     //设置串口数据位8
    serial.setParity(QSerialPort::NoParity);    //无校验位
    serial.setStopBits(QSerialPort::OneStop);   //1位停止位
    serial.setFlowControl(QSerialPort::NoFlowControl);
    if(!serial.open(QIODevice::ReadWrite))
    {
        QMessageBox::critical(NULL, "提示", "串口打开失败");
        return;
    }

串口的关闭:

    serial.close();

关联信号与槽函数:

connect(&serial, & QSerialPort::readyRead, this, &Pulse::serialPort_readyRead);

串口通讯协议:

电压值的显示:S+传感器数值+\r\n
心率值的显示:B+心率值+\r\n

槽函数里进行串口数据的解析:

//串口数据接收并解析
void Pulse::serialPort_readyRead()
{
    bool ok1, ok2;
    static double x;
    double SensorValue;
    QByteArray rx_buf= serial.readAll();;
    int len = rx_buf.length();
    //    qDebug() << rx_buf << " - " << len;
    x += 0.1;
    if(rx_buf.startsWith("S") && rx_buf.endsWith("\r\n"))
    {
        int indx1 = rx_buf.indexOf("\r\n");
        QString str1 = rx_buf.mid(1, indx1 - 1);
        SensorValue = str1.toDouble(&ok1) * 3.3 / 4096 ;
        if(ok1 && !stopFlag)
        {
            if(SensorValue > 2.5)
                SensorValue = 2.5;
            if(SensorValue < 1.4)
                SensorValue = 1.4;
            //            qDebug() << " 电压值: "<< SensorValue;
            QString dis_SIG;
            dis_SIG.sprintf("%.2f v", SensorValue);
            ui->lbe_SIG->setText(dis_SIG);
            ui->widget->graph(0)->addData(x, SensorValue);
            ui->widget->xAxis->setRange(x, 40, Qt::AlignRight);
            ui->widget->replot();
            //            ui->widget->replot(QCustomPlot::rpQueuedReplot);
        }
    }
    else if(rx_buf.startsWith("B") && rx_buf.endsWith("\r\n"))
    {
        int index2 = rx_buf.indexOf("\r\n");
        QString str2 = rx_buf.mid(1, index2 - 1);
        BMP = str2.toInt(&ok2);
        qDebug() << "心率值: "<< str2;
        if(ok2 && !stopFlag)
        {
            QString dis_BPM;
            ui->lbe_BPM->setText(QString::number(BMP,10) + "/min");
        }
    }
    else
    {
        x = 0;
        serial.close(); //关闭串口
        this->ui->btn_uart_Ctrl->setText("打开串口");
        QMessageBox::warning(this, "警告", "串口数据格式错误!");
    }
    rx_buf.clear();
}

关于串口的详细使用,可以参考最开始学习Qt时做的一个练手项目:Qt小项目之串口助手控制LED

QCustomplot绘图库的使用

1.添加库文件到工程

库文件的下载:QCustomPlot-source.tar.gz

或者到官方网站下载最新版的库文件:qcustomplot

主要就两个文件qcustomplot.hqcustomplot.cpp,把两个文件添加到Qt工程

2.pro文件添加

qcustomplot包含了一些打印的功能,所以需要包含打印的支持

QT += printsupport

3.UI界面添加Widget绘图窗口

UI界面添加Widget绘图窗口,并右键把它提升为QCustomPlot类,Qt提升控件时,通常提升的类名称中,每个单词的首字母必须大写,否则无法识别,如这里必须写成QCustomPlot而不能写成Qcustomplot或qcustomplot

4.Widget的初始化:

ui->widget->setBackground(QBrush(Qt::white));   //设置背景颜色
ui->widget->axisRect()->setupFullAxesBox();//在坐标轴右侧和上方画线,和X/Y轴一起形成一个矩形
ui->widget->legend->setFont(QFont("Helvetica", 12)); //设置图例字体和大小
ui->widget->legend->setVisible(true);       //使能图例可见
ui->widget->xAxis->setLabel("时间"); //设置X轴文字标注
ui->widget->yAxis->setLabel("电压值");//设置Y轴文字标注
ui->widget->yAxis->setRangeLower(1);
ui->widget->yAxis->setRangeUpper(3);
//    ui->widget->yAxis->setRangeLower(-2);            //设置y轴最小值
//    ui->widget->yAxis->setRangeUpper(3);            //设置y轴最大值
//    ui->widget->graph(0)->setLineStyle(QCPGraph::lsLine);
//    ui->widget->graph(0)->setPen(QPen(Qt::blue));
ui->widget->addGraph();
QPen pen(Qt::red, 1.5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
ui->widget->graph(0)->setPen(pen);
ui->widget->graph(0)->setName("心跳曲线");

5.实时显示串口发来的电压值

在串口接收的槽函数中实现:

ui->widget->graph(0)->addData(x, SensorValue);
ui->widget->xAxis->setRange(x, 40, Qt::AlignRight);
ui->widget->replot();

QCustomplot是Qt开发环境下一个很强大而又简单的绘图库,关于QCustomplot库的详细使用方法,可以参考这篇文章:Qt-QCustomplot画静态、动态曲线教程图解

软件自动更新功能的实现

这个上位机包含了一个检测更新的小功能,如果有新版本,点击检查更新会弹出如下窗口,如果点击去下载,会直接跳转到浏览器,创建下载任务。

详细的实现思路和过程,可以看我写的笔记:Qt实现软件自动更新的一种简单方法

软件的下载

有需要这个上位机软件的朋友,可以直接下载:uFun_Pulse_v1.1.exe

总结

这两周利用周末的时间,把uFUN开发板+传感器实现心率计这个小项目的实现过程写完了,整体来看,写的不是很详细,但具体的实现思路介绍的还算清晰,希望能对大家有一些帮助。上位机目前还有一些小BUG待解决,等有点时间,再继续完善。

uFUN评测系列文章



欢迎大家关注我的个人博客www.wangchaochao.top

或微信扫码关注我的公众号

原文地址:https://www.cnblogs.com/whik/p/10659235.html

时间: 2024-10-16 06:37:27

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

emWin 移植 - 基于红牛开发板

一直想利用所学的东西自己设计一个精致一些的作品,手头正好有一块红牛开发板,就先用它来写一些软件,熟悉一下过程和一些想法的可行性.首先当然是选择一个操作系统了,对比了几种之后选择了emWin.那就移植一下吧. 这里首先要感谢一下http://www.openedv.com/posts/list/0/27697.htm 这篇帖子.我的思路基本是照着这个帖子做的.感谢楼主把辛苦的研究成果贡献出来,让我这个菜鸟能够快些入门. STemWin下载地址: http://www.st.com/web/en/c

基于Nucleo开发板STM32F4XX模版的建立与ST-Link的配置

本文将建立一个基于Nucleo开发板和KEIL5.14的工程模版,由一下几个部分组成: 1.工程模版的建立 2.STlink的设置与永远的流水灯 1.工程模版的建立 1)在建立工程之前,首先建立一个存放模版文件的文件夹,我们把它叫做template.然后在建立6个子文件夹:Doc,Libraries,Listing,Output,Project,USER,在Libraries里建立CMSIS和FWlib文件夹,在CMSIS中建立startup,这些文件夹的名字可以任意取的,这样命名只是为了方便识

基于.net开发chrome核心浏览器【三】

原文:基于.net开发chrome核心浏览器[三] 本篇我们讲解怎么用CefGlue开发一个最简单的浏览器 一: CefGlue是建立在Cef项目之上的,Cef项目是C/C++的项目:CefGlue只不过是通过PInvoke来访问Cef项目生成的一些dll下面我们来看看Cef项目生成的一些dll和资源都是做什么用的打开这个目录\cef_binary_3.1453.1236_windows_xilium\Releaselibcef.dll-------------------------->Cef

基于Tiny210开发板视频显示

基于Tiny210开发板视频显示 1.写基于V4L2编程 ========videodevice.h文件========= #ifndef VIDEODEVICE_H #define VIDEODEVICE_H #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/m

CC2540开发板学习笔记(三)&mdash;&mdash;外部中断

一.实验内容 通过外部中断方式依次按下按键S1控制LED1的亮灭 二.实验过程 1.电路原理图同上 2.中断的概念 比如说我们在执行main函数时,突然来了个指令.优先级比现在执行的main还高,那我们便选择跳过去执行优先级高的,完了之后再执行main函数,中断就类似这样一个概念,使用中断可以减少CPU的无效浪费,降低能耗. 3.寄存器调度 (1)LED1的初始化..同前两节,就是SEL,DIR,INP三个,还有附初始状态. (2)外部中断初始化(S1的外部中断初始化) 按键S1外部中断初始化方

基于JZ2440开发板编写bootloader总结(一)

凡走过必留下痕迹,学点什么都会有用的. 本系列博文总结了自己在学习嵌入式Linux编程过程中的收获,若有错误,恳请指正,谢谢! --参考教材韦东山系列教材 bootloader 是一个用于启动linux内核的C程序,为了达到最终启动内核的目的需要完成以下几个步骤: step1:硬件相关初始化,为启动内核准备硬件平台: step2:将内核从NAND FLASH读取到SDRAM: step3:设置需要传递给内核的启动参数: step4:跳转到SDRAM,运行内核: 下面将详细讲述各个步骤细节: 第一

基于麒麟座开发板2.0的MQTT实现例程

链接--->https://sanwen8.cn/p/649shZ1.html OneNET现已全面适配标准MQTT协议,相信这一功能的增加会**便于开发者进行设备的接入. OneNET提供了MQTT的C语言版本的SDK供大家使用,接下来我们将利用该SDK,将MQTT协议移植到麒麟座开发板上,希望这边文章能对希望使用MQTT接入OneNET的开发者提供一定帮助.? (本文中使用的SDK.调试工具.以及说明文档,均可以在官网文档中心中的MQTT专区下载) - 下载SDK - (一) ? 首先进入我

基于TQ2440开发板的WiFi模块的使用经验总结

一.软.硬件资源准备: 内核版本:linux-2.6.30.4 交叉编译器版本:4.3.3 wpa_supplicant工具:wpa_supplicant-0.7.3.tar ; openssl-0.9.8e.tar 开发板:TQ2440 无线网卡芯片:RTL8192CU,(淘宝上35元购买了一个USB接口的无线网卡:http://item.taobao.com/item.htm?spm=a1z09.5.0.0.H6U4Yy&id=25936180156&_u=kk57vmr1977) 无

学习手记-基于iTOP4412开发板NFS服务器搭建及测试

NFS特点: 1)基于UDP/IP 2)功能和网盘基本上差不多,但性能没那么强. NFS服务器搭建步骤: 在ubantu上安装nfs软件:nfs-kernel-server 配置文件 1)打开配置文件:/etc/exports 2)增加配置:/home/topeet/minLinux/ *(rw,sync,no_root_squash) 含义如下: /home/topeet/minLinux/:服务器上的共享目录 *:表示接受任何网段的访问 rw:可读可写 sync:同步 no_root_squ