Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/issue_template.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Troubleshooting checklist

- [ ] I read the README (on master) thoroughly
- [ ] I ran the MAX30100_Tester and I'm going to paste the output down below
- [ ] I ran the MAX30102_Tester and I'm going to paste the output down below
- [ ] I filled in all the details of my setup down below

### Description of the issue
Expand All @@ -11,6 +11,6 @@
### Details of my setup

* Arduino hardware:
* MAX30100 breakout:
* MAX30102 breakout:
* Arduino framework version:
* MAX30100 library version:
* MAX30102 library version:
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ cache:
- "~/.platformio"

env:
- PLATFORMIO_CI_SRC=examples/MAX30100_Minimal
- PLATFORMIO_CI_SRC=examples/MAX30100_Debug
- PLATFORMIO_CI_SRC=examples/MAX30102_Minimal
- PLATFORMIO_CI_SRC=examples/MAX30102_Debug

install:
- pip install -U platformio
Expand Down
64 changes: 30 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
# Arduino-MAX30100
# Arduino-MAX30102

[![Build Status](https://travis-ci.org/oxullo/Arduino-MAX30100.svg?branch=master)](https://travis-ci.org/oxullo/Arduino-MAX30100)
Arduino library for the Maxim Integrated MAX30102 oximetry / heart rate sensor by Shivam Gupta <gupta.shivam1996@gmail.com>

Arduino library for the Maxim Integrated MAX30100 oximetry / heart rate sensor.

![MAX30100](http://www.mouser.com/images/microsites/Maxim_MAX30100.jpg)
Based on a library written for the older MAX30100 sensor by OXullo Intersecans <x@brainrapers.org> in 2016.
It has been ported to work with MAX30102 sensor breakouts, and new functions have been added to the library such as channel control,
so that all available functions of the device can be accessed with ease.

All algorithms and example codes are written by the above author [OXullo Intersecans <x@brainrapers.org>], this is a fork building on that to extend support.
Original Library can be found here : https://github.com/oxullo/Arduino-MAX30100

vvvvvvvvvvvvvv
Carried over content, changed to fit the experiments I performed:
vvvvvvvvvvvvvv

## Disclaimer

The library is offered only for educational purposes and it is not meant for medical uses.
Use it at your sole risk.

## Notes

Maxim integrated stopped the production of the MAX30100 in favor of MAX30101 and MAX30102.
Therefore this library won't be seeing any further improvement, besides fixes.

*IMPORTANT: when submitting issues, make sure to fill ALL the fields indicated in the template text of the issue. The issue will be marked as invalid and closed immediately otherwise.*

## Hardware

This library has been tested with the MikroElektronika Heart rate click daughterboard:
This library has been tested with two different breakout boards for MAX30102

https://www.amazon.in/xcluma-MAX30102-Upgraded-Ultra-Low-Compatible/dp/B07TZCNG2G/ref=sr_1_1?crid=3H93UW42TRQWY&dchild=1&keywords=xcluma+max30102&qid=1601127280&sprefix=xcluma+max%2Caps%2C299&sr=8-1

https://robokits.co.in/sensors/heart-beat-sensor/max30102-oximetry-sensor-module

http://www.mikroe.com/click/heart-rate/
https://in.element14.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=15001&langId=91&productSeoURL=maxim-integrated-products&storeId=10186&partNumber=2627165&krypto=R4I%2BFWxL8JW4fRaTcbt%2BHuLRKF64g5pcACQC6j4AdeuGGnr%2F0z4QoAgzJYIFu516Z9ZklPwUROYW5qFA%2BXaDmA%3D%3D

along with an Arduino UNO r3. Any Arduino supporting the Wire library should work.

Expand All @@ -41,7 +48,7 @@ up by 4,7kOhm or less resistors.

## Architecture

The library offers a low-level driver class, MAX30100.
The library offers a low-level driver class, MAX30102.
This component allows for low level communication with the device.

A rather simple but working implementation of the heart rate and SpO2 calculation
Expand All @@ -61,18 +68,18 @@ The PulseOximeter class is not optimised for battery-based projects.

The included examples show how to use the PulseOximeter class:

* MAX30100_Minimal: a minimal example that dumps human-readable results via serial
* MAX30100_Debug: used in conjunction with the Processing pde "rolling_graph" (extras folder), to show the sampled data at various processing stages
* MAX30100_RawData: demonstrates how to access raw data from the sensor
* MAX30100_Tester: this sketch helps to find out potential issues with the sensor
* MAX30102_Minimal: a minimal example that dumps human-readable results via serial
* MAX30102_Debug: used in conjunction with the Processing pde "rolling_graph" (extras folder), to show the sampled data at various processing stages
* MAX30102_RawData: demonstrates how to access raw data from the sensor
* MAX30102_Tester: this sketch helps to find out potential issues with the sensor

## Troubleshooting

Run the MAX30100_Tester example to inspect the state of your rig.
Run the MAX30102_Tester example to inspect the state of your rig.
When run with a properly connected sensor, it should print:

```
Initializing MAX30100..Success
Initializing MAX30102..Success
Enabling HR/SPO2 mode..done.
Configuring LEDs biases to 50mA..done.
Lowering the current to 7.6mA..done.
Expand All @@ -95,7 +102,7 @@ Typical issues when attempting to run the examples:
In particular when the tester fails with:

```
Initializing MAX30100..FAILED: I2C error
Initializing MAX30102..FAILED: I2C error
```

This is likely to be caused by an improper pullup setup for the I2C lines.
Expand All @@ -109,7 +116,7 @@ to 3.3V, you should ensure that its inputs are compatible with the 3.3V logic le
An original Atmel ATMega328p considers anything above 3V as HIGH, so it might work well without
level shifting hardware.

Since the MAX30100 I2C pins maximum ratings aren't bound to Vdd, a cheap option to avoid
Since the MAX30102 I2C pins maximum ratings aren't bound to Vdd, a cheap option to avoid
level shifting is to simply pull SDA and SCL up to 5V instead of 3.3V.

### Sketchy beat frequency readouts
Expand All @@ -119,31 +126,20 @@ by default at 50mA on all examples, excluding the Tester (which sets it to 7.6mA
This value is somehow critical and it must be experimented with.

The current can be adjusted using PulseOximeter::setIRLedCurrent().
Check the _MAX30100_Minimal_ example.
Check the _MAX30102_Minimal_ example.

### Advanced debugging

Two tools are available for further inspection and error reporting:

* extras/recorder: a python script that records a session that can be then analysed with the provided collection of jupyter notebooks
* extras/rolling_graph: to be used in conjunction with _MAX30100_Debug_ example, it provides a visual feedback of the LED tracking and heartbeat detector
* extras/rolling_graph: to be used in conjunction with _MAX30102_Debug_ example, it provides a visual feedback of the LED tracking and heartbeat detector

Both tools have additional information on the README.md in their respective directories.

## Tested devices

* Arduino UNO r3, Mikroelektronika Heart rate click (https://shop.mikroe.com/heart-rate-click)

This combination works without level shifting devices at 400kHz I2C clock rate.

* Arduino UNO r3, MAX30100 custom board with 4.7kOhm pullups to 5V to SDA, SCL, INT

As above, working at 400kHz

* Sparkfun Arduino Pro 328p 8MHz 3.3V, Mikroelektronika Heart rate click

Even if this combination works (MAX30100 communication), the slower clock speed fails to deliver
the required performance deadlines for a 100Hz sampling.
#todo

## Troubled breakouts

Expand Down
Original file line number Diff line number Diff line change
@@ -1,81 +1,84 @@
/*
Arduino-MAX30100 oximetry / heart rate integrated sensor library
Copyright (C) 2016 OXullo Intersecans <x@brainrapers.org>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// This example must be used in conjunction with the Processing sketch located
// in extras/rolling_graph

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

// PulseOximeter is the higher level interface to the sensor
// it offers:
// * beat detection reporting
// * heart rate calculation
// * SpO2 (oxidation level) calculation
PulseOximeter pox;

uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
Serial.println("B:1");
}

void setup()
{
Serial.begin(115200);

// Initialize the PulseOximeter instance and register a beat-detected callback
// The parameter passed to the begin() method changes the samples flow that
// the library spews to the serial.
// Options:
// * PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT : filtered samples and beat detection threshold
// * PULSEOXIMETER_DEBUGGINGMODE_RAW_VALUES : sampled values coming from the sensor, with no processing
// * PULSEOXIMETER_DEBUGGINGMODE_AC_VALUES : sampled values after the DC removal filter

// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT)) {
Serial.println("ERROR: Failed to initialize pulse oximeter");
for(;;);
}

pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
// Make sure to call update as fast as possible
pox.update();

// Asynchronously dump heart rate and oxidation levels to the serial
// For both, a value of 0 means "invalid"
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("H:");
Serial.println(pox.getHeartRate());

Serial.print("O:");
Serial.println(pox.getSpO2());

tsLastReport = millis();
}
}
/*
Arduino-MAX30102 oximetry / heart rate integrated sensor library by Shivam Gupta (gupta.shivam1996@gmail.com)

Based on MAX30100 library, Copyright (C) 2016 OXullo Intersecans <x@brainrapers.org>
All alogrithms and methods used are from the above author,
I have only modified this enough to make it work with the new MAX30102 sensor.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// This example must be used in conjunction with the Processing sketch located
// in extras/rolling_graph

#include <Wire.h>
#include "MAX30102_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

// PulseOximeter is the higher level interface to the sensor
// it offers:
// * beat detection reporting
// * heart rate calculation
// * SpO2 (oxidation level) calculation
PulseOximeter pox;

uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
Serial.println("B:1");
}

void setup()
{
Serial.begin(115200);

// Initialize the PulseOximeter instance and register a beat-detected callback
// The parameter passed to the begin() method changes the samples flow that
// the library spews to the serial.
// Options:
// * PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT : filtered samples and beat detection threshold
// * PULSEOXIMETER_DEBUGGINGMODE_RAW_VALUES : sampled values coming from the sensor, with no processing
// * PULSEOXIMETER_DEBUGGINGMODE_AC_VALUES : sampled values after the DC removal filter

// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT)) {
Serial.println("ERROR: Failed to initialize pulse oximeter");
for(;;);
}

pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
// Make sure to call update as fast as possible
pox.update();

// Asynchronously dump heart rate and oxidation levels to the serial
// For both, a value of 0 means "invalid"
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("H:");
Serial.println(pox.getHeartRate());

Serial.print("O:");
Serial.println(pox.getSpO2());

tsLastReport = millis();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/*
Arduino-MAX30100 oximetry / heart rate integrated sensor library
Copyright (C) 2016 OXullo Intersecans <x@brainrapers.org>
Arduino-MAX30102 oximetry / heart rate integrated sensor library by Shivam Gupta (gupta.shivam1996@gmail.com)

Based on MAX30100 library, Copyright (C) 2016 OXullo Intersecans <x@brainrapers.org>
All alogrithms and methods used are from the above author,
I have only modified this enough to make it work with the new MAX30102 sensor.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -17,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include "MAX30102_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

Expand Down Expand Up @@ -53,9 +56,9 @@ void setup()
}

// The default current for the IR LED is 50mA and it could be changed
// by uncommenting the following line. Check MAX30100_Registers.h for all the
// by uncommenting the following line. Check MAX30102_Registers.h for all the
// available options.
// pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// pox.setIRLedCurrent(MAX30102_LED_CURR_7_6MA);

// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
Expand Down
Loading