当前位置:   article > 正文

MAX30102脉搏血氧仪和心率传感器(含寄存器介绍)_max30102心率算法详解

max30102心率算法详解

动机

最近在学习使用MAX30102传感器,但网络上的文章大都只是给出示例代码而没有较为详细的介绍,本文章结合官方文档和网上资料,记录并分享我对该传感器的认识。文章末尾给出基于Arduino的简单的MAX30102库,注释较为详细。该代码在ESP8266上可运行,但只实现了简单的数据访问。

MAX30102简介

MAX30102脉搏血氧仪和心率传感器包含两个LED,分别发射红光(RED)和红外光(IR),光线照射进人体组织后一部分被吸收,另一部分反射光被集成的光电传感器捕获、转变为电信号。两种光的电信号都会呈现出具有直流(DC)成分的交流(AC)信号,AC成分的频率就是脉搏频率,使用任何一个电信号就能获得心跳频率。

血氧浓度(SpO2)的计算需要同时使用两个电信号,估算SpO2,以下线性近似公式来自MAX3010X用户手册
R = AC red / DC red AC ir / DC ir SpO 2 = ( 104 − 17 R ) × 100 %

R=ACred/DCredACir/DCirSpO2=(10417R)×100%
RSpO2=ACir/DCirACred/DCred=(10417R)×100%
两个电信号的DC和AC成分

使用方法

该传感器使用IIC总线与主机通信,通过读写传感器上的寄存器控制它的运转。在Arduino中,读寄存器大致需要以下步骤:

Wire.beginTransmission(ADDRESS_OF_MAX30102);	//select slave
Wire.write(ADDRESS_OF_REGISTER);	//send the register's address
Wire.endTransmission();

Wire.requestFrom(ADDRESS_OF_MAX30102, sizeof(required_data));	// ask for reading
if (Wire.available()) {
	int val = Wire.read();	//read 1 byte from max30102
	// ... continue to read if required_data is more than 1 byte.
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

写寄存器与其类似:

Wire.beginTransmission(ADDRESS_OF_MAX30102);
Wire.write(ADDRESS_OF_REGISTER);
Wire.write(one_byte_of_data);	//write1 byte to max30102
Wire.endTransmission();
  • 1
  • 2
  • 3
  • 4

寄存器介绍

以下主要介绍我在编程中使用到的寄存器和寄存器位,更详细的内容可以查看MAX30102数据手册

0x00-0x01 中断状态(1)、(2)

MAX30102传感器具有一个中断引脚,当传感器发生某些事件后,该引脚会从高电平跳变为低电平,触发主机的中断事件。该中断引脚只有一根,所以主机需要读取中断状态寄存器来判断引起中断的事件。

REGISTERB7B6B5B4B3B2B1B0
Interrupt Status 1A_FULLPPG_RDYALC_OVF\\\\PWR_RDY
Interrupt Status 2\\\\\\DIE_TEMP_RDY\

其中某一比特为1则表示该事件发生。

  • A_FULL:传感器片上的FIFO缓存将要满,“将满”的标准可以在其它寄存器内设置。
  • PPG_RDY:一个采样完成,主机可以读取一个FIFO中的样本。
  • PWR_RDY:芯片上电完成。
  • DIE_TEMP_RDY:MAX30102带有一个温度传感器,DIE_TEMP_RDY表示温度转换完成,主机可以访问寄存器获取温度数值。

0x02-0x03 中断使能(1)、(2)

REGISTERB7B6B5B4B3B2B1B0
Interrupt Enable 1A_FULL_ENPPG_RDY_ENALC_OVF_EN\\\\\
Interrupt Enable 2\\\\\\DIE_TEMP_RDY_EN\

即可读也可写,对应0x00和0x01的中断比特,置1表示可以由该事件引起中断。

0x04-0x07 FIFO

REGISTERB7B6B5B4B3B2B1B0
FIFO Write Pointer\\\FIFO_WR_PTR[4][3][2][1][0]
Over Flow Counter\\\OVF_COUNTER[4][3][2][1][0]
FIFO Read Pointer\\\FIFO_RD_PTR[4][3][2][1][0]
FIFO Data RegisterFIFO_DATA[7][6][5][4][3][2][1][0]
  • FIFO_WR_PTR:MAX30102的FIFO可以容纳32个样本,FIFO_WR_PTR指向下一个样本要写入的位置。
  • FIFO_RD_PTR:指向下一个要读取的位置。
  • OVF_COUNTER:主机可以设置让传感器丢弃旧数据以容纳新数据,OVF_COUNTER记录了有多少个旧数据被覆盖(丢弃)。
  • FIFO_DATA:主机通过该寄存器读取采样结果。在血氧模式下,主机申请读取该寄存器后,从机会返回6字节数据,前3字节是红光信号的比特17到比特16(前6比特是无效数据)、比特15到比特8以及比特7到比特0;后3字节则是红外光信号,比特排列方式与红光相同。

一般在初始化时将FIFO_WR_PTR、FIFO_RD_PTR和OVF_COUNTER设置为0。

0x08 FIFO配置

REGISTERB7B6B5B4B3B2B1B0
FIFO ConfigurationSMP_AVE[2][1][0]FIFO_ROLLOVER_ENFIFO_A_FULL[3][2][1][0]
  • SMP_AVE:这3比特控制传感器如何处理采样结果,当设置为000,传感器不做处理直接压进FIFO、触发PPG_RDY中断;当设置为101,传感器每收集32个样本做平均后才会将结果压入FIFO,触发中断。当SMP_AVE在000到101之间变化时,每增加1,参与平均的样本数翻倍。超过101后仍是32。
  • FIFO_ROLLOVER_EN:控制传感器在FIFO满时,能否用新数据覆盖旧数据。
  • FIFO_A_FULL:设置FIFO里剩余多少个空位就算将要满,触发A_FULL中断。该值从0x0到0xF间变化,如设置为0x3则表示剩余3个空位就是将要满了。

0x09 模式配置

REGISTERB7B6B5B4B3B2B1B0
Mode ConfigurationSHDNRESET\\\MODE[2][1][0]
  • SHDN:进入省电模式,在该模式下寄存器内容不会丢失,并且还能执行读写操作。
  • RESET:将所有寄存器的内容恢复到默认值。
  • MODE:设置传感器当前运行在哪个模式,能获取哪些样本值。
    • 010:心率模式
    • 011:血氧模式
    • 111:多LED模式

0x0A SpO2配置

REGISTERB7B6B5B4B3B2B1B0
SpO2 Configuration\SPO2_ADC_RGE[1][0]SPO2_SR[2][1][0]LED_PW[1][0]
  • SPO2_ADC_RGE:设置ADC的最大量程,影响最低有效位对应的电压值。当设置为00,最大量程是2048nA,每增加1则量程翻倍。
  • SPO2_SR:SpO2模式下的每秒采样数,该参数并不能随意设置,真实的采样速率还会受到LED_PW影响。最小的000对应50Hz,最大的111对应3200Hz。
  • LED_PW:控制红光和红外光的脉冲宽度,进而影响ADC的分辨率,设置为00时分辨率是15比特,设置为11时能达到18比特,但脉冲越宽采样频率就越会受限。

实际的采样速率由SPO2_SR和LED_PW共同决定,在心率模式和血氧模式下不同的搭配方法会出现不同的采样速率,具体可见MAX30102数据手册的Table 11. SpO2 Mode (Allowed Settings)及Table 12. HR Mode (Allowed Settings)。

0x0C-0x0D LED脉冲波幅

REGISTERB7B6B5B4B3B2B1B0
LED Pulse Amplitude 1LED1_PA[7][6][5][4][3][2][1][0]
LED Pulse Amplitude 2LED2_PA[7][6][5][4][3][2][1][0]

这两个寄存器控制两个LED的典型电流大小,影响亮度。在MAX30102上,LED1是红光LED、LED2是红外光LED。LED_PA在0x00到0xFF之间变化,值越大所需的电流就越大。

0x11-0x12 多LED模式配置

由于我所需的功能在SpO2模式下就能完成,所以并没有详细了解多LED模式。

0x1F-0x21 芯片温度

REGISTERB7B6B5B4B3B2B1B0
Die Temp IntegerTINT[7][6][5][4][3][2][1][0]
Die Temp Fraction\\\\TFRAC[3][2][1][0]
Die Temperature Config\\\\\\\TEMP_EN
  • TEMP_EN:当主机将该比特设置为1后芯片开始采集一次温度、转换,完成后从机自动将该位复位,触发DIE_TEMP_RDY,主机便可读取0x1F和0x20寄存器获得温度值。
  • TINT:8位有符号数,表示摄氏温度的整数部分。
  • TFRAC:4位无符号数,对应设施温度的小数部分,最低有效位对应0.0625摄氏度。

加入TINT=0x25=3710、TFRAC=0x8=810,则实际温度是 37 + 8 × 0.0625 = 37. 5 ∘ C 37+8\times 0.0625=37.5^{\circ}\text{C} 37+8×0.0625=37.5C

0xFE-0xFF PART ID

REGISTERB7B6B5B4B3B2B1B0
Revision IDREV_ID[7][6][5][4][3][2][1][0]
Part IDPART_ID[7][6][5][4][3][2][1][0]
  • REV_ID:版本号ID,不同渠道获得的传感器可能有不同的值。
  • PART_ID:部件ID,固定为0x15,可以在通过读取该寄存器判断从机是否可能为MAX30102。

Arduino代码

MAX30102脉搏血氧仪和心率传感器库(Arduino)

参考资料

  1. MAX30102: High-Sensitivity Pulse Oximeter and Heart-Rate Sensor for Wearable Health Data Sheet (Rev.1)
  2. UG-6409: MAX3010x EV Kits: Recommended Configurations and Operating Profiles
  3. 全网第一个max30102的详细讲解!!返校后的第一个视频!!感叹号
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/445204
推荐阅读
相关标签
  

闽ICP备14008679号