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

单片机无线调试-看见心跳-手机显示心率波形_第1张图片

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

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

一、单片机端

1.1硬件连接

单片机无线调试-看见心跳-手机显示心率波形_第2张图片

    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通信配置

单片机无线调试-看见心跳-手机显示心率波形_第3张图片

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

2.2编辑控件

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

单片机无线调试-看见心跳-手机显示心率波形_第4张图片

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

单片机无线调试-看见心跳-手机显示心率波形_第5张图片

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

单片机无线调试-看见心跳-手机显示心率波形_第6张图片

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

单片机无线调试-看见心跳-手机显示心率波形_第7张图片

STM32驱动MAX30102代码在这里

另附MAX30100的代码

应用可以在这里扫码下载

单片机无线调试-看见心跳-手机显示心率波形_第8张图片

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

你可能感兴趣的:(无线控制,无线控制,心率检测,MAX30102,MAX30100,蓝牙调试器)