基于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.h
和qcustomplot.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评测系列文章
- 基于uFUN开发板的心率计(一)DMA方式获取传感器数据
- 基于uFUN开发板的心率计(二)动态阈值算法获取心率值
- Qt实现软件自动更新的一种简单方法
- 【UFUN开发板评测】小巧而不失精致,简单而不失内涵——uFun开发板开箱爆照
- 如何使用串口来给STM32下载程序
- STM32串口打印输出乱码的解决办法
- Keil报错:cannot open source input file "core_cmInstr.h" 解决办法
欢迎大家关注我的个人博客:www.wangchaochao.top
或微信扫码关注我的公众号
基于uFUN开发板的心率计(三)Qt上位机的实现的更多相关文章
- 基于uFUN开发板的心率计(二)动态阈值算法获取心率值
前言 上一篇文章:基于uFUN开发板的心率计(一)DMA方式获取传感器数据,介绍了如何获取PulseSensor心率传感器的电压值,并对硬件电路进行了计算分析.心率计,重要的是要获取到心率值,本篇文章 ...
- 基于uFUN开发板的心率计(一)DMA方式获取传感器数据
前言 从3月8号收到板子,到今天算起来,uFUN到手也有两周的时间了,最近利用下班后的时间,做了个心率计,从单片机程序到上位机开发,到现在为止完成的差不多了,实现很简单,uFUN开发板外加一个Puls ...
- 基于uFUN开发板和扩展板的联网校准时钟
项目概述 上周在uFUN试用群里看到管理员说试用活动快结束了,要抓紧完成评测总结,看大家的评测总结也都写了,我也不能落后啊!正好最近做的扩展板到手了,于是赶紧进行调试,做了一个不用校准的时钟,时钟这种 ...
- 基于uFUN开发板的RGB调色板
前言 使用uFUN开发板配合Qt上位机,实现任意颜色的混合,Qt上位机下发RGB数值,范围0-255,uFUN开发板进行解析,然后输出不同占空比的PWM,从而实现通过RGB三原色调制出任意颜色. Qt ...
- 千呼万唤始出来——uFUN开发板2.0开箱评测
前言 今年3月,我参与了面包板社区组织的第一批uFUN开发板评测活动,并有幸能获得试用机会,那是我第一次了解到uFUN这个项目及背后的故事,4月份,uFUN 2.0版本来了,收到了张工送的一块样板,后 ...
- 【UFUN开发板评测】小巧而不失精致,简单而不失内涵——uFun开发板开箱爆照
关于uFun学习板--"满满的爱和正能量" uFun是由@张进东 张工组织发起的一个开源的学习板,设计初衷是为了帮助学生更好的理解电子知识和开发技巧,同时又能对学生毕业找工作有很明 ...
- 基于.net开发chrome核心浏览器【三】
原文:基于.net开发chrome核心浏览器[三] 本篇我们讲解怎么用CefGlue开发一个最简单的浏览器 一: CefGlue是建立在Cef项目之上的,Cef项目是C/C++的项目:CefGlue只 ...
- 基于 Arduino 开发板,这款插座是可编程且开源的
基于 Arduino 开发板,这款插座是可编程且开源的 https://www.oschina.net/news/74861/open-source-socket https://github.com ...
- 【RTOS】基于V7开发板的uCOS-III,uCOS-II,RTX4,RTX5,FreeRTOS原版和带CMSIS-RTOS V2封装层版全部集齐
RTOS模板制作好后,后面堆各种中间件就方便了. 1.基于V7开发板的最新版uCOS-II V2.92.16程序模板,含MDK和IAR,支持uC/Probe https://www.cnblogs.c ...
随机推荐
- python第八天)——购物车作业优化完成
发现之前的三级菜单代码有BUG现已经修改过来了 购物车程序:启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够, ...
- Java获取数据库表 字段 存储的部分数据
在浏览器页面,选中图片(可多选) >单击删除按钮. 重点是, 本数据库表TabHeBeiTianQi中 存在 同一id,对应的picLocalPath字段 存储了多张图片,图片地址用 逗号 ...
- 用Python实现数据结构之映射
映射与字典 字典dict是Python中重要的数据结构,在字典中,每一个键都对应一个值,其中键与值的关系就叫做映射,也可以说是每一个键都映射到一个值上. 映射(map)是更具一般性的数据类型,具体到P ...
- Win10安装Redis
Redis安装 下载地址:https://github.com/MicrosoftArchive/redis/releases 下载对应的版本:这里下载Redis-x64-3.2.100 解压文件 进 ...
- 使用zip压缩文件夹方法
最近使用MapGis对.MPJ工程文件文件裁剪后,要对裁剪后的图形文件.ML,.MT,.MP,.MPJ文件打包,在网上找到7zip,Zlib的库,虽然都有源码,但是Zlib库中的使用没找到文件压缩的函 ...
- fedora添加ntfs文件系统支持
ntfs支持(安装后不能打开,重启) 如果没有换源先看一下换源. 查找库中是否有ntfs-3g. [root@bogon zhujikuan]# yum search ntfs 上次元数据过期检查:0 ...
- Shell脚本应用(for、while循环语句和case分支语句)
1.for:读取不同的变量值,逐个执行同一组命令,直到取值完毕退出,变量值以空格分隔 语法: for 变量值 in 取值列表 do 命令序列 done 2.while:重复测试某个条件,成立则执 ...
- 使用golang求出A-Z的所有子集
参考链接:https://blog.csdn.net/K346K346/article/details/80436430 有一个集合由A-Z这26个字母组成,打印这个集合的所有子集,每个子集一行,写C ...
- Source Insight4 破解安装
首先确保你在官网下载了原版4.0并安装好了. 1,下载如下的sourceinsight4.exe文件,替换安装文件夹下的sourceinsight4.exe. 链接:http://pan.baidu. ...
- 开启 J2EE(一)—‘全明星队伍’
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/akkzhjj/article/details/27973427 J2EE-一套规范 J2EE(Jav ...