开发环境:

Arduino-1.8.5-windows.exe、HXDZ-30102-ACC

硬件设备:

MAX30102

MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块。

它集成了一个红光LED和一个红外光LED、光电检测器、光器件,以及带环境光抑制的低噪声电子电路。

采用一个1.8V电源和一个独立的5.0V用于内部LED的电源,应用于可穿戴设备进行心率和血氧采集检测,佩戴于手指、耳垂和手腕等处。

标准的I2C兼容的通信接口可以将采集到的数值传输给Arduino、KL25Z等单片机进行心率和血氧计算。

该芯片还可通过软件关断模块,待机电流接近为零,实现电源始终维持供电状态。

集成了玻璃盖可以有效排除外界和内部光干扰,拥有最优可靠的性能。

心率血氧传感器模块(HXDZ-30102-ACC)

集成了LIS2DH12(ST的三轴加速传感器,用于记录运动数据)和MAX30102(血氧和心率检测记录)。

传感器参数:

电路板尺寸:38*16mm

电路板厚度:2.5mm

LED峰值波长:660nm/880nm

LED供电电压:3.3v~5v

检测信号类型:光反射信号(PPG)

输出信号接口:I2C接口(数字接口)

通信接口电压:3~5v

工作电路:1.5mA(3.3v 输入)

心率精确度:+/- 5bpm,+/- 10bpm(动态)

分辨率: 1bpm

采样率:100Hz(STM32程序)/ 25Hz(arduino程序)

接口说明

VCC:LED电源输入端,也是I2C总线上拉电平,可以接3.3v或者5v

GND:地线

SCL:I2C总线的时钟引脚

SDA:I2C总线的数据引脚

I_L:LIS2DH12芯片的中断引脚

I_M:MAX30102芯片的中断引脚

工作原理

传统的脉搏测量方法主要有三种:

1、从心电信号中提取

2、从测量血压时压力传感器测到的波动来计算脉率

3、光电容积法

前两种会限制病人的活动,长时间使用会加重病患的心理和生理负担,而光电容积法在实际中时普遍使用的一种有效方法,其特点:方法简单、佩戴方便、可靠性高。

光电容积法基本原理:

利用人体组织在血管搏动时造成透光率不同来进行脉搏和血氧饱和度测量的。其使用的传感器由光源和光电变换器两部分组成,通过绑带或夹子固定在病患的手指、手腕或耳垂上。光源一般采用对动脉血中氧合血红蛋白(Hb02)和血红蛋白(Hb)有选择性的特定波长的发光二极管(一般使用660nm附近的红光和900nm附近的红外光)。当光束透过人体外周血管,由于动脉搏动充血容积变化导致这束光的透光率发生改变,此时由光电变换器接收经人体组织反射的光线,转变为电信号并将其放大和输出。

由于脉搏是随心脏的搏动而周期性变化的信号,动脉血管容积也周期性变化,因此光电变换器的电信号变化周期就是脉搏率。同时根据血氧饱和度的定义,其表示为:

计算公式.png

image.png

注意:

1、SaO2 :广义上的氧饱和度,常指血液样品中的氧含量对该样品血液最大氧含量的百分比(SpO2是经皮血氧饱和度, 而SaO2是动脉血氧饱和度,二者不同,但是相关性好,绝对值十分接近)。

2、HbO2:氧合血红蛋白

3、Hb:还原血红蛋白

MAX30102本身集成了完整的发光LED及其驱动部分,光感应和AD转换部分,环境光干扰消除及数字滤波部分,只将数字接口留给用户,极大地减轻了用户的设计负担。用户只需要使用单片机通过硬件I2C或者模拟I2C接口来读取MAX30102本身的FIFO,就可以得到转换后的光强度数值,通过编写相应的算法就可以得到心率值和血氧饱和度。

工作原理.png

实现算法

心率和血氧饱和度算法流程图:

算法流程图.png

工作流程

首先连接开发板串口,波特率需要进行必要设置,奇偶校验位无,上电后,复位MAX30102,并开始对MAX30102进行功能初始化,此时Red LED和 IR LED交替点亮来检测人体皮肤下血液的搏动和血氧含量(此时可以看到MAX30102有红光亮起,说明初始化成功)。开发板将一段时间内MAX30102采集的LED反射数据存储在内部RAM中,然后分别计算Red LED和 IR LED的直流成分(DC)和交流成分(AC),最后算出数值R并通过预先存储在两波峰之间的时间差T来确定,每分钟心跳数BPM=60/T。(具体算法原理可以参考AN6409芯片手册中29~31页说明)

red和ir是红色LED,红外LED的原始数据,HR表示心率值,HRvalid是心率是否有效标识,SPO2是血氧数值,SPO2valid是血氧首付有效标识

血氧模块与Arduino连接说明:

接口连接说明:

Arduino和HXDZ-30102-ACC接口说明.png

实际连接图:

实物连接图.png

原理图管脚说明:

Arduino UNO原理图.png

实现代码

/*

引脚连接关系

Arduino UNO HXDZ-30102/HXDZ-30102-ACC

SDA SDA

SCL SCL

PIN 10 INT/I_M

5V VCC

GND GND

*/

#include

#include "algorithm.h"

#include "max30102.h"

//if Adafruit Flora development board is chosen, include NeoPixel library and define an NeoPixel object

#if defined(ARDUINO_AVR_FLORA8)

#include "adafruit_neopixel.h"

//to lower the max brightness of the neopixel LED

#define BRIGHTNESS_DIVISOR 8

Adafruit_NeoPixel LED = Adafruit_NeoPixel(1, 8, NEO_GRB + NEO_KHZ800);

#endif

#define MAX_BRIGHTNESS 255

#define blinkPin 13

#if defined(ARDUINO_AVR_UNO)

//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format

//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.

uint16_t aun_ir_buffer[100]; //infrared LED sensor data

uint16_t aun_red_buffer[100]; //red LED sensor data

#else

uint32_t aun_ir_buffer[100]; //infrared LED sensor data

uint32_t aun_red_buffer[100]; //red LED sensor data

#endif

int32_t n_ir_buffer_length; //data length

int32_t n_spo2; //SPO2 value

int8_t ch_spo2_valid; //indicator to show if the SPO2 calculation is valid

int32_t n_heart_rate; //heart rate value

int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid

uint8_t uch_dummy;

// the setup routine runs once when you press reset:

void setup() {

#if defined(ARDUINO_AVR_LILYPAD_USB)

pinMode(13, OUTPUT); //LED output pin on Lilypad

#endif

#if defined(ARDUINO_AVR_FLORA8)

//Initialize the LED

LED.begin();

LED.show();

#endif

pinMode(blinkPin, OUTPUT); //LED output pin on UNO

digitalWrite(blinkPin,HIGH); // turn on pin 13 LED

delay(1000);

digitalWrite(blinkPin,LOW); // turn on pin 13 LED

delay(1000);

digitalWrite(blinkPin,HIGH); // turn on pin 13 LED

delay(1000);

digitalWrite(blinkPin,LOW); // turn on pin 13 LED

delay(1000);

digitalWrite(blinkPin,HIGH); // turn on pin 13 LED

delay(1000);

digitalWrite(blinkPin,LOW); // turn on pin 13 LED

delay(1000);

maxim_max30102_reset(); //resets the MAX30102

// initialize serial communication at 115200 bits per second:

Serial.begin(115200);

Serial.print(F("MAX30102 begins to start working"));

pinMode(10, INPUT); //pin D10 connects to the interrupt output pin of the MAX30102

delay(1000);

maxim_max30102_read_reg(REG_INTR_STATUS_1,&uch_dummy); //Reads/clears the interrupt status register

maxim_max30102_init(); //initialize the MAX30102

}

// the loop routine runs over and over again forever:

void loop() {

uint32_t un_min, un_max, un_prev_data, un_brightness; //variables to calculate the on-board LED brightness that reflects the heartbeats

int32_t i;

float f_temp;

un_brightness=0;

un_min=0x3FFFF;

un_max=0;

n_ir_buffer_length=100; //buffer length of 100 stores 4 seconds of samples running at 25sps

//read the first 100 samples, and determine the signal range

for(i=0;i

{

while(digitalRead(10)==1); //wait until the interrupt pin asserts

maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i)); //read from MAX30102 FIFO

if(un_min>aun_red_buffer[i])

un_min=aun_red_buffer[i]; //update signal min

if(un_max

un_max=aun_red_buffer[i]; //update signal max

}

un_prev_data=aun_red_buffer[i];

//calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)

maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

//Continuously taking samples from MAX30102. Heart rate and SpO2 are calculated every 1 second

while(1)

{

i=0;

un_min=0x3FFFF;

un_max=0;

//dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top

for(i=25;i<100;i++)

{

aun_red_buffer[i-25]=aun_red_buffer[i];

aun_ir_buffer[i-25]=aun_ir_buffer[i];

//update the signal min and max

if(un_min>aun_red_buffer[i])

un_min=aun_red_buffer[i];

if(un_max

un_max=aun_red_buffer[i];

}

//take 25 sets of samples before calculating the heart rate.

for(i=75;i<100;i++)

{

un_prev_data=aun_red_buffer[i-1];

while(digitalRead(10)==1);

digitalWrite(9, !digitalRead(9));

maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));

//calculate the brightness of the LED

if(aun_red_buffer[i]>un_prev_data)

{

f_temp=aun_red_buffer[i]-un_prev_data;

f_temp/=(un_max-un_min);

f_temp*=MAX_BRIGHTNESS;

f_temp=un_brightness-f_temp;

if(f_temp<0)

un_brightness=0;

else

un_brightness=(int)f_temp;

}

else

{

f_temp=un_prev_data-aun_red_buffer[i];

f_temp/=(un_max-un_min);

f_temp*=MAX_BRIGHTNESS;

un_brightness+=(int)f_temp;

if(un_brightness>MAX_BRIGHTNESS)

un_brightness=MAX_BRIGHTNESS;

}

#if defined(ARDUINO_AVR_LILYPAD_USB)

analogWrite(13, un_brightness);

#endif

#if defined(ARDUINO_AVR_FLORA8)

LED.setPixelColor(0, un_brightness/BRIGHTNESS_DIVISOR, 0, 0);

LED.show();

#endif

//send samples and calculation result to terminal program through UART

Serial.print(F("red="));

Serial.print(aun_red_buffer[i], DEC);

Serial.print(F(", ir="));

Serial.print(aun_ir_buffer[i], DEC);

Serial.print(F(", HR="));

Serial.print(n_heart_rate, DEC);

Serial.print(F(", HRvalid="));

Serial.print(ch_hr_valid, DEC);

Serial.print(F(", SPO2="));

Serial.print(n_spo2, DEC);

Serial.print(F(", SPO2Valid="));

Serial.println(ch_spo2_valid, DEC);

}

maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);

}

}

运行效果

初始化:

MAX30102初始化.png

无采集状态:

无采集数据.png

image.png

数据采集状态:

数据开始采集.png

ps:这里由于整体软件和硬件的标准没有像医疗设备的标准一样,所以只是验证性测试。

spo2数据集_Arduino 血氧心率模块传感器数据采集相关推荐

  1. spo2数据集_自己翻译的Max30100寄存器中文资料(血氧心率传感器IC)

    Max30100 可穿戴光电式的血氧心率传感器IC 总体描述: Max30100是一款集成的脉搏血氧和心率检测传感器.它使用了两个LED灯,一个用来优化光学的光电探测器,和低噪声模拟信号处理器,用来检 ...

  2. 血氧心率测量仪(带温湿度测量功能)OLED显示

    血氧心率测量仪(带温湿度测量功能)OLED显示 原理图资料 模块说明 测试数据处理图 部分代码展示 资料包 原理图资料 模块说明 数字温湿度传感 DHT11 ►相对湿度和温度测量 ►全部校准,数字输出 ...

  3. 基于STM32F030、MAX30102血氧心率监测仪的设计(三)

    本篇主要记录一下开发过程中遇到的问题与解决. max30102模块是某宝上购买的,价格不贵5元左右,如下图所示. 使用引脚为SDA.SCL.INT.VIN.GND 拿到模块后,看着资料开始移植程序,我 ...

  4. STM32WB55大半年开发记录,血氧心率检测手环

    1.STM32WB55开发经验 在长达大半年的STM32WB55蓝牙手环开发的过程当中,让我感受到了这款芯片的魅力和ST为其倾力打造的生态环境是真的很不错! 不过在开发STM32WB55这款芯片的时候 ...

  5. MAX30102脉搏血氧仪和心率传感器(四)血氧+心率完整版(STM32)

    文章目录 前言 一.先上测试结果 1.测试步骤 2.测试结果 3.后续处理方法 二.血氧饱和度 1.原理 2.计算方法 三.源码获取(STM32例程) 前言 相较于上一章,增加和改进的地方有:①增加了 ...

  6. 景联文科技提供智能手表健康监测数据采集服务,涵盖血压血氧心率睡眠数据

    智能手表的三大主要应用场景:运动辅助.健康检测.通知通话,可穿戴的手环手表由于戴在手腕上,24小时不间断地产生人体健康数据,在检测脉搏.心率.血氧和睡眠等健康指标方面具有天然优势,近些年来以华为为代表 ...

  7. 基于STM32F030、MAX30102血氧心率监测仪的设计(二)

    上篇主要讲解了MAX30102寄存器相关知识,这篇主要看下程序配置. MAX30102寄存器配置 在一般的配置中我们让设备开机直接开始进入SpO2/HR 模式(PROX_INT_EN 置 0),设置两 ...

  8. 基于STM32F030、MAX30102血氧心率监测仪的设计(一)

    搞这个设计用时大约一周,中途遇到好多问题,查找资料乱七八糟,始终没有解决问题,只能自己慢慢的啃资料,本文章主要记录设计过程及记录遇到的问题,做个记录同时帮助有需要的朋友. 目前该设计已成功读取计算出血 ...

  9. 基于STM32F030、MAX30102血氧心率监测仪的设计(四)

    这篇主要分享代码,不做过多介绍! #include "myiic.h"#define CPU_FREQUENCY_MHZ 48 // STM32时钟主频void iic_delay ...

最新文章

  1. 如何使用标准稳压器输出几百毫伏极低直流电压?
  2. SFB 项目经验-81-在企业内部外部限制访问ECP
  3. Hillstone SA-5020 与Juniper SSG 520 的×××互联
  4. 处理字符数据--运算符和函数
  5. Sicily 1817 校歌手大奖赛
  6. 数据库-优化-索引-索引的优化注意事项
  7. 对于大型公司项目平台选择j2ee的几层认识
  8. rails i18n模型_Rails国际化的完整指南(i18n)
  9. 【算法系列之七】合并两个有序链表
  10. python变量类型是动态的_【Python】python动态类型
  11. 从零入门 Serverless | 使用 Spot 低成本运行 Job 任务
  12. 未来网络安全重塑,保障安全的会不会只有四五家?
  13. python 操作MongoDB
  14. Python批量下载中国大学MOOC课件
  15. 589页22万字城市智慧应急指挥中心大数据信息化系统整体设计方案
  16. Android N - Data Saver
  17. P4 程序设计语法学习
  18. NAS入门之——My Cloud EX2+未入网的路由器局域网组网
  19. mysql中on用法_详解mysql中的Using与On的用法
  20. 【181221】VC 编写的网址收藏夹程序(Access)源代码

热门文章

  1. 【django】配置URLconf
  2. China Linux Kernel-ppt
  3. [专栏目录]-ARM学习笔记目录
  4. 进程间通信——共享内存(CreateFileMapping+MapViewOfFile)
  5. 通过ngrok在内网捕获meterpreter反弹
  6. [NPUCTF2020]芜湖(Base64隐写)
  7. 【安全漏洞】ThinkPHP 3.2.3 漏洞复现
  8. android开发关于和使用本机内存,内置存储卡和外置存储卡大揭秘
  9. MySQL LEFT/RIGHT JOIN:外连接查询
  10. 1003 Emergency (25 分)【难度: 中等 / 知识点: 变种的Dijkstra】