Homemade Pulse Oximetry Display (The H-P.O.D.)
A convenient way of measuring BPM and blood-oxygen saturation levels (SPO2) from the comfort of your own home.
Components and supplies
1
MAX30102 High-Sensitivity Pulse Oximeter and Heart-Rate Sensor for Wearable Health
1
I2C 16x2 Arduino LCD Display Module
1
Arduino UNO
1
Breadboard (generic)
Tools and machines
1
Soldering iron (generic)
Apps and platforms
1
Arduino IDE
Project description
Code
The Code
arduino
1/*! 2* @file SPO2.ino 3* @brief Display heart-rate and SPO2 on serial in real-time, normal SPO2 is within 95~100 4* @n Try to fix the sensor on your finger in using to avoid the effect of pressure change on data output. 5* @n This library supports mainboards: ESP8266, FireBeetle-M0, UNO, ESP32, Leonardo, Mega2560 6* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) 7* @licence The MIT License (MIT) 8* @author [YeHangYu](hangyu.ye@dfrobot.com) 9* @version V0.1 10* @date 2020-05-29 11* @url https://github.com/DFRobot/DFRobot_MAX30102 12*/ 13#include <DFRobot_MAX30102.h> 14DFRobot_MAX30102 particleSensor; 15/* 16Macro definition options in sensor configuration 17sampleAverage: SAMPLEAVG_1 SAMPLEAVG_2 SAMPLEAVG_4 18 SAMPLEAVG_8 SAMPLEAVG_16 SAMPLEAVG_32 19ledMode: MODE_REDONLY MODE_RED_IR MODE_MULTILED 20sampleRate: PULSEWIDTH_69 PULSEWIDTH_118 PULSEWIDTH_215 PULSEWIDTH_411 21pulseWidth: SAMPLERATE_50 SAMPLERATE_100 SAMPLERATE_200 SAMPLERATE_400 22 SAMPLERATE_800 SAMPLERATE_1000 SAMPLERATE_1600 SAMPLERATE_3200 23adcRange: ADCRANGE_2048 ADCRANGE_4096 ADCRANGE_8192 ADCRANGE_16384 24*/ 25#include <Wire.h> 26#include <LCD_I2C.h> 27LCD_I2C lcd(0x27); // Default address of most PCF8574 modules, change according 28 29 30void setup() 31{ 32 lcd.begin(); // If you are using more I2C devices using the Wire library use lcd.begin(false) 33 // this stop the library(LCD_I2C) from calling Wire.begin() 34 lcd.backlight(); 35 lcd.home(); 36 lcd.clear(); 37Serial.begin(9600); 38/*! 39 *@brief Init sensor 40 *@param pWire IIC bus pointer object and construction device, can both pass or not pass parameters (Wire in default) 41 *@param i2cAddr Chip IIC address (0x57 in default) 42 *@return true or false 43 */ 44while (!particleSensor.begin()) { 45 //lcd.println("MAX30102 was not found"); 46 delay(1000); 47} 48/*! 49 *@brief Use macro definition to configure sensor 50 *@param ledBrightness LED brightness, default value: 0x1F(6.4mA), Range: 0~255(0=Off, 255=50mA) 51 *@param sampleAverage Average multiple samples then draw once, reduce data throughput, default 4 samples average 52 *@param ledMode LED mode, default to use red light and IR at the same time 53 *@param sampleRate Sampling rate, default 400 samples every second 54 *@param pulseWidth Pulse width: the longer the pulse width, the wider the detection range. Default to be Max range 55 *@param adcRange ADC Measurement Range, default 4096 (nA), 15.63(pA) per LSB 56 */ 57particleSensor.sensorConfiguration(/*ledBrightness=*/50, /*sampleAverage=*/SAMPLEAVG_4, \\ 58 /*ledMode=*/MODE_MULTILED, /*sampleRate=*/SAMPLERATE_100, \\ 59 /*pulseWidth=*/PULSEWIDTH_411, /*adcRange=*/ADCRANGE_16384); 60} 61 62int32_t SPO2; //SPO2 63int8_t SPO2Valid; //Flag to display if SPO2 calculation is valid 64int32_t heartRate; //Heart-rate 65int8_t heartRateValid; //Flag to display if heart-rate calculation is valid 66 67void loop() 68{ 69 particleSensor.heartrateAndOxygenSaturation(/**SPO2=*/&SPO2, /**SPO2Valid=*/&SPO2Valid, /**heartRate=*/&heartRate, /**heartRateValid=*/&heartRateValid); 70 lcd.setCursor(1,0); 71 lcd.print("BPM: "); 72 lcd.print(heartRate, DEC); 73 lcd.print(" "); 74 lcd.print(" "); 75 76lcd.setCursor(0, 1); 77if (heartRateValid == 1){ 78lcd.print(F("SPO2: ")); 79lcd.print(SPO2, DEC); 80} else if (heartRateValid == 0) { 81lcd.print(F("SPO2: 0")); 82lcd.print("%"); 83 84} 85 delay(10); 86}
The Code
arduino
1/*! 2* @file SPO2.ino 3* @brief Display heart-rate and SPO2 on serial 4 in real-time, normal SPO2 is within 95~100 5* @n Try to fix the sensor on your 6 finger in using to avoid the effect of pressure change on data output. 7* @n This 8 library supports mainboards: ESP8266, FireBeetle-M0, UNO, ESP32, Leonardo, Mega2560 9* 10 @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) 11* @licence 12 The MIT License (MIT) 13* @author [YeHangYu](hangyu.ye@dfrobot.com) 14* @version 15 V0.1 16* @date 2020-05-29 17* @url https://github.com/DFRobot/DFRobot_MAX30102 18*/ 19#include 20 <DFRobot_MAX30102.h> 21DFRobot_MAX30102 particleSensor; 22/* 23Macro definition 24 options in sensor configuration 25sampleAverage: SAMPLEAVG_1 SAMPLEAVG_2 SAMPLEAVG_4 26 27 SAMPLEAVG_8 SAMPLEAVG_16 SAMPLEAVG_32 28ledMode: MODE_REDONLY 29 MODE_RED_IR MODE_MULTILED 30sampleRate: PULSEWIDTH_69 PULSEWIDTH_118 PULSEWIDTH_215 31 PULSEWIDTH_411 32pulseWidth: SAMPLERATE_50 SAMPLERATE_100 SAMPLERATE_200 SAMPLERATE_400 33 34 SAMPLERATE_800 SAMPLERATE_1000 SAMPLERATE_1600 SAMPLERATE_3200 35adcRange: 36 ADCRANGE_2048 ADCRANGE_4096 ADCRANGE_8192 ADCRANGE_16384 37*/ 38#include 39 <Wire.h> 40#include <LCD_I2C.h> 41LCD_I2C lcd(0x27); // Default address of most 42 PCF8574 modules, change according 43 44 45void setup() 46{ 47 lcd.begin(); 48 // If you are using more I2C devices using the Wire library use lcd.begin(false) 49 50 // this stop the library(LCD_I2C) from calling Wire.begin() 51 52 lcd.backlight(); 53 lcd.home(); 54 lcd.clear(); 55Serial.begin(9600); 56/*! 57 58 *@brief Init sensor 59 *@param pWire IIC bus pointer object and construction device, 60 can both pass or not pass parameters (Wire in default) 61 *@param i2cAddr Chip 62 IIC address (0x57 in default) 63 *@return true or false 64 */ 65while (!particleSensor.begin()) 66 { 67 //lcd.println("MAX30102 was not found"); 68 delay(1000); 69} 70/*! 71 72 *@brief Use macro definition to configure sensor 73 *@param ledBrightness LED brightness, 74 default value: 0x1F(6.4mA), Range: 0~255(0=Off, 255=50mA) 75 *@param sampleAverage 76 Average multiple samples then draw once, reduce data throughput, default 4 samples 77 average 78 *@param ledMode LED mode, default to use red light and IR at the same 79 time 80 *@param sampleRate Sampling rate, default 400 samples every second 81 82 *@param pulseWidth Pulse width: the longer the pulse width, the wider the detection 83 range. Default to be Max range 84 *@param adcRange ADC Measurement Range, default 85 4096 (nA), 15.63(pA) per LSB 86 */ 87particleSensor.sensorConfiguration(/*ledBrightness=*/50, 88 /*sampleAverage=*/SAMPLEAVG_4, \\ 89 /*ledMode=*/MODE_MULTILED, 90 /*sampleRate=*/SAMPLERATE_100, \\ 91 /*pulseWidth=*/PULSEWIDTH_411, 92 /*adcRange=*/ADCRANGE_16384); 93} 94 95int32_t SPO2; //SPO2 96int8_t 97 SPO2Valid; //Flag to display if SPO2 calculation is valid 98int32_t heartRate; 99 //Heart-rate 100int8_t heartRateValid; //Flag to display if heart-rate calculation 101 is valid 102 103void loop() 104{ 105 particleSensor.heartrateAndOxygenSaturation(/**SPO2=*/&SPO2, 106 /**SPO2Valid=*/&SPO2Valid, /**heartRate=*/&heartRate, /**heartRateValid=*/&heartRateValid); 107 108 lcd.setCursor(1,0); 109 lcd.print("BPM: "); 110 lcd.print(heartRate, DEC); 111 112 lcd.print(" "); 113 lcd.print(" "); 114 115lcd.setCursor(0, 1); 116if (heartRateValid 117 == 1){ 118lcd.print(F("SPO2: ")); 119lcd.print(SPO2, DEC); 120} else if (heartRateValid 121 == 0) { 122lcd.print(F("SPO2: 0")); 123lcd.print("%"); 124 125} 126 delay(10); 127}
Downloadable files
Max30102 Basic Schematic
Max30102 Basic Schematic

Documentation
Max30102 Basic Setup
Max30102 Basic Setup

Max30102 Basic Setup
Max30102 Basic Setup

Comments
Only logged in users can leave comments