ESP32驱动MAX30102脉搏血氧心率传感器
- MAX30102脉搏血氧心率传感器
- MAX30102模块引脚定义
- MAX30102模块与ESP32开发板引脚接线
- MAX30102 Arduino驱动程序
- 获取心率数据
- 获取血氧饱和度数值
- 获取指尖温度
MAX30102脉搏血氧心率传感器
MAX30102一种光学传感器,能够以无创方式检测血氧饱和度(SpO2)和心率。此外,它还配备有温度传感器,用于进行温度补偿和校准。MAX30102包含一个红色LED、一个红外LED以及一个光检测器。这些LED会向皮肤发出光线,而光检测器则负责检测反射回来的光线。随着心脏的跳动,血液流动状况的变化会导致反射光强度的改变。含氧血红蛋白会吸收更多的红外线;脱氧血红蛋白会吸收更多的红光。根据红色和红外线波长下反射光强度的比值,传感器便可计算出血氧饱和度SpO2值。而每次心跳时血液容量的变化则有助于我们测定心率。
MAX30102模块引脚定义
VIN:供电3.3/5V
GND:供电负极
SCL:IIC通信时钟信号
SDA:IIC通信数据信号
INT:中断输出
MAX30102模块与ESP32开发板引脚接线
| MAX30102 | ESP32开发板 |
|---|---|
| GND | GND |
| VIN | 5V |
| SDA | 21 |
| SCL | 22 |
MAX30102 Arduino驱动程序
打开Arduino IDE库管理器安装SparkFun MAX3010x驱动库
获取心率数据
#include<Wire.h>#include"MAX30105.h"#include"heartRate.h"MAX30105sensor;// SettingsconstbyteRATE_SIZE=5;// How many beats we averagebyte rates[RATE_SIZE];// Store last few valid BPM valuesbyte rateSpot=0;byte validBeats=0;long lastBeat=0;float currentBPM=0;int averageBPM=0;unsigned long lastPrint=0;// Only accept realistic heart rates (adjust for your case)constfloatMIN_BPM=45;constfloatMAX_BPM=180;voidsetup(){Serial.begin(115200);Serial.println("MAX30102 Heart Rate Sensor");Serial.println();Serial.println("Place your finger on the sensor...");Serial.println();// Initialize the sensorif(!sensor.begin(Wire,I2C_SPEED_FAST)){Serial.println("Error initializing the sensor...");while(1);}sensor.setup();// Use default settingssensor.setPulseAmplitudeRed(0);// Turn off red LED}voidloop(){long irValue=sensor.getIR();// Read infrared value// Check if a heartbeat was detectedif(checkForBeat(irValue)){long timeBetweenBeats=millis()-lastBeat;lastBeat=millis();currentBPM=60.0/(timeBetweenBeats/1000.0);// Only keep realistic valuesif(currentBPM>=MIN_BPM&¤tBPM<=MAX_BPM){rates[rateSpot]=(byte)currentBPM;rateSpot++;if(rateSpot>=RATE_SIZE){rateSpot=0;}// Count valid beats (until buffer is full)if(validBeats<RATE_SIZE){validBeats++;}// Only calculate average when buffer is fullif(validBeats>=RATE_SIZE){// Calculate the averageaverageBPM=0;for(byte i=0;i<RATE_SIZE;i++){averageBPM+=rates[i];}averageBPM/=RATE_SIZE;}}}// Print once every secondif(millis()-lastPrint>=1000){lastPrint=millis();if(irValue<50000){// No finger on the sensorSerial.println("Waiting for finger...");}elseif(averageBPM==0){// Finger is present but not enough valid beats yetSerial.println("Measuring... keep your finger still");}else{// We have a valid averageSerial.print("Heart Rate: ");Serial.print(averageBPM);Serial.println(" BPM");}}}上传程序到开发板,打开串口监视器,把手指按压到传感器表面上,稍等片刻即可输出心率数据
人静坐时的心率通常属于静息心率范畴,一般成年人在 50~100 次/分钟 之间都算正常。
获取血氧饱和度数值
#include<Wire.h>#include"MAX30105.h"#include"spo2_algorithm.h"MAX30105 sensor;// Buffers needed by the algorithm#defineBUFFER_SIZE100uint32_tirBuffer[BUFFER_SIZE];uint32_tredBuffer[BUFFER_SIZE];int32_tspo2;// Oxygen saturation valueint8_tvalidSPO2;// 1 = valid reading, 0 = not valid yetint32_theartRate;// Not used, but required by the functionint8_tvalidHeartRate;voidsetup(){Serial.begin(115200);Serial.println("MAX30102 Oxygen Saturation");Serial.println();Serial.println("Place your finger on the sensor...");Serial.println();// Initialize the sensorif(!sensor.begin(Wire,I2C_SPEED_FAST)){Serial.println("Error initializing the sensor...");while(1);}byte ledBrightness=60;// 0=Off to 255=50mAbyte sampleAverage=4;// 1, 2, 4, 8, 16, 32byte ledMode=2;// 1 = Red only, 2 = Red + IR, 3 = Red + IR + Greenbyte sampleRate=100;// 50, 100, 200, 400, 800, 1000, 1600, 3200intpulseWidth=411;// 69, 118, 215, 411intadcRange=4096;// 2048, 4096, 8192, 16384// Configure sensor with these settingssensor.setup(ledBrightness,sampleAverage,ledMode,sampleRate,pulseWidth,adcRange);}voidloop(){// Collect 100 samples (takes a few seconds)for(byte i=0;i<BUFFER_SIZE;i++){while(sensor.available()==false){sensor.check();}redBuffer[i]=sensor.getRed();irBuffer[i]=sensor.getIR();sensor.nextSample();}// Calculate SpO2maxim_heart_rate_and_oxygen_saturation(irBuffer,BUFFER_SIZE,redBuffer,&spo2,&validSPO2,&heartRate,&validHeartRate);// Display oxygen saturationif(validSPO2){Serial.print("Oxygen Saturation: ");Serial.print(spo2);Serial.println(" %");}else{Serial.println("Measuring... keep your finger still");}Serial.println();}上传程序到开发板,打开串口监视器,把手指按压到传感器表面上,稍等片刻即可输出血氧饱和度数值
静坐或安静状态下:
98%~100%:很常见,很好;
95%~97%:一般也算正;
93%~94%:偏低,建议复测,看是否手指冷、末梢循环差、指甲油、仪器误差等;
≤92%:尤其如果持续这样,建议就医;
≤90%:属于低氧血症范围,比较危险,尤其伴呼吸困难、胸闷、意识模糊时,应尽快就医。
获取指尖温度
MAX30102传感器还配备了一个温度传感器,该传感器可用于校准心率及血氧饱和度数值。还可以利用这个传感器来获取体温值(此处指指尖温度)。以下代码展示了如何使用ESP32从MAX30102传感器中获取体温值。
#include<Wire.h>#include"MAX30105.h"MAX30105 sensor;voidsetup(){Serial.begin(115200);Serial.println("MAX30102 Temperature Sensor");Serial.println();// Initialize the sensorif(!sensor.begin(Wire,I2C_SPEED_FAST)){Serial.println("Error initializing the sensor...");while(1);}// Turn off the LEDs so they don't heat the sensorsensor.setup(0);// 0 = LEDs offsensor.enableDIETEMPRDY();// Enable temperature ready signal}voidloop(){// Read temperature in CelsiusfloattempC=sensor.readTemperature();// Convert to FahrenheitfloattempF=tempC*1.8+32.0;// Print the temperature readingsSerial.print("Temperature: ");Serial.print(tempC,2);Serial.print(" °C | ");Serial.print(tempF,2);Serial.println(" °F");delay(1000);}上传程序到开发板,打开串口监视器,把手指按压到传感器表面上,即可输出温度值