A functional pulse oximeter system built using the ESP32 microcontroller and MAX30102 sensor. This project demonstrates real-time measurement of blood oxygen saturation (SpO₂) and heart rate (BPM), displayed on a 128x64 OLED screen. A second version simulates photoplethysmography (PPG) signals, enabling full signal processing pipeline testing without hardware.
Designed as a showcase of self-taught applied engineering in MedTech, this project reflects my ability to:
- Translate medical sensing theory into working embedded systems
- Apply signal processing techniques to extract physiological metrics
- Work across hardware, firmware, and algorithm development
- Communicate results clearly via UI (OLED) and documentation
As a incoming graduate student in Human Systems Engineering concentraing in Health Sysems with a background in Health Technology, this hands-on build sharpens my technical credibility while reinforcing my user-centric design foundation.
| Component | Description |
|---|---|
| Microcontroller | ESP32 DOIT DevKit V1 |
| Sensor | MAX30102 (IR + Red LED, photodetector) |
| Display | SSD1306 OLED (128x64, I2C) |
| Output Metrics | SpO₂, BPM |
| Modes | Hardware mode + Simulated data mode |
| Communication | I2C for sensor + display |
| Platform | Arduino IDE |
- Hardware Mode: The MAX30102 emits IR and Red light into tissue and captures reflected light to generate raw PPG signals.
- Simulated Mode: Gaussian pulses simulate systolic/diastolic peaks + noise to mimic real PPG waveforms.
- High-Pass Filter removes baseline wander (DC drift).
- Low-Pass Filter smooths high-frequency noise and stabilizes AC signals.
- AC component = pulsatile flow (from heartbeat)
- DC component = constant light absorption by tissue
- Calculated for both IR and Red signals over a circular buffer.
Formula used: R = (AC_Red / DC_Red) ÷ (AC_IR / DC_IR) SpO₂ = 110 - 25 × R
This ratio-of-ratios method approximates blood oxygen saturation.
- Peaks in the IR waveform are detected using amplitude thresholds.
- Time between peaks determines BPM:
BPM = 60 / (time between peaks)
- Values are shown on the OLED in real-time.
- Simulated mode outputs signals to Serial Plotter.
- Uses real data from MAX30102
- Outputs live BPM/SpO₂ to OLED
- No sensor required
- Generates synthetic Red/IR PPG signals
- Follows same filtering and calculation logic
- Outputs to Serial Plotter for visualization
-
hardware_version.ino
Final implementation for real-time BPM + SpO₂ output using actual hardware. -
simulated_version.ino
Simulated PPG generator + full signal processing pipeline, with detailed inline comments. -
README.md
Full documentation and system architecture.
- Libraries:
SparkFun MAX3010xAdafruit GFXAdafruit SSD1306
| ESP32 Pin | MAX30102 | OLED Display |
|---|---|---|
| GPIO 21 | SDA | SDA |
| GPIO 22 | SCL | SCL |
| 3.3V | VIN | VCC |
| GND | GND | GND |
- Open Arduino IDE
- Select board: ESP32 Dev Module
- Install required libraries via Library Manager
- Upload
hardware_version.inoorsimulated_version.ino - Use OLED or Serial Monitor/Plotter for output
- Embedded firmware design: Programming microcontrollers to run device functions.
- Digital signal processing: Interpreting sensor data to produce meaningful measurements.
- Biomedical sensing fundamentals: Understanding how physiological signals like heart rate and oxygen saturation are measured.
- Sensor interfacing (I2C): Connecting and communicating with sensors.
- Real-time system debugging: Troubleshooting the device to ensure reliable performance.
- Simulation-driven development: Using software simulations to test and refine the system before building hardware.
This project is open-source under the MIT License.