Design a clinical-accuracy pulse oximeter using AFE4490 analog front end, dual-wavelength LED, and Beer-Lambert law oxygen saturation algorithm.
Medical ElectronicsSpO2PhotoplethysmographyAFE4400Heart RateWearable
DifficultyIntermediate
Duration3–4 weeks
Components10 items
Steps4 steps
📖
Introduction
Design a clinical-accuracy pulse oximeter using AFE4490 analog front end, dual-wavelength LED, and Beer-Lambert law oxygen saturation algorithm. This comprehensive guide covers everything from design through implementation, testing, and deployment.
🧪
Theory & Background
Beer-Lambert Law: light attenuation through tissue depends on absorber concentration. Oxygenated hemoglobin (HbO2) absorbs IR more than red. Deoxygenated Hb absorbs red more than IR. At 660nm (red): Hb absorbs 10× more than HbO2. At 940nm (IR): HbO2 absorbs more. PPG (Photoplethysmography): during systole, arterial blood volume in finger increases → more light absorbed. During diastole: less absorption. AC component = pulsatile blood. DC component = tissue + venous blood. SpO2 = f(R) where R = (AC_red/DC_red) / (AC_IR/DC_IR). Calibration empirical equation: SpO2 = -45.060 × R² + 30.354 × R + 94.845.
Advertisement
🔨
Components & Requirements
10 components required for this project.
#
Component
Purpose
Qty
1
AFE4490 (Texas Instruments Pulse Oximeter AFE)
LED driver + transimpedance amplifier + ADC
x1
2
Red LED (660nm, 5mW)
Oxygenated/deoxygenated hemoglobin discrimination
x1
3
Infrared LED (940nm, 5mW)
Second wavelength measurement
x1
4
Photodiode (BPW34, broadband)
Transmitted light detection
x1
5
STM32L4 (low power MCU)
SpO2 algorithm processing
x1
6
0.96" OLED display (SSD1306)
SpO2 and HR display
x1
7
Finger clip probe housing (3D printed)
Optical path and tissue contact
x1
8
LiPo 100mAh + charger
Portable power
x1
9
Band-pass filter (0.5–4 Hz)
Heart rate signal isolation
x1
10
Arduino for prototyping (MAX30100 module first)
Algorithm prototyping before custom AFE
x1
📋
Step-by-Step Implementation
Follow these 4 steps carefully.
1
SpO2 Measurement Principle
Beer-Lambert Law: light attenuation through tissue depends on absorber concentration. Oxygenated hemoglobin (HbO2) absorbs IR more than red. Deoxygenated Hb absorbs red more than IR. At 660nm (red): Hb absorbs 10× more than HbO2. At 940nm (IR): HbO2 absorbs more. PPG (Photoplethysmography): during systole, arterial blood volume in finger increases → more light absorbed. During diastole: less absorption. AC component = pulsatile blood. DC component = tissue + venous blood. SpO2 = f(R) where R = (AC_red/DC_red) / (AC_IR/DC_IR). Calibration empirical equation: SpO2 = -45.060 × R² + 30.354 × R + 94.845.
2
AFE4490 Configuration
AFE4490: complete analog front end — drives LEDs (programmable current 0–50mA) and processes photodiode signal. LED timing: alternating LED activation — RED → blank → IR → blank. Sample rate: typically 250 Hz (programmable). Transimpedance amplifier: converts photodiode current to voltage. Programmable gain (2kΩ–1MΩ feedback). 22-bit ADC. SPI communication. Output: 32-bit signed values for RED and IR channels. Signal chain: LED driver → tissue → photodiode → TIA → ADC → MCU. Key requirement: synchronize LED timing to measurement timing (only sample during LED-ON phase).
3
SpO2 Algorithm Implementation
Extract AC and DC from raw samples: DC component = low-pass filter (moving average over 10s). AC component = bandpass filter (0.5–4 Hz — heart rate range). Peak detection: find peaks in red and IR AC signals. Calculate per-beat: AC_red = peak-to-peak red amplitude, DC_red = mean red. Similarly for IR. R ratio = (AC_red/DC_red) / (AC_IR/DC_IR). Look up SpO2 from calibration equation (or table). Average over 4–8 beats for stability. Heart rate: count peak-to-peak intervals, convert to BPM = 60 / period_seconds.
4
Clinical Accuracy Considerations
Clinical standard: SpO2 accuracy ±2% (ISO 80601-2-61). Accuracy factors: motion artifact (arm movement causes false AC signals — motion detection using accelerometer, reject noisy beats), ambient light (AFE4490 measures with LEDs off to subtract ambient light), sensor positioning (correct finger placement critical — too loose or too tight reduces signal quality), probe design (wavelengths must match calibration curves), skin pigmentation (melanin absorbs some light — recalibrate for different populations). This is an educational device — not for clinical use without regulatory approval (CE/FDA Class II medical device).
💻
Code & Implementation
Core code for spo2_algorithm.c:
spo2_algorithm.cC
// SpO2 Calculation Algorithm // Input: Raw red and IR samples from AFE4490 at 100Hz #include <stdint.h> #include <math.h> #define SAMPLE_RATE 100 #define BUFFER_SIZE 100 // 1 second of data float red_buf[BUFFER_SIZE], ir_buf[BUFFER_SIZE]; int buf_idx = 0; // Simple DC extraction (moving average) float dc_filter(float *buf, int n) { float sum = 0; for(int i = 0; i < n; i++) sum += buf[i]; return sum / n; } // Find peak-to-peak amplitude (AC component) float ac_amplitude(float *buf, int n) { float max = buf[0], min = buf[0]; for(int i = 1; i < n; i++) { if(buf[i] > max) max = buf[i]; if(buf[i] < min) min = buf[i]; } return max - min; } float calculate_spo2(void) { float dc_red = dc_filter(red_buf, BUFFER_SIZE); float dc_ir = dc_filter(ir_buf, BUFFER_SIZE); float ac_red = ac_amplitude(red_buf, BUFFER_SIZE); float ac_ir = ac_amplitude(ir_buf, BUFFER_SIZE); if(dc_red < 50000 || dc_ir < 50000) return -1; // No finger detected float R = (ac_red / dc_red) / (ac_ir / dc_ir); // Calibration equation (device-specific, calibrate against reference) float spo2 = -45.060f * R * R + 30.354f * R + 94.845f; return fmaxf(70, fminf(100, spo2)); } int calculate_heart_rate(float *ir_buf, int n) { // Simple peak detection - count peaks in IR signal int peaks = 0; float threshold = dc_filter(ir_buf, n); bool above = false; for(int i = 1; i < n-1; i++) { if(ir_buf[i] > threshold && !above) { peaks++; above = true; } else if(ir_buf[i] <= threshold) above = false; } return peaks * (60 * SAMPLE_RATE / n); // BPM }
🔬
Testing & Troubleshooting
Test Pulse Oximeter Design (SpO2) by verifying each subsystem individually before full integration.
!
Troubleshooting Tips
Verify power voltages, check ground connections, use serial monitor for debug.
🌎
Real-World Applications
*Wearable health monitoring device
*Sports performance pulse measurement
*Telemedicine peripheral device
*Clinical simulation training device
*Physiological signal processing education
*Remote patient monitoring research
*Breathing disorder research tool
*Altitude sickness monitoring research
🚀
Extensions & Next Steps
Add ECG channel for combined cardiac monitoring
Implement perfusion index measurement
Add motion artifact rejection with accelerometer
Build a multi-site monitoring system (finger + earlobe)
Implement respiratory rate extraction from PPG signal
🎮
Interactive Playground
Coming Soon
An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.
❓
Frequently Asked Questions
Can a DIY pulse oximeter be trusted for medical decisions?
NO. A DIY pulse oximeter should never be used for clinical decisions. Reasons: uncalibrated (calibration requires comparison with co-oximetry blood samples across SpO2 range 70–100%), no validation testing (clinical devices tested on diverse skin tones, with motion, in clinical conditions), no regulatory approval (FDA Class II device in US, Class IIa in EU — requires extensive clinical testing), no quality control manufacturing (component variations affect accuracy). Use case: educational understanding of photoplethysmography and SpO2 physics. For health monitoring: use FDA/CE-cleared commercial devices (Masimo, Nellcor, or validated consumer devices like certain Fitbit, Apple Watch models).