> Source: https://www.tinkered.ai/components/max30102/arduino-uno (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/max30102/arduino-uno. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# MAX30102 Pulse Oximeter with an Arduino Uno

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

| MAX30102 Pulse Oximeter | Arduino Uno | Note |
| --- | --- | --- |
| VIN | 5V |  |
| GND | GND |  |
| SDA | SDA |  |
| SCL | SCL |  |

## 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)

## Code

Libraries: sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library

```cpp
// 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();
}
```

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

## 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.

## More

- [MAX30102 Pulse Oximeter reference](https://www.tinkered.ai/components/max30102.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the MAX30102 Pulse Oximeter on the Arduino Uno in the browser, with this wiring and code, free: https://www.tinkered.ai/components/max30102/arduino-uno
