I want to output the BPM and SPO2 value of the MAX30105 sensor

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.

If you have combined 2 different code samples into one, can you supply links to the two examples.
It looks like you have while() statements which could block the other part that you have merged in.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.