top of page

Heart Rate 
Monitor

This project uses the MAX30100 sensor with an Arduino Uno to measure both heart rate (in BPM) and blood oxygen saturation levels (SpOâ‚‚). The results are displayed in real time on the Serial Monitor. The MAX30100 integrates two LEDs, a photodetector, and signal processing to provide accurate physiological readings in a compact sensor.

​

How It Works

The MAX30100 uses two light sources—one infrared and one red LED—to illuminate the skin and detect the reflected light using a photodiode. The amount of light absorbed changes with the pulse (blood volume) and the oxygen level in the blood. The sensor captures these signals and transmits raw data to the Arduino via I²C. The Arduino, using a library, processes this data to calculate both BPM (heart rate) and SpOâ‚‚ (oxygen saturation percentage), which is then displayed on the Serial Monitor.

Materials Anchor

Materials

To build a colour heart rate monitor project with an Arduino Uno, you'll need the following materials:

Components:
​​

​

1) Arduino Uno

  • The main microcontroller that reads the sensor data and processes heart rate calculations.

​

2) MAX30100 Sensor Module

  • An integrated optical sensor that measures both heart rate and blood oxygen saturation (SpOâ‚‚) using light absorption.

​

3) 4 x Jumper Wires (Male-to-Female or Male-to-Male)

  • Used to connect the pulse sensor’s VCC, GND, and Signal pins to the Arduino Uno.

​

4) USB Cable (Type B)

  • Connects the Arduino Uno to your computer for uploading code and viewing output in the Serial Monitor.

Setup Anchor

Basic Setup

Breadboard GREY.png
Schematic GREY.png

1) MAX30100 Sensor

  • VIN → 3.3V 

  • GND → GND

  • SDA → Pin A4 (via 220Ω resistor)

  • SCL → Pin A5 (via 220Ω resistor)​

  • INT → Leave disconnected

  • IRD → Leave disconnected

  • RD → Leave disconnected

    • You do not need to connect RD or IRD manually.
      The MAX30100 handles LED control internally via its firmware and I²C communication.

    • These pins may be exposed for testing, diagnostics, or manual override, but are not typically used in regular Arduino projects.

​

  • INT = Interrupt

    • This pin outputs a LOW pulse when new data (heart rate or SpOâ‚‚) is available.

    • You can connect it to an Arduino digital pin and use attachInterrupt() for more efficient data handling.

    • Not required for basic operation — polling with .update() in the loop works fine.

​​

After wiring, connect the Arduino to your computer via USB, upload the code, and open the Serial Monitor (set to 115200 baud) to view BPM and SpOâ‚‚ data.

​

​Software Setup

​​

1) Wire.h library

  • This library is native to the Arduino IDE and doesn't need downloading.

  • ​

1) MAX30100_PulseOximeter library

  • In Arduino IDE → Sketch → Include Library → Manage Libraries → Search for “MAX30100_PulseOximeter by oxullo” → Install​

Code
Code PIC.png

CODE BREAK-DOWN

Code Break Down

#include <Wire.h>

  • Includes the Wire library needed for I²C communication between the Arduino and the MAX30100 sensor.

​​

#include "MAX30100_PulseOximeter.h"

  • Includes the PulseOximeter library, which simplifies working with the MAX30100 sensor.

​

#define REPORTING_PERIOD_MS 1000

  • Defines a time interval of 1000 milliseconds (1 second) for how often the heart rate and SpOâ‚‚ will be printed to the Serial Monitor.

​

PulseOximeter pox;

  • Creates an instance of the PulseOximeter class named 'pox'. This object will handle the sensor's data processing and reading.

​

uint32_t lastReportTime = 0;

  • Creates a variable to store the last time heart rate and oxygen data were printed. It's used to space out the updates.

​

void onBeatDetected()

  • Defines a function that will be called automatically every time the sensor detects a heartbeat.

​

Serial.println("Beat!");

  • Prints “Beat!” to the Serial Monitor every time a heartbeat is detected, for user feedback.

​

void setup()

  • Starts the Arduino’s setup section. This part runs once when the board is powered on or reset.

​

Serial.begin(115200);

  • Starts serial communication with the computer at a baud rate of 115200 bits per second.

​

Serial.println("Initializing MAX30100...");

  • Displays a message in the Serial Monitor to show that sensor setup is starting.

​

if (!pox.begin())

  • Attempts to initialise communication with the MAX30100 sensor. If it fails…

​

Serial.println("FAILED to initialize MAX30100");

  • Displays an error message if the sensor is not detected or communication fails.

​

while (1);

  • Freezes the program if the sensor fails to initialise, so the user knows there’s an issue.

​

else { Serial.println("MAX30100 ready.");

  • If the sensor is successfully detected, prints a confirmation message to the Serial Monitor.

​

pox.setOnBeatDetectedCallback(onBeatDetected);

  • Tells the sensor to run the 'onBeatDetected' function each time it sees a heartbeat.

​

void loop()

  • Begins the main part of the program that runs continuously.

​

pox.update();

  • Updates the sensor readings and processes the raw data from the MAX30100.

​

if (millis() - lastReportTime > REPORTING_PERIOD_MS)

  • Checks whether 1 second has passed since the last print. If so, it continues to the next block.

​

Serial.print("BPM: ");

  • Prints the label “BPM: ” to the Serial Monitor.

​

Serial.print(pox.getHeartRate());

  • Prints the current calculated heart rate in beats per minute.

​

Serial.print(" | SpO2: ");

  • Prints the label “SpO2: ” to the Serial Monitor, following the BPM.

​

Serial.println(pox.getSpO2());

  • Prints the current blood oxygen saturation percentage to the Serial Monitor and starts a new line.

​

lastReportTime = millis();

  • Updates the last report time to the current time, so the next reading happens 1 second later.

bottom of page