MAX30102 Pulse Oximeter with an Arduino Uno

A pulse oximeter and heart-rate sensor: red and infrared LEDs, a photodetector and an 18-bit ADC behind one window, read over I2C.

MAX30102 Pulse Oximeter, A pulse oximeter and heart-rate sensor: red and infrared LEDs, a photodetector and an 18-bit ADC behind one window, read over I2C.
In short

On an Arduino Uno the MAX30102 module takes the 5V pin on VIN, its regulators feed the chip's 1.8 V logic and LEDs, and it sits on the Uno's I2C pins, A4 and A5, at 400 kHz. Reading the raw counts and a heart rate fits the Uno; SpO2 is where the 2 KB of SRAM starts to show.

Wiring the MAX30102 Pulse Oximeter to the Arduino Uno

Pin by pin.

MAX30102 Pulse OximeterArduino Uno
VIN5V
GNDGND
SDASDA
SCLSCL

What to know on the Arduino Uno

  • The bare chip needs 1.7 V to 2.0 V for its logic and 3.1 V to 5.0 V for its LEDs, so only a module with regulators belongs on the Uno's 5V.Maxim MAX30102 datasheet 19-7740 Rev 1, p. 2
  • sensor.begin(Wire, I2C_SPEED_FAST) runs the bus at 400 kHz, the chip's maximum and also the fastest the Uno's two-wire interface supports.Maxim MAX30102 datasheet 19-7740 Rev 1, p. 5; Microchip ATmega328P datasheet DS40002061B, TWI section
  • SparkFun's SpO2 example stores 100 red and 100 IR samples; on the Uno it keeps them as 16-bit values, dropping the high bits of the 18-bit readings, because 32-bit buffers do not fit in the Uno's SRAM. Heart rate alone, as in this sketch, needs no such buffer.SparkFun MAX3010x library, Example8_SPO2; Maxim MAX30102 datasheet 19-7740 Rev 1, p. 3
  • The loop prints a line for every sample. At 115200 baud that printing takes a noticeable share of the Uno's time between samples, so print less often if beats are missed.Arduino UNO R3 tech specs
  • The board pulls SDA and SCL up to its 3.3 V rail (or 1.8 V, set by its jumper), while the Uno's TWI pins want 0.7 × VCC, 3.5 V, for a high. At 3.3 V it usually works because Wire.begin() adds the Uno's internal pull-ups to 5 V; at 1.8 V it does not, so set the jumper to 3.3 V or use a level shifter.Microchip ATmega328P datasheet DS40002061B, two-wire interface characteristics

MAX30102 Pulse Oximeter code for the Arduino Uno

Compiled for arduino:avr:uno on 2026-10-30.

Libraries: sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library
// MAX30102 Pulse Oximeter on Arduino Uno: wiring and a free simulation at https://www.tinkered.ai/components/max30102/arduino-uno
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"

MAX30105 sensor;
const byte RATE_SIZE = 4;
byte rates[RATE_SIZE];
byte rateSpot = 0;
long lastBeat = 0;
float beatsPerMinute = 0;
int beatAvg = 0;

void setup() {
  Serial.begin(115200);
  if (!sensor.begin(Wire, I2C_SPEED_FAST)) {
    Serial.println("MAX30102 not found");
    while (1) delay(10);
  }
  sensor.setup();                     // 6.4 mA LEDs, 4 averaged at 400 sps, 411 us, 4096 nA
  sensor.setPulseAmplitudeRed(0x0A);  // red dimmed: heart rate uses the IR channel
  sensor.setPulseAmplitudeGreen(0);
}

void loop() {
  long ir = sensor.getIR();
  if (checkForBeat(ir)) {
    long delta = millis() - lastBeat;
    lastBeat = millis();
    beatsPerMinute = 60 / (delta / 1000.0);
    if (beatsPerMinute < 255 && beatsPerMinute > 20) {
      rates[rateSpot++] = (byte)beatsPerMinute;
      rateSpot %= RATE_SIZE;
      beatAvg = 0;
      for (byte x = 0; x < RATE_SIZE; x++) beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
  }
  Serial.print("IR=");
  Serial.print(ir);
  Serial.print(" BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(" Avg=");
  Serial.print(beatAvg);
  if (ir < 50000) Serial.print(" (no finger)");
  Serial.println();
}

MAX30102 Pulse Oximeter on the Arduino Uno: questions

Can I connect a MAX30102 module to the Arduino Uno's 5V?

Yes on a module with regulators: VIN to 5V, GND to GND, SDA to A4 and SCL to A5. The bare chip runs its logic from 1.8 V (Maxim datasheet, p. 2), so never wire it to 5 V directly.

Can an Arduino Uno calculate SpO2 with the MAX30102?

Yes with SparkFun's example, but the Uno lacks SRAM for full 32-bit sample buffers, so it truncates the samples to 16 bits. A board with more memory gives the algorithm the full 18-bit data.

What address does the MAX30102 use on the Uno?

0x57 (Maxim datasheet, p. 5). A DS3231 module's EEPROM also answers at 0x57, so do not share the Uno's bus with one.

Keep going

For AI assistants

This guide as plain Markdown. /components/max30102/arduino-uno.md

What will you build with it?