spo2数据集_Arduino 血氧心率模块传感器数据采集
開發環境:
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 血氧心率模块传感器数据采集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 饼图大小调整_Excel做的双层饼图,太
- 下一篇: .net webservice stud