Hello
I would like to calculate BPM and SPO2 using MAX30105.
I succeeded in outputting each using the library example of the sensor. And now I’am going to merge the two examples. In this code, SPO2 is output, but there seems to be a problem measuring the beat for BPM.
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"
#include "spo2_algorithm.h"
MAX30105 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100]; //red LED sensor data
int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2;
int32_t heartRate; //heart rate value
int8_t validHeartRate;
void setup() {
Serial.begin(115200);
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
byte ledBrightness = 60; //Options: 0=Off to 255=50mA
byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 400; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
// particleSensor.setup(); //Configure sensor with default settings
// particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
// particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}
void loop() {
bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps
//read the first 100 samples, and determine the signal range
for (byte i = 0 ; i < bufferLength ; i++)
{
while (particleSensor.available() == false) //do we have new data?
{
particleSensor.check(); //Check the sensor for new data
}
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so move to next sample
}
//calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
//Continuously taking samples from MAX30102. Heart rate and SpO2 are calculated every 1 second
while (1)
{
long irValue = particleSensor.getIR();
//BPM
if (checkForBeat(irValue) == true) //beat measured (Failed to measure beat value!)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0); //BPM
if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++) //RATE_SIZE = 4
{
beatAvg += rates[x];
}
beatAvg /= RATE_SIZE;
}
Serial.print("BPM = ");
Serial.print(beatsPerMinute);
Serial.print("\t");
Serial.print("Avg BPM = ");
Serial.println(beatAvg);
}
//==========================================================================
//dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
for (byte i = 25; i < 100; i++)
{
redBuffer[i - 25] = redBuffer[i];
irBuffer[i - 25] = irBuffer[i];
}
//take 25 sets of samples before calculating the heart rate.
for (byte i = 75; i < 100; i++)
{
while (particleSensor.available() == false) //do we have new data?
{
particleSensor.check(); //Check the sensor for new data
}
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so move to next sample
if (irValue > 100000) //touch finger
{
if (validHeartRate == 1) //update new value?
{
Serial.print(F("HR = "));
Serial.println(heartRate, DEC);
//Serial.print(F(", HRvalid = "));
//Serial.println(validHeartRate, DEC);
}
if (validSPO2 == 1)
{
Serial.print(F("SPO2 = "));
Serial.println(spo2, DEC);
//Serial.print(F(", SPO2Valid = "));
//Serial.println(validSPO2, DEC);
Serial.println("");
}
}
else
{
//Serial.println("No finger");
}
}
//After gathering 25 new samples recalculate HR and SP02
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
}
}
if (checkForBeat(irValue) == true)
Calculates the BPM when a beat value is received through this code. But it doesn’t detect any beat values, so the code for the BPM is ignored.
Can I get some help with this problem?
Thank you.