Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arduino Build

MAX30102 Pulse Oximeter (Current Fork)

YouTube Video

This repository contains an Arduino/C++ pulse oximeter implementation for the MAX30102, based on the MAXIM reference code and the RF algorithm work preserved in README_RF.md.

The current code has been refactored to support:

  • interrupt-driven sample acquisition
  • rolling updates using a circular sample buffer
  • a reusable median filter class (median_filter.h)
  • smoothed HR/SpO2 output and OLED display updates

Upstream Context

The original RF-focused project history and notes are kept in README_RF.md.

Primary upstream reference:

What This Fork Changes

Compared with the batch-only flow, this fork updates results continuously while still feeding the algorithms a full chronological window:

  • Samples are read from MAX30102 using the interrupt pin (oxiInt).
  • New samples are written into ring buffers (no shifting of entire arrays).
  • A chronological window is assembled from the ring buffer for each algorithm run.
  • Results are updated every UPDATE_STEP samples instead of waiting for a full refill.
  • HR/SpO2 smoothing uses a fixed-size median filter that stores invalid sentinels and ignores them when calculating the median.

Sketch Layout

  • Main sketch folder: max30102_esp32c3_oled_oximeter/
  • Main entry sketch: max30102_esp32c3_oled_oximeter/max30102_esp32c3_oled_oximeter.ino
  • Supporting code for the sketch is colocated in the same folder:
    • median_filter.h
    • algorithm_by_RF.cpp/.h
    • algorithm.cpp/.h
    • max30102.cpp/.h
  • README_RF.md - archived upstream RF-specific README

Runtime Flow

  1. Read UPDATE_STEP fresh samples (interrupt-gated).
  2. Write into circular red/IR buffers.
  3. Once the ring has at least BUFFER_SIZE samples, build an ordered analysis window.
  4. Run RF (and optional MAXIM) algorithm on that window.
  5. Push results into median filters (invalid values are preserved as sentinels).
  6. Output filtered values over Serial and to the display.

Configuration Knobs

You will most likely tune these first:

  • UPDATE_STEP in max30102_esp32c3_oled_oximeter.ino: update cadence (smaller = more responsive, noisier)
  • MEDIAN_HISTORY in max30102_esp32c3_oled_oximeter.ino: smoothing window length
  • FS, ST, and quality thresholds in algorithm_by_RF.h

Important: if you change FS or ST, keep related derived parameters in algorithm_by_RF.h consistent.

Hardware Notes

  • MAX30102 interrupt pin is expected on oxiInt (currently pin 2).
  • I2C pins are configured in max30102_esp32c3_oled_oximeter.ino and passed into maxim_max30102_init(...).
  • OLED uses U8g2 and is initialized in the sketch; verify pin mapping for your board.

Connections

ESP32-C3 MAX30102
V5 VIN
GD GND
GPIO2 INT
GPIO5 SDA
GPIO6 SCL

Troubleshooting

If HR/SpO2 is unstable or stuck:

  • verify INT wiring and polarity
  • confirm red/IR channels are not swapped
  • inspect raw PPG waveform quality before tuning algorithm constants
  • reduce motion artifacts (finger pressure and movement matter a lot)
  • start with smaller UPDATE_STEP and moderate MEDIAN_HISTORY

For historical debugging/reporting guidance, see README_RF.md.

About

MAX30102 Pulse Oximeter for ESP32-C3 OLED

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages