nferrante93 / ESP32_MAX30102

Development of a real-time systems for read SpO2 and heart rate from a max30102 sensor with a ESP32-C3 microcontroller.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ESP-IDF Heart Rate and Oximeter Sensor

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

Summary

  • Heartbeat recognition and heart rate display
  • SPO2 Measurement

Quick Start

Minimimal Setup

The Connection with the ESP32-C3 are as follow:
ESP32 MAX30102
G21 SDA
G22 SCL
+3.3 V Vin
GND GND
G18 INT

Registers

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.

Interrupts Registers

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

Settings Interrupts Registers

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.

SpO2

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;

Future Improvements

  • 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

References

MAX30102 Datasheet

MAX30102 Application Node

About

Development of a real-time systems for read SpO2 and heart rate from a max30102 sensor with a ESP32-C3 microcontroller.


Languages

Language:C 99.0%Language:CMake 1.0%