热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

arduino串口绘图_Arduino趣味制作脉搏传感器测量心率

在本期文章中,我们来介绍一种利用脉搏传感器输出的模拟信号计算心率的方法。该方法经测试,得出的心率值还是比较准确的,且测量效率较高。下面先来

在本期文章中,我们来介绍一种利用脉搏传感器输出的模拟信号计算心率的方法。该方法经测试,得出的心率值还是比较准确的,且测量效率较高。下面先来介绍一下文中所用的脉搏传感器。

5fa54e71d9d8d0439d382eba80f95dd7.png

该传感器测量脉搏的强度,输出一个模拟信号。其测量脉搏使用了“光电容积法”。下面是模块手册上摘抄的原理说明:“光电容积法是利用人体组织在血管搏动时造成透光率不同来测量脉搏的。光源采用对动脉血中氧和血红蛋白有选择性的一定波长(500NM-700NM)的发光二极管。当光束透过外周血管,由于动脉搏动充血容积变化导致透光率发生变化,此时用光电变换器接收经人体组织反射的、变化的光信号,转变为电压信号输出。”这种传感器测量时只需用手指接触或夹在耳垂上即可测量,但缺点就是当皮肤潮湿或接触传感器不充分则测量会失效。

下面,我们先用Arduino采集传感器的原始数据,用串口将原始数据输出到ArduinoIDE的“串口绘图”看看“心电图”。(代码比较简单,只需要启动串口,然后“打印”AD采样的值即可。)下图为传感器与手指接触良好时得到的曲线,采样周期为10毫秒:

7c3a31452ef24bc23e3e731a4dd93d21.png

接下来看看当手指未接触传感器时得到的曲线:

6b6c8c6092cf4bce8990c738d4fad64f.png

从上面两图可以看到,当传感器采集到脉搏时,会输出与心跳一至的“搏动”信号,其最大值在800左右,最小值在400左右,我们可以通过串口监视器看到具体的数值。这两个值因人而异,不同的人会得到不同的峰谷值。当手指移开,传感器“悬空”,则得到第二图中的曲线,数据会在500-600之间有一个很小的波动。至此,我们对传感器的输出信号有了一个基本的认识,但本文的关键不是看看这个“心电图”,虽然系统采集并打印了数据,但系统并不知道所采集的“心电图”中,心率-心跳次数是多少,所以,接下来的关键就是设计一个处理方法,从“心电图”中获取心跳次数。

在我最初接触这个传感器时,我觉得要算出心率很简单啊:一分钟内统计来了多少个波峰不就知道心率了。然而事实上,这个方法并不奏效,它存在两个问题:1、如何统计“波峰”;2、测量一次心率,至少需要连续采样信号一分钟以上,效率太低。经过查阅资料及仔细的思考,我确立了这样一个计算思路:测量两次“波峰”之间的间隔时间,就可以推算一分钟内的心率。但是仍然存在一个问题:如何判断“波峰”?从波形中我们很容易想到:设定一个“阈值”,当数值大于该阈值时则记为一个波峰。但是,波峰阈值设定为多少合适呢?不同的人,或者同一个人不同时间或不同状态,得到的波峰值都不一致,这个方法还是不行,从上面的图中我们可以看到,每个波峰的峰值其实都不一致,其中一个波峰相对于其他的波峰“矮”了不少,如果简单地设定阈值,对于计算心率可能会出现很大的误差。那么,怎样才能准确地判断一个波峰呢?

通过观察波形,可以得到:一个波峰必然经历一个“单调递增”和一个“单调递减”的过程,因此我们可以在采样一次数据后,马上对“曲线”进行“求导”,也就是计算曲线的斜率,用本次的采样值减去上一次的采样值得出一个“导数”。曲线在单调递增的区间,导数是正的;在单调递减区间,导数是付的;在波峰的封顶,必然有一个导数为零的地方。实际上,导数为0的点是我们进行定时计算的最佳点,但这个点是很难采样到的,因此,只能把导数第一次“由正变负”的时刻作为计时开始及计算的特征点。另外,在“心电图”中我们还能看到,在“大波峰”的旁边,还伴随着一个“小波峰”,这个小波峰的导数也有同样的变化过程,而这个小波峰对于心率计算是没有作用的,但如果我们不作处理,就会对心率计算产生巨大影响。为了“去掉”小波峰,可以在采样中记录曲线的最大值和最小值,当系统检测到导数为负数时,参考当前采样值是否小于最大值且大于最小值加上一定的值,这样既可将小波峰的影响隔离掉。

下图中的定理说明了函数单调性与导数的关系:

c1c7b5537adc97ceb549496d14d7f9a9.png

基于上述方法,在第一次试验中,直接引入了AD采样的值进行计算,得出的结果是失败的,分析原因就是“导数”一直在正负切换。再次分析“心电图”发现,这是由于“心电图”的“毛刺”引起的,因此,在进行导数计算之前,还应该对AD采样的值进行滤波处理。借助之前对陀螺仪加速度计数据处理的经验,这里可以采用一阶滞后滤波的方法来处理,其实就是本次的输出值为上一次的输出值与本次测量值的加权和。下面看看滤波后的心电图,采样周期为10毫秒:

2311de2aedb151e001bbbc290cf6be8e.png

从上图中看到,经过滤波后的“心电图”变得光滑了很多,“毛刺”消失了,且“小波峰”也被“拉平”了很多,这给心率计算带来了极大的好处。下面给出基本“心电图”打印的代码及心率计算输出的代码:

0fc4958fa5d4305a6d3ce8dbda0dffa5.png

37e8c5b7ce28c508e3e6eac07c387bef.png

下面是心率测量计算的输出显示:

c6d2b524969bc575f6cf2efd8fb2a25f.png

在上面的代码中,以13号引脚上LED同步指示心跳-即LED随心跳闪烁。在测量过程中,如果系统检测到“导数”始终在正负5的范围内(该范围可以通过串口输出导数值确定)或AD采样滤波值低于最大峰值减去200,则开始计数,如果连续两秒符合这个条件,则系统会判定手指已移开或无心跳,此时会将曲线最大值与最小值进行“复位”处理。

下面是演示视频:

      欢迎关注智造DIY创客空间,后续将陆续分享飞思卡尔、STM32的学习过程以及更多Arduino的趣味制作。我们一直致力于创客课程及项目开发实战的研究。暑期青少年创客活动课程继续!

ddb2737fc2bf082ba99ce7efe7540be3.png

地址:玉溪市红塔区红塔大道50号商务大楼305室智造DIY创客空间

电话:13577781795




推荐阅读
  • vue使用
    关键词: ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 最近学习反射机制的时候Properties.load(读取本地文件流的时候怎么也找不到加载文件后面发现IDEA的默认根目录是在它的Project工程下IDEA的文件目录和Ec ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文讨论了如何在不使用SearchBar display controller的情况下,单独使用SearchBar并捕获其textChange事件。作者介绍了实际状况,即左侧SliderMenu中的SearchBar需要在主页TableView中显示搜索结果。然后,作者提供了解决方案和步骤,帮助读者实现这一功能。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 在使用Visual Studio 2019评估Blazor时,将taghelper添加到剃刀文件时会出现错误。错误信息是"标记助手:@addTagHelper *,BlazorPOC.Validations"。需要在文件顶部添加@using语句"@using BlazorPOC.Validations"来解决这个问题。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
author-avatar
前前后后zzyyix
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有