A DIY Heart-Rate Monitor with the MAX30100

The MAX30100 measures heart rate and blood oxygen saturation (SpO2) using photoplethysmography (PPG): a red LED and an infrared LED inside the module pulse light through the thin skin and capillaries of a fingertip, and a photodetector on the same side of the sensor reads how much of each wavelength gets absorbed on the way back. Blood absorbs red and infrared light differently depending on how much oxygen it's carrying, and the volume of blood in the capillaries changes slightly with every heartbeat, so the photodetector's signal rises and falls in a small periodic wave riding on top of a steady baseline. The spacing between those waves gives heart rate in beats per minute, and the ratio of how much the red signal swings versus how much the infrared signal swings — the "ratio of ratios" — gives an estimate of SpO2. It's the same principle used in clip-on hospital pulse oximeters, built into a two-LED, one-photodiode I²C module that costs a fraction of a medical device and is simple enough to wire to an Arduino Uno in an afternoon.

This is a hobby and learning project, not a medical device. The readings a MAX30100 module produces on a breadboard have not been clinically calibrated, validated, or certified for health use. Do not use this build to diagnose a medical condition, to decide whether to seek medical care, or to make any actual health monitoring decision for yourself or anyone else. If you have concerns about your heart rate or blood oxygen levels, use a certified medical pulse oximeter and talk to a healthcare professional.

How does the MAX30100 measure heart rate and blood oxygen?

Output Range Typical accuracy Interface
Heart rate 0–255 bpm ±2 bpm I²C
SpO2 0–100% ±2% I²C

Inside the module, the red and infrared LEDs fire in an alternating pattern controlled by the chip itself, and an internal photodiode and analog front end digitize the returning light into a raw sample stream (0–65535 counts) that firmware pulls off the I²C bus. A driver library — commonly SparkFun's MAX3010x/MAX30105 library, which explicitly supports the MAX30100, MAX30102, and MAX30105 — then runs a peak-detection algorithm on that raw stream to find individual heartbeats and time the gaps between them, and a separate SpO2 algorithm compares the AC and DC components of the red and infrared channels to estimate oxygen saturation. None of this math happens on the sensor chip itself; it all runs on the microcontroller, which is why the Arduino Uno in this build is doing real signal-processing work, not just relaying numbers.

How do you wire the MAX30100 to an Arduino Uno?

Arduino Uno pin MAX30100 pin Signal
3.3V VIN Power
GND GND Ground
A4 SDA I²C data
A5 SCL I²C clock

A4 and A5 double as the Uno's I²C bus (SDA and SCL) alongside their analog-input role, so no extra shield or level shifter is needed to reach the sensor. The one wiring detail that actually matters here: the MAX30100 die runs on 1.8V internally and its logic is 3.3V, and it is not 5V tolerant. Most breakout boards include an onboard regulator that accepts 3.3–5V on the VIN pin, but the bare SDA/SCL lines from the chip are still 3.3V logic, so check the specific breakout's markings before assuming it's safe to drive those lines at 5V, and make sure the I²C bus has pull-up resistors (most breakout modules already include them). Power for the Uno itself is simplest over its USB cable; a full pulse-oximeter build has no motors or high-current peripherals, so USB power is normally enough.

How accurate is a DIY pulse oximeter?

Treat the numbers this build prints to the serial monitor as hobby-grade estimates, not clinical measurements. Three things degrade accuracy in practice: finger placement (the fingertip needs to sit flat over both LEDs and the photodetector with consistent, gentle pressure — too loose and the signal is noisy, too tight and it restricts blood flow), motion artifacts (even small finger movements swamp the tiny PPG signal with much larger noise, which is why hospital-grade oximeters clip firmly onto a fingertip and ask the patient to stay still), and the complete absence of medical calibration or certification on a breakout module and open-source algorithm, versus the multi-point calibration and regulatory testing that goes into an actual clinical pulse oximeter. A well-wired MAX30100 with a still finger and good ambient conditions will generally track relative changes in heart rate and SpO2 reasonably well for a learning project. It should never be trusted as a substitute for a real medical device, especially at the edges of the range or during any actual health concern.

Is this safe to use?

Electrically, yes, when wired correctly: the MAX30100 runs on low voltage and low current, and the LEDs are far below any level that poses a hazard to skin or eyes at the fingertip contact distance this sensor is designed for. The failure modes worth knowing are electrical, not medical: driving the sensor's 3.3V logic lines from the Uno's 5V rail without confirming the breakout's tolerance can damage the chip, and skipping I²C pull-ups can leave the sensor unable to talk to the Arduino at all. Beyond the wiring, the real safety statement is the one already made above — this is a hobby project for learning how PPG sensing and I²C firmware work, not a device to rely on for any actual health decision.

Watch it built live

We typed this into Compoden's storefront assistant, Soldr, exactly as a customer would:

"I want to build a DIY heart rate and pulse oximeter monitor using a MAX30100 sensor with an Arduino Uno"

Compoden storefront AI assistant Soldr responding to a MAX30100 heart rate and pulse oximeter request with an Arduino Uno, showing the parts tray

Soldr matched the sensor slot on the first try, to a module Compoden lists under both chip names: "The MAX30100/30102 Heart Rate & SpO2 Sensor Module is the part that actually measures your heart rate and SpO2. It uses light to detect changes in blood flow, which tells it your pulse and oxygen levels. This sensor communicates using I2C… It operates at 3.3V logic… It is important to note that this sensor is NOT 5V tolerant, meaning if you connect its data pins directly to the 5V logic pins of the Arduino, it could be damaged. It also needs a pull-up resistor…" Worth being precise about that part: Compoden's listing and product description name it as a combined MAX30100/MAX30102 module rather than a MAX30100-exclusive breakout — both chips share the same pinout and I²C interface, and the module is sold as covering either. Soldr also flagged a real mismatch in the tray on its own: "the 5V power adapter outputs 5V, but the Arduino Uno's barrel connector input is designed for 7-12V, meaning this adapter will not directly power the Arduino through that specific input." In practice, the Uno in this build is easiest to power over its USB cable instead of that barrel-jack adapter.

Watch the firmware get generated

We then asked Compoden's code assistant, Soldr's PWA build companion, to write the actual pulse-oximeter firmware:

"I'm building a DIY heart-rate and pulse oximeter monitor with an Arduino Uno and a MAX30100 sensor over I2C. Write the full firmware to read heart rate and SpO2 and print them to the serial monitor."

Soldr PWA firmware editor screenshot showing generated Arduino Uno code for a MAX30100 heart rate and SpO2 sensor using the SparkFun MAX3010x library

Its own summary read: "This sketch reads heart rate and SpO2 from the MAX30100/MAX30102 sensor connected via I2C (SDA to A4, SCL to A5) and prints the values to the serial monitor at 115200 baud. Install via Library Manager: SparkFun MAX3010x Pulse and Proximity Sensor Library." The generated sketch includes #include <Wire.h> and #include <MAX30105.h> — with an inline comment noting the MAX30105 library "also supports MAX30100/MAX30102" — plus a heartRate.h header for beat detection and a spo2_algorithm.h header for the oxygen-saturation math, a MAX30105 particleSensor; object, a small rolling array (RATE_SIZE = 4) for averaging beats-per-minute, and an infrared sample buffer for the SpO2 calculation. The build log flagged one honest caveat mid-generation — "Heads up — this sketch does not compile yet. I tried an automatic fix and a documentation lookup, and it still fails." — before the firmware tab settled on the Arduino UNO (.hex) target shown in the screenshot above. Treat the generated source as a real, editable starting point for this exact wiring, not a guaranteed drop-in compile; the Firmware tab lets you edit and recompile directly against the board you pick from its target list.

Get everything in this build

These are the real parts Soldr put in the tray for the exact prompt above — live prices and direct add-to-cart links, no bundling or assumed extras.

Part Price Add to cart
Arduino Uno R3 CH340G ATmega328P Board Rs.230 Add to cart
MAX30100/30102 Heart Rate & SpO2 Sensor Module Rs.110 Add to cart
23 AWG Multi-Strand Breadboard Wire Rs.10 Add to cart
Male-to-Male Breadboard Jumper Wires (20cm, 24 AWG) Rs.40 Add to cart
5V 2A Power Adapter (Barrel Connector) Rs.170 Add to cart
Total Rs.560 Add all 5 to cart

As noted above, the Uno in this list is normally powered over USB rather than that barrel-jack adapter, since the adapter's 5V output doesn't match the Uno's 7–12V barrel-jack input — keep the adapter for a later build that needs it, or swap it out at checkout.

Built and Backed by Compoden

The parts listed above ship from Compoden's India stock and are checked for compatibility before they're carded together, not sourced individually and hoped to work. Delivery typically takes 3–7 days across India, with Cash on Delivery and UPI both available at checkout. Compoden's support team can help with wiring or firmware issues on this build, including the I²C pull-up and 5V-tolerance points raised above.

FAQ

Is a MAX30100 pulse oximeter accurate enough to trust for health decisions?
No. This is a hobby and educational build. The MAX30100 module used here is not clinically calibrated or certified, and readings can be thrown off by finger placement and motion. Never use it to diagnose a condition or decide on medical care — use a certified medical pulse oximeter and consult a healthcare professional for that.

Does Compoden sell a MAX30100-only module, or is it combined with the MAX30102?
Compoden's listing covers both chips on one module — "MAX30100/30102 Heart Rate & SpO2 Sensor Module" — since the two share the same pinout and I²C interface. It is not a separate MAX30100-exclusive breakout.

Why does the MAX30100 need 3.3V and not 5V?
The sensor's internal logic and LED drive circuitry run at 1.8V and 3.3V and are not 5V tolerant. Feeding its SDA/SCL lines from the Arduino Uno's 5V logic directly, without confirming the breakout module's own tolerance, risks damaging the chip.

What library does the firmware use to read heart rate and SpO2?
The generated sketch uses SparkFun's MAX3010x/MAX30105 Arduino library, which explicitly supports the MAX30100 alongside the MAX30102 and MAX30105, plus separate heart-rate and SpO2 algorithm headers for the actual beat-detection and oxygen-saturation math.

Back to blog