这次带来一篇使用手机观察心率波形的教程,这可能是最后一篇 关于蓝牙调试器的“硬核广告” 了,这几天一直做这个真的做的有些反感了,感觉时间被浪费,如果有人能从中受益就好了,但看起来不是所有的付出都有收获。不废话了,先看一下效果吧:

这次使用的是MAX30102型的心率检测模块,其为光电投射式的,因为血液对特定波长的光有吸收作用,每次心脏泵血时,该波长都会被大量吸收,以此就可以确定心跳。在使用这种模块时,要注意只能使用手指或其他皮肤比较容易透光的部位进行检测。使用手背或者其它部位基本是检测不到的。估计是因为皮肤中的黑色素会吸收大部分的光,而手指部分皮肤黑色素较少,因此会比较明显。

一、单片机端

1.1硬件连接

MAX30102提供了I2C的接口用于与单片机通信,其作为从设备的地址为0xAE。从图中可以看到其共有八个引脚,其中我们只用了四个,两个用于供电,这个模块可以直接使用3.3V供电。然后SCL和SDA引脚用于I2C通信。

1.2程序编写

完整代码在这里

1.2.1MAX30102驱动

一开始我使用的是STM32的硬件I2C接口,但是搞了半天,发现STM32的硬件I2C一直卡在BUSY标志,没法正常使用,一直听说STM32的硬件I2C不好用,这次真的是吃了教训了。没有办法,又重新写了一个使用IO口来模拟I2C的程序 fake_i2c,fake_i2c的初始化有些不同,下面程序中init_fake_i2c(1,2,MAX30102_ADD,1)的参数 1,2,MAX30102_ADD,1  其中“1”的含义是I2C通信时钟周期系数,该数越小,则通信速率越高,MAX30102最高支持400kHz的通信频率,数据传输还是挺快的。其中的“2”的含义是等待Ack的延时周期,如果从设备在2个时钟周期没有回应,则判定为无Ack。接下来的“MAX30102_ADD”是MAX30102的通信地址。最后的“1”是寄存器地址的宽度,表示宽度为1byte。

//------------------------------------------------------------------------------------------------------

//初始化心率检测模块 MAX30102

//设置模式 : 可设置仅 心率 或 SPO2模式

//设置两种光源的亮度brightness : 配置亮度,范围是00~ff

void initMAX30102(unsigned char mode,unsigned char ir_led_brightness,unsigned char red_led_brightness){

init_fake_i2c(1,2,MAX30102_ADD,1);

fake_i2c_write_reg(0x02,0xf0);

fake_i2c_write_reg(0x03,0x02);

fake_i2c_write_reg(0x04,0x00);

fake_i2c_write_reg(0x05,0x00);

fake_i2c_write_reg(0x06,0x00);

fake_i2c_write_reg(0x08,0x1f);

fake_i2c_write_reg(0x09, mode);

fake_i2c_write_reg(0x0a,0x61);

fake_i2c_write_reg(0x0c, ir_led_brightness);

fake_i2c_write_reg(0x0d, red_led_brightness);

}

然后是数据的读取:

//-------------------------------------------------------------------------------------------------------

//读取采样值

//这些采样值都是经过一定的滤波处理的

//将变量地址传入以读出数据

void MAX30102_ReadValue( float *ir_v,float *red_v){

static unsigned short last_ir,last_red;

static float rate_ir,rate_red;

unsigned char buffer[6];

unsigned char state;

unsigned short raw_value_ir;

unsigned short raw_value_red;

state =fake_i2c_read_reg(0x04);//读取FIFO新数据的数目,如果非0,说明有新的数据

if(state){

fake_i2c_read_buff(0x07,6,buffer);

fake_i2c_write_reg(0x04,0x00);

fake_i2c_write_reg(0x06,0x00);

raw_value_ir = (buffer[1]<<8)+buffer[2];

raw_value_red = (buffer[4]<<8)|buffer[5];

if(raw_value_ir!=last_ir)

rate_ir += ((raw_value_ir-last_ir)-rate_ir)*0.18f;

if(raw_value_red!=last_red)

rate_red += ((raw_value_red-last_red)-rate_red)*0.18f;

last_ir = raw_value_ir;

last_red = raw_value_red;

}

(*red_v)+=rate_red;

(*ir_v)+=rate_ir;

(*ir_v)*=0.8f;

(*red_v)*=0.8f;

if(*ir_v>MAX30102_FILTERED_VALUE_RANGE)

*ir_v = MAX30102_FILTERED_VALUE_RANGE;

if(*ir_v<-MAX30102_FILTERED_VALUE_RANGE)

*ir_v = -MAX30102_FILTERED_VALUE_RANGE;

if(*red_v>MAX30102_FILTERED_VALUE_RANGE)

*red_v = MAX30102_FILTERED_VALUE_RANGE;

if(*red_v<-MAX30102_FILTERED_VALUE_RANGE)

*red_v = -MAX30102_FILTERED_VALUE_RANGE;

}

在这里并没有输出读取的原数据,而是采用一些滤波的算法,先微分,然后确定波动变化率,再对波动变化率积分,并且将积分的数值通过系数向0靠拢,以及限幅,总之就是什么乱七八糟各种手段用上,最终得到一串看得过去的波形。至于心率和血氧等的计算我就偷个懒不写了。

1.2.2通信配置

//根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目

#define TX_BOOL_NUM 0

#define TX_BYTE_NUM 0

#define TX_SHORT_NUM 0

#define TX_INT_NUM 0

#define TX_FLOAT_NUM 2

1.2.3主函数

/// ir:红外 red:红光 检测两种光源的反射程度

TxPack txpack;

float ir_value,red_value;

int main(void)

{

initMAX30102(MAX30102_MODE_IR,0x66,0x65);

initValuePack(115200);

while(1)

{

//延时

for(inti=0;i<20000;i++)

{}

MAX30102_ReadValue(&ir_value,&red_value);

txpack.floats[0] = ir_value;

txpack.floats[1] = red_value;

sendValuePack(&txpack);

}

}

二、手机端

详细的手机端应用的介绍见这里,接下来就默认你看过我之前的教程了

2.1通信配置

我们可以从MAX30102读取到两种不同光源的光反射量,分别读取红外光和红色可见光下血液吸收量。

2.2编辑控件

这里为了观察更方便,我们将工程切换为横屏视图

然后编辑控件,添加了一个波形图和一个能量槽:

链接数据,这里我只链接了IR 红外光的检测值。能量槽上下限的设置需要注意,可以设置为-300~300,如下图

至此就可以连接蓝牙模块,运行此工程,你就能看到自己的心跳了。

STM32驱动MAX30102代码在这里

另附MAX30100的代码

应用可以在这里扫码下载

如果本文对你有用的话,来个红包支持一哈

单片机无线调试-看见心跳-手机显示心率波形相关推荐

  1. Android无线调试出现错误的解决方法

    1. adb相关无线调试的命令: adb tcpip <PORT> 是通过TCPIP的无线方式连接Android设备,PORT为端口号,可以随意指定 (如:adb tcpip 6666)) ...

  2. Android adb无线调试脚本

    使用adb的无线调试功能十分的方便. 但是实际工作中,总是要手动输入,十分麻烦.所以就把它写成脚本文件. 使用步骤 连接上USB 运行脚本文件(windows双击运行bat文件,mac的话termin ...

  3. android dhcp 脚本,Android adb无线调试脚本

    image.png 使用adb的无线调试功能十分的方便. 但是实际工作中,总是要手动输入,十分麻烦.所以就把它写成脚本文件. 使用步骤 连接上USB 运行脚本文件(windows双击运行bat文件,m ...

  4. android studio 无线手机调试插件,Android Studio ADB Wifi 无线调试

    关于在Android studio中ADB WIFI插件实现无线调试的使用 一.安装Adb Wifi插件 打开File->perfrence->plugins->Browse rep ...

  5. Android手机无线调试

    一.啥是无线调试?为啥需要无线调试 平时我们调试APP的时候,会将手机连接到USB数据线,然后再将数据线连接到电脑上.但是,由于长期插拔或者USB线材材质的问题,经常会出现无法连接的问题:而且,通常公 ...

  6. Android Studio小米手机无线调试

    之前只尝试过usb和在虚拟机上调试,这次安装flamingo版本之后发现可以无线调试,用自己手机试了下,挺方便的.具体如下: 1.手机电脑连接同一个wifi 2.小米手机进入设置 - 我的设备 - 全 ...

  7. 安卓手机用WIFI无线调试adb

    1.准备连接 1.首先将电脑和手机连接同一个WIFI,并插上数据线 2.打开电脑CMD,输入命令adb start-server开启adb服务 3.输入adb devices 查询已连接的设备 Lis ...

  8. 还在用数据线调试手机?我教你无线调试

    前言 相信大部分学安卓开发的新人还在使用数据线来调试应用,这是很正常的现象,毕竟数据线是必备品,而且有线调试传输速度快,而且更稳定. 但是呢,有时候用数据线会显得桌面比较乱,有时候还会忘记带数据线,更 ...

  9. 148、基于STM32单片机的心跳心率波形采集系统

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 一.功能介绍 二.实物图 三.原理图 四.程序 五.资料包括 一.功能介绍 (1)采用MAX30102实时采集人体心率波形,通过OLED显示屏绘制成 ...

最新文章

  1. 正确“假期休息模式”
  2. 秘籍 | 机器学习数据集网址大全
  3. 武大+CMU最新开源!全面支持平面/鱼眼/球面相机的实时统一线段检测算法
  4. Intel汇编语言程序设计学习-第四章 数据传送、寻址和算术运算-上
  5. Java 8特性探究(1):通往lambda之路_语法篇
  6. de casteljau算法_泊松分布算法的应用:开一家4S店
  7. c++ 编译添加dll_matconvnet安装、编译、配置
  8. python算法与数据结构-冒泡排序算法(32)
  9. spark官方文档_这些未在 Spark SQL 文档中说明的优化措施,你知道吗?
  10. MyEclipse导入项目后 js文件报错
  11. matlab时频分析工具箱安装_科研小班 | 加州大学伯克利分校 | 物理、电子工程:MATLAB信号和数据处理课题...
  12. 从代码到上线, 云端Docker化持续交付实践
  13. python定位相邻节点_Python selenium —— 父子、兄弟、相邻节点定位方式详解
  14. ES系列三、基本知识准备
  15. 利用VBB仿真——实现《天空之城》播放
  16. 计划学Linux,老男孩Linux怎么样?真实的学员评价!
  17. 短时间提高英语口语方法
  18. iCollections—桌面管理工具
  19. Glance 镜像服务
  20. 【Cesium】智慧城市建筑白模泛光特效

热门文章

  1. 从0到1搭建kubernetes集群
  2. 二进制部署高可用Kubernetes v1.17.x
  3. Weex实战分享|企鹅电竞Weex实践和性能优化
  4. Push还是Pull,这是个问题么?
  5. Django新手入门教程(2)测试服务器是否可用
  6. 行流 - 通用;仅使用库存接口开单 and 行流 - 通用;
  7. powerpoint预览_如何调整PowerPoint模板的大小
  8. jzoj5234. 【NOIP2017模拟8.7A组】外星人的路径
  9. 基于java后端的 krpano 功能化
  10. Codeforces 272C Dima and Staircase 思维 or 线段树