MAX30102 pulse oximeter library. Get raw data from IR and Red lights through I2C and the actual temperature in degrees Celcius.

Fork of MAX30100 by StepOne

Files at this revision

API Documentation at this revision

Comitter:
Filea
Date:
Tue Jun 21 09:43:15 2016 +0000
Parent:
0:e1e1947a9882
Commit message:
Modified the code from the library MAX30100 to work with MAX30102 pulse oximeter.

Changed in this revision

max30100.cpp Show diff for this revision Revisions of this file
max30100.h Show diff for this revision Revisions of this file
max30102.cpp Show annotated file Show diff for this revision Revisions of this file
max30102.h Show annotated file Show diff for this revision Revisions of this file
diff -r e1e1947a9882 -r 02f411fefe6f max30100.cpp
--- a/max30100.cpp	Sun Apr 03 13:43:19 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- Library for the Maxim MAX30100 pulse oximetry system
- */
-
-#include "max30100.h"
-#include "functions.h"
-
-static Serial pc(SERIAL_TX, SERIAL_RX);
-
-void MAX30100::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
-    data_read[0] = data_read[0] & 0xFC; // Set LED_PW to 00
-    data_write[0] = data_read[0] | pw;
-    i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1);     // Mask LED_PW
-    data_write[0] = ((red<<4) | ir);
-    i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1); // write LED configs
-}
-
-void MAX30100::setSPO2(sampleRate sr, high_resolution hi_res){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
-    data_read[0] = data_read[0] & 0xA3; // Set SPO2_SR to 000 and SPO2_HI_RES_EN to 0
-    data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6);
-    i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); // Mask SPO2_SR
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
-    data_write[0] = data_read[0] & 0xF8; // Set Mode to 000
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE
-}
-
-void MAX30100::setInterruptSPO2(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1);
-    data_write[0] = data_read[0] | 0x10; // Set Interrupt enable for SPO2
-    i2c_write(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_write, 1); // Mask ENB_SPO2_RDY
-}
-
-int MAX30100::getNumSamp(void){
-    char data_read[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1);
-    char wrPtr = data_read[0];
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1);
-    char rdPtr = data_read[0];
-    return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16);
-}
-
-void MAX30100::setTemp(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
-    data_write[0] = data_read[0] | 0x0B;    // Set SPO2 Mode and enable temperature
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
-}
-
-void MAX30100::setSPO2mode(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
-    data_write[0] = data_read[0] | 0x03;    // Set SPO2 Mode
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1);
-}
-
-int MAX30100::readTemp(void){
-    char data_read[1];
-    char temp_int, temp_fract;
-    int temp_measured;
-    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1);
-    temp_int = data_read[0];
-    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1);
-    temp_fract = data_read[0] & 0x0F;
-    temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4);
-    return temp_measured;
-}
-
-void MAX30100::readSensor(void){
-    char data_read[4];
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 4);  // Read four times from the FIFO
-    HR = (data_read[0]<<8) | data_read[1];    // Combine values to get the actual number
-    SPO2 = (data_read[2]<<8) | data_read[3];  // Combine values to get the actual number
-}
-
-void MAX30100::shutdown(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);  // Get the current register
-    data_write[0] = data_read[0] | 0x80;
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1);   // mask the SHDN bit
-}
-
-void MAX30100::reset(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);  // Get the current register
-    data_write[0] = data_read[0] | 0x40;
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1);   // mask the RESET bit
-}
-
-void MAX30100::startup(void){
-    char data_read[1];
-    char data_write[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);  // Get the current register
-    data_write[0] = data_read[0] & 0x7F;
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1);   // mask the SHDN bit
-}
-
-char MAX30100::getRevID(void){
-    char data_read[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1);
-    return data_read[0];
-}
-
-char MAX30100::getPartID(void){
-    char data_read[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1);
-    return data_read[0];
-}
-
-void MAX30100::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){
-    char data_write[1];
-    data_write[0] = 0x03;
-    i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Heart rate only
-    data_write[0] = ir;
-    i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1);
-    data_write[0] = ((sr<<2)|pw);
-    i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1);
-}
-
-void MAX30100::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){
-    
-    setLEDs(pw, red, ir);
-    setSPO2(sr, hi_res);
-    
-}
-
-void MAX30100::printRegisters(void){
-    char data_read[1];
-    i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, data_read, 1);
-    pc.printf("INT_STATUS: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1);
-    pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1);
-    pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_OVR_COUNTER, data_read, 1);
-    pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1);
-    pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 1);
-    pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
-    pc.printf("CONFIG: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
-    pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_read, 1);
-    pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1);
-    pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1);
-    pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1);
-    pc.printf("REVISION_ID: %#4X\r\n", data_read[0]);
-    i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1);
-    pc.printf("PART_ID: %#4X\r\n", data_read[0]);
-}
diff -r e1e1947a9882 -r 02f411fefe6f max30100.h
--- a/max30100.h	Sun Apr 03 13:43:19 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- Library for the Maxim MAX30100 pulse oximetry system
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __MAX30100_H
-#define __MAX30100_H
-
-#include "mbed.h"
-
-
-/******************************************************************************/
-/*********** PULSE OXIMETER AND HEART RATE REGISTER MAPPING  **************/
-/******************************************************************************/
-
-// status registers
-#define MAX30100_INT_STATUS          0x00
-#define MAX30100_INT_ENABLE          0x01
-
-// FIFO registers
-#define MAX30100_FIFO_W_POINTER      0x02
-#define MAX30100_OVR_COUNTER         0x03
-#define MAX30100_FIFO_R_POINTER      0x04
-#define MAX30100_FIFO_DATA_REG       0x05
-
-// configuration registers
-#define MAX30100_CONFIG              0x06
-#define MAX30100_SPO2_CONFIG         0x07
-#define MAX30100_LED_CONFIG          0x09
-
-// temperature registers
-#define MAX30100_TEMP_INTEGER        0x16
-#define MAX30100_TEMP_FRACTION       0x17
-
-// PART ID registers
-#define MAX30100_REVISION_ID         0xFE
-#define MAX30100_PART_ID             0xFF
-
-#define I_AM_MAX30100                0x11
-
-/************************************** REGISTERS VALUE *******************************************/
-
-// I2C address
-#define MAX30100_ADDRESS             0xAE
-
-//Enable interrupts
-#define MAX30100_INT_ENB_A_FULL      ((uint8_t)0x80)
-#define MAX30100_INT_ENB_TEMP_RDY    ((uint8_t)0x40)
-#define MAX30100_INT_ENB_HR_RDY      ((uint8_t)0x20)
-#define MAX30100_INT_ENB_SO2_RDY     ((uint8_t)0x10)
-
-//Mode configuration
-#define MAX30100_MODE_SHDN           ((uint8_t)0x80)
-#define MAX30100_MODE_RESET          ((uint8_t)0x40)
-#define MAX30100_MODE_TEMP_EN        ((uint8_t)0x08)
-#define MAX30100_MODE_HR             ((uint8_t)0x02)
-#define MAX30100_MODE_SPO2           ((uint8_t)0x03)
-
-//SPO2 configuration
-#define MAX30100_SPO2_HI_RES_EN           ((uint8_t)0x40)
-
-typedef enum{ // This is the same for both LEDs
-    pw200,    // 200us pulse
-    pw400,    // 400us pulse
-    pw800,    // 800us pulse
-    pw1600    // 1600us pulse
-}pulseWidth;
-
-typedef enum{
-    sr50,    // 50 samples per second
-    sr100,   // 100 samples per second
-    sr167,   // 167 samples per second
-    sr200,   // 200 samples per second
-    sr400,   // 400 samples per second
-    sr600,   // 600 samples per second
-    sr800,   // 800 samples per second
-    sr1000   // 1000 samples per second
-}sampleRate;
-
-typedef enum{
-    i0,    // No current
-    i4,    // 4.4mA
-    i8,    // 7.6mA
-    i11,   // 11.0mA
-    i14,   // 14.2mA
-    i17,   // 17.4mA
-    i21,   // 20.8mA
-    i27,   // 27.1mA
-    i31,   // 30.6mA
-    i34,   // 33.8mA
-    i37,   // 37.0mA
-    i40,   // 40.2mA
-    i44,   // 43.6mA
-    i47,   // 46.8mA
-    i50    // 50.0mA
-}ledCurrent;
-
-typedef enum{
-    low,    // low resolution SPO2
-    high    // high resolution SPO2 (16 bit with 1.6ms LED pulse width)
-}high_resolution;
-
-typedef enum
-{
-    OXIMETER_OK = 0,
-    OXIMETER_ERROR = 1,
-    OXIMETER_TIMEOUT = 2,
-    OXIMETER_NOT_IMPLEMENTED = 3
-} OXIMETER_StatusTypeDef;
-
-/**
- * @brief  MAX30100 driver extended internal structure definition
- */
-typedef struct
-{
-    OXIMETER_StatusTypeDef (*Enable_Free_Fall_Detection) (void);
-    OXIMETER_StatusTypeDef (*Disable_Free_Fall_Detection) (void);
-    OXIMETER_StatusTypeDef (*Get_Status_Free_Fall_Detection) (uint8_t *);
-} MAX30100_DrvExtTypeDef;
-
-class MAX30100 {
-public:
-        
-    /* Public Methods */
-    
-    uint16_t HR;      // Last heart rate datapoint
-    uint16_t SPO2;    // Last oximetry datapoint
-    
-    void  setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir);  // Sets the LED state
-    void  setSPO2(sampleRate sr, high_resolution hi_res); // Setup the SPO2 sensor, disabled by default
-    int   getNumSamp(void);       // Get number of samples
-    void  readSensor(void);       // Updates the values
-    void  shutdown(void);   // Instructs device to power-save
-    void  reset(void);      // Resets the device
-    void  startup(void);    // Leaves power-save
-    char  getRevID(void);   // Gets revision ID
-    char  getPartID(void);  // Gets part ID
-    void  begin(pulseWidth pw = pw1600, // Longest pulseWidth
-                ledCurrent ir = i50,    // Highest current
-                sampleRate sr = sr100); // 2nd lowest sampleRate
-    void  init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir);
-    void  setTemp(void);
-    int   readTemp(void);
-    void  setSPO2mode(void);
-    void  setInterruptSPO2(void);
-    void  printRegisters(void); // Dumps contents of registers for debug
-};
-
-#endif /* __MAX30100_H */
\ No newline at end of file
diff -r e1e1947a9882 -r 02f411fefe6f max30102.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max30102.cpp	Tue Jun 21 09:43:15 2016 +0000
@@ -0,0 +1,183 @@
+/*
+ * Library for the Maxim MAX30102 pulse oximetry system, I modified a copy of the MAX30100 library in May 2016
+ */
+
+#include "max30102.h"
+#include "functions.h"
+ 
+Serial pc(USBTX, USBRX);
+
+void MAX30102::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1);
+    data_read[0] = data_read[0] & 0xFD;                                 // Set LED_PW to 01
+    data_write[0] = data_read[0] | pw;
+    i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1);   // Mask LED_PW
+    data_write[0] = (red);
+    i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1);  // write LED1 configs
+    data_write[0] = (ir);
+    i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_write, 1);  // write LED2 configs
+}
+
+void MAX30102::setSPO2(sampleRate sr, high_resolution hi_res){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1);
+    data_read[0] = data_read[0] & 0x85;                                 // Set ADC_rge to 00, SPO2_SR to 001 = sr100 and LEDpw to 01 = 118
+    data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6);
+    i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1);   // Mask SPO2_SR
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);
+    data_write[0] = data_read[0] & 0xF8; // Set Mode to 000
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);        // Mask MODE
+}
+
+void MAX30102::setInterruptSPO2(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1);
+    data_write[0] = data_read[0] & 0x00;                                // Set Interrupt enable for SPO2 | 0x10   // New: disable prox! & ~0x10
+    i2c_write(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_write, 1);    // Mask ENB_SPO2_RDY
+} 
+
+int MAX30102::getNumSamp(void){
+    char data_read[1] = {0};
+//    i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1);
+//    i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1);
+//    wait(0.148);
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1);
+    char wrPtr = data_read[0];
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1);
+    char rdPtr = data_read[0];
+    return ((int)wrPtr - (int)rdPtr);                                   // New counting
+ //   return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16);
+}
+
+void MAX30102::setTemp(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1);
+    data_write[0] = data_read[0] | 0x01;    // Enable temperature
+    i2c_write(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_write, 1);   // Mask MODE
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1);
+}
+
+void MAX30102::setSPO2mode(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);
+    data_write[0] = data_read[0] | 0x03;    // Set SPO2 Mode
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);
+}
+
+int MAX30102::readTemp(void){
+    char data_read[1];
+    char temp_int, temp_fract;
+    int temp_measured;
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1);
+    temp_int = data_read[0];
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1);
+    temp_fract = data_read[0] & 0x0F;
+    temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4);
+    return temp_measured;
+}
+
+void MAX30102::readSensor(void){
+    char data_read[6] = {0}; 
+    HR = 0;
+    SPO2 = 0;
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 6);   // Read six times from the FIFO
+    HR = (data_read[0]<<16) | (data_read[1]<<8) | data_read[2];         // Combine values to get the actual number
+    HR = HR>>2;
+    SPO2 = (data_read[3]<<16) | (data_read[4]<<8) | data_read[5];       // Combine values to get the actual number
+    SPO2 = SPO2>>2;
+}
+
+void MAX30102::shutdown(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);          // Get the current register
+    data_write[0] = data_read[0] | 0x80;
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);        // mask the SHDN bit
+}
+
+void MAX30102::reset(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);          // Get the current register
+    data_write[0] = data_read[0] | 0x40;
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);        // mask the RESET bit
+}
+
+void MAX30102::startup(void){
+    char data_read[1];
+    char data_write[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);          // Get the current register
+    data_write[0] = data_read[0] & 0x7F;
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);        // mask the SHDN bit
+}
+
+char MAX30102::getRevID(void){
+    char data_read[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1);
+    return data_read[0];
+}
+
+char MAX30102::getPartID(void){
+    char data_read[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1);
+    return data_read[0];
+}
+
+void MAX30102::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){
+    char data_write[1];
+    data_write[0] = 0x02;
+    i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1);        // Heart rate only
+    data_write[0] = ir;
+    i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1);
+    data_write[0] = ((sr<<2)|pw);
+    i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1);
+}
+
+void MAX30102::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){
+    char data_write[1];
+    
+    setLEDs(pw, red, ir);
+    setSPO2(sr, hi_res);
+    
+    data_write[0] = 0x10;
+    i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_CONFIG, data_write, 1);
+      
+}
+
+void MAX30102::printRegisters(void){
+    char data_read[1];
+    i2c_read(MAX30102_ADDRESS, MAX30102_INT_STATUS, data_read, 1);
+    pc.printf("INT_STATUS: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1);
+    pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1);
+    pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_OVR_COUNTER, data_read, 1);
+    pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1);
+    pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 1);
+    pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1);
+    pc.printf("CONFIG: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1);
+    pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_read, 1);
+    pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1);
+    pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1);
+    pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1);
+    pc.printf("TEMP_CONFIG: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1);
+    pc.printf("REVISION_ID: %#4X\r\n", data_read[0]);
+    i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1);
+    pc.printf("PART_ID: %#4X\r\n", data_read[0]);
+}
diff -r e1e1947a9882 -r 02f411fefe6f max30102.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max30102.h	Tue Jun 21 09:43:15 2016 +0000
@@ -0,0 +1,150 @@
+/*
+ * Library for the Maxim MAX30102 pulse oximetry system, I modified a copy of the MAX30100 library in May 2016
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAX30102_H
+#define __MAX30102_H
+
+#include "mbed.h"
+
+
+/******************************************************************************/
+/*********** PULSE OXIMETER AND HEART RATE REGISTER MAPPING  **************/
+/******************************************************************************/
+
+// status registers
+#define MAX30102_INT_STATUS          0x00
+#define MAX30102_INT_ENABLE          0x02
+
+// FIFO registers
+#define MAX30102_FIFO_W_POINTER      0x04
+#define MAX30102_OVR_COUNTER         0x05
+#define MAX30102_FIFO_R_POINTER      0x06
+#define MAX30102_FIFO_DATA_REG       0x07
+
+// configuration registers
+#define MAX30102_FIFO_CONFIG         0x08
+#define MAX30102_CONFIG              0x09
+#define MAX30102_SPO2_CONFIG         0x0A
+#define MAX30102_LED_CONFIG_1        0x0C 
+#define MAX30102_LED_CONFIG_2        0x0D  
+
+// temperature registers
+#define MAX30102_TEMP_INTEGER        0x1F
+#define MAX30102_TEMP_FRACTION       0x20
+#define MAX30102_TEMP_CONFIG         0x21
+
+// PART ID registers
+#define MAX30102_REVISION_ID         0xFE
+#define MAX30102_PART_ID             0xFF
+
+#define I_AM_MAX30102                0x15
+
+/************************************** REGISTERS VALUE *******************************************/
+
+// I2C address
+#define MAX30102_ADDRESS             0xAE
+
+//Enable interrupts
+#define MAX30102_INT_ENB_A_FULL      ((uint8_t)0x80)
+#define MAX30102_INT_ENB_TEMP_RDY    ((uint8_t)0x40)
+#define MAX30102_INT_ENB_HR_RDY      ((uint8_t)0x20)
+#define MAX30102_INT_ENB_SO2_RDY     ((uint8_t)0x10)
+
+//Mode configuration
+#define MAX30102_MODE_SHDN           ((uint8_t)0x80)      // Bit 7 high
+#define MAX30102_MODE_RESET          ((uint8_t)0x40)      // Bit 6 high
+#define MAX30102_MODE_TEMP_EN        ((uint8_t)0x01)
+#define MAX30102_MODE_HR             ((uint8_t)0x02)
+#define MAX30102_MODE_SPO2           ((uint8_t)0x03)
+
+//SPO2 configuration
+#define MAX30102_SPO2_HI_RES_EN           ((uint8_t)0x40)
+
+typedef enum{ // This is the same for both LEDs
+    pw68,     // 68us pulse, ADC 15
+    pw118,    // 118us pulse, ADC 16
+    pw215,    // 215us pulse, ADC 17
+    pw411     // 411us pulse, ADC 18
+}pulseWidth;
+
+typedef enum{
+    sr50,    // 50 samples per second
+    sr100,   // 100 samples per second
+    sr200,   // 200 samples per second
+    sr400,   // 400 samples per second
+    sr800,   // 800 samples per second
+    sr1000   // 1000 samples per second
+}sampleRate;
+
+typedef enum{
+    i0,    // No current
+    i4,    // 4.4mA
+    i8,    // 7.6mA
+    i11,   // 11.0mA
+    i14,   // 14.2mA
+    i17,   // 17.4mA
+    i21,   // 20.8mA
+    i27,   // 27.1mA
+    i31,   // 30.6mA
+    i34,   // 33.8mA
+    i37,   // 37.0mA
+    i40,   // 40.2mA
+    i44,   // 43.6mA
+    i47,   // 46.8mA
+    i50    // 50.0mA
+}ledCurrent;
+
+typedef enum{
+    low,    // low resolution SPO2
+    high    // high resolution SPO2 (18 bit with 411us LED pulse width)
+}high_resolution;
+
+typedef enum
+{
+    OXIMETER_OK = 0,
+    OXIMETER_ERROR = 1,
+    OXIMETER_TIMEOUT = 2,
+    OXIMETER_NOT_IMPLEMENTED = 3
+} OXIMETER_StatusTypeDef;
+
+/**
+ * @brief  MAX30102 driver extended internal structure definition
+ */
+typedef struct
+{
+    OXIMETER_StatusTypeDef (*Enable_Free_Fall_Detection) (void);
+    OXIMETER_StatusTypeDef (*Disable_Free_Fall_Detection) (void);
+    OXIMETER_StatusTypeDef (*Get_Status_Free_Fall_Detection) (uint8_t *);
+} MAX30102_DrvExtTypeDef;
+
+class MAX30102 {
+public:
+        
+    /* Public Methods */
+    
+    uint32_t HR;      // Last heart rate datapoint
+    uint32_t SPO2;    // Last oximetry datapoint
+    
+    void  setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir);  // Sets the LED state
+    void  setSPO2(sampleRate sr, high_resolution hi_res); // Setup the SPO2 sensor, disabled by default
+    int   getNumSamp(void);       // Get number of samples
+    void  readSensor(void);       // Updates the values
+    void  shutdown(void);   // Instructs device to power-save
+    void  reset(void);      // Resets the device
+    void  startup(void);    // Leaves power-save
+    char  getRevID(void);   // Gets revision ID
+    char  getPartID(void);  // Gets part ID
+    void  begin(pulseWidth pw = pw411,  // Longest pulseWidth
+                ledCurrent ir = i50,    // Highest current
+                sampleRate sr = sr100); // 2nd lowest sampleRate
+    void  init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir);
+    void  setTemp(void);
+    int   readTemp(void);
+    void  setSPO2mode(void);
+    void  setInterruptSPO2(void);
+    void  printRegisters(void); // Dumps contents of registers for debug
+};
+
+#endif /* __MAX30102_H */
\ No newline at end of file