This driver developed for the MAX30102 Heart Rate and Pulse Oximetry sensor uses an I2C communcations with an interrupt for the buffer reading as suggested in the MAX30102 Datasheet.
*Code in this repository is in the Public Domain (or CC0 licensed, at your option.) Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*- Heartbeat recognition and heart rate display
- SPO2 Measurement
ESP32 | MAX30102 |
---|---|
G21 | SDA |
G22 | SCL |
+3.3 V | Vin |
GND | GND |
G18 | INT |
The MAX30102 is controlled/adjusted using its eight bit registers. A register map detailed in the MAX30102 Datasheet.
We can see the register types, what each bit in the register does, the register address, its state when the device is powered on or reset (POR), and whether it is read only or writable.The interrupts triggered by Interrupt status 1 and Interrupt status 2 are as follows: FIFO almost full flag (A_FULL), new FIFO data ready (PPG_RDY), ambient light cancellation overflow (ALC_OVF), proximity threshold triggered (PROX_INT), power ready flag (PWR_RDY).
This interrupt table is implemented as an enum.
/**
* Interrupt Mode Enum.
* A_FULL: FIFO Almost Full Flag.
* PPG_RDY: New FIFO Data Ready.
* ALC_OVF: Ambient Light Cancellation Overflow.
* PWR_RDY: Power Flag Ready
* DIE_TEMP_RDY: Internal Temperature Ready Flag
*/
#define MAX30102_INTERRUPT_STATUS_1 0x00
#define MAX30102_INTERRUPT_STATUS_2 0x01
#define MAX30102_INTERRUPT_ENABLE_1 0x02
#define MAX30102_INTERRUPT_ENABLE_2 0x03
#define MAX30102_INTERRUPT_A_FULL 7
#define MAX30102_INTERRUPT_PPG_RDY 6
#define MAX30102_INTERRUPT_ALC_OVF 5
#define MAX30102_INTERRUPT_DIE_TEMP_RDY 1
- Enable the required interrupts:
// Enable FIFO_A_FULL interrupt
esp_err_t ret = max30102_write_register(this,MAX30102_INTERRUPT_ENABLE_1,PROX_INT_EN); //0b0001 0000 //enable prox interrupt
- Run interrupt handler once interrupt flag is active:
// If the finger is near the sensor the prox_int became 1 and the fifo a full interrupt will be enabled:
if (prox_int){
sensor_have_finger[0] = true ;
//clear buffer
max30102_write_register(&max30102,MAX30102_INTERRUPT_ENABLE_1, FIFO_A_FULL_EN); //0b1000 0000 //disable prox interrupt and enable fifo_a_full
}
The second possibility is to use the Semaphore for notify the Getbpm task when the interrupts happens and use also a led that wil blink when the interrupts is triggered.
This is implemented in the c max30102_update function. The basic equations are discussed in detail in the MAX30102 Application Node.
A possible implementations of the conversion from the raw data to SpO2 values is shown below.float ratio_rms = log( sqrt( this->red_ac_sq_sum /
(float)this->samples_recorded ) ) /
log( sqrt( this->ir_ac_sq_sum /
(float)this->samples_recorded ) );
if(this->debug)
printf("RMS Ratio: %f\n", ratio_rms);
this->current_spO2 = 104.0 - 17.0 * ratio_rms;
data->spO2 = this->current_spO2;
- DC Removal from the raw data
- Digital Signal Processing of the raw data with butterworth filter and Mean Median Filter
- SpO2 and Heart Rate Measuring