SparkFun Pulse Oximeter and Heart Rate Monitor Hookup Guide

Contributors: Elias The Sparkiest
Favorited Favorite 7

Example 4: Adjust LED Values

The fourth example will show you how to adjust the accuracy of the SparkFun Pulse Oximeter and Heart Rate Monitor. We'll do this by adjusting the length of time that the LEDs inside the MAX30101 pulse, which will also impact how many samples we can get at a time. So we'll talk about these two settings and how they play against each other. Open the example up by heading to File > Examples > SparkFun Bio Sensor Hub Library > Example4_config_LEDs_BPM.ino .

Starting at the top, we assign the reset and mfio pins to pin 4 and 5 respectively. Below that we have two variables that will store the pulse width and the sample rate: width and samples. A longer pulse width changes the amount of time that the sensor's LEDs shine into the finger before ascertaining how much light was absorbed. This results in higher resolution data as the finger is fully illuminated before collecting data. However, the trade off is the sensor has less time to collect samples. For each increasing pulse width setting, there is a decrease in the amount of samples that can be collected. Check the table above under Pulse Width vs Sample Collection above to see all possible interactions.

const int resPin = 4;
const int mfioPin = 5;

// Possible widths: 69, 118, 215, 411us
int width = 411; 
// Possible samples: 50, 100, 200, 400, 800, 1000, 1600, 3200 samples/second
// Not every sample amount is possible with every width; check out our hookup
// guide for more information.
int samples = 400; 
int pulseWidthVal;
int sampleVal;

// Takes address, reset pin, and MFIO pin.
SparkFun_Bio_Sensor_Hub bioHub(resPin, mfioPin); 

bioData body; 

I'll reiterate what's stated in the first example. Just above you'll see this funky type called bioData. This is a type that is unique to the SparkFun Pulse Oximeter and Heart Rate Monitor and it holds all the Biometric data of the sensor: Heart rate, confidence, blood oxygen levels, finger detection, led data, etc. There is a table above under Reference Tables and Sensor Settings that displays the information available in bioData.

Unlike our first example, in this one we're we are calling bioHub.configSensorBpm(MODE_ONE) which tells the MAX32664 to give us both LED data as well as biometric data and to load it up into bioData. We'll see this come into play later on in the loop below.

int error = bioHub.configSensorBpm(MODE_ONE); // Configure Sensor and BPM mode 
    Serial.println("Sensor configured.");
else {
    Serial.println("Error configuring sensor.");
    Serial.print("Error: "); 

To set the pulse width, there is a call to bioHub.setPulseWidth(width), giving it the variable width that we defined above that holds the value 411┬ÁS. We then set the sample rate with bioHub.setSampleRate(samples), again using the variable defined above. If you were to set a sample rate above what is capable at a particular pulse width, the sensor will automatically set it to the highest possible setting at that rate automatically. After configuring both settings, both values are read back with calls to bioHub.readPulseWidth() and bioHub.readSampleRate().

error = bioHub.setPulseWidth(width);
if (!error){
    Serial.println("Pulse Width Set.");
else {
    Serial.println("Could not set Pulse Width.");
    Serial.print("Error: "); 

// Check that the pulse width was set. 
pulseWidthVal = bioHub.readPulseWidth();
Serial.print("Pulse Width: ");

// Set sample rate per second. Remember that not every sample rate is
// available with every pulse width. Check hookup guide for more information.  
error = bioHub.setSampleRate(samples);
if (!error){
    Serial.println("Sample Rate Set.");
else {
    Serial.println("Could not set Sample Rate!");
    Serial.print("Error: "); 

// Check sample rate.
sampleVal = bioHub.readSampleRate();
Serial.print("Sample rate is set to: ");

// Some time to read your settings.

Here in the loop, we have a bit more information being printed out to the serial monitor than in the first example. Specifically there are the body.irLed and body.redLed data points which give us the number of light samples collected by the sensor for the respective LEDs.

void loop(){

    // Information from the readSensor function will be saved to our "body"
    // variable.  
    body = bioHub.readSensorBpm();
    Serial.print("Infrared LED counts: ");
    Serial.print("Red LED counts: ");
    Serial.print("Heartrate: ");
    Serial.print("Confidence: ");
    Serial.print("Blood Oxygen: ");
    Serial.print("Status: ");
    delay(500); // Slowing it down, we don't need to break our necks here.