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
Revision 1:02f411fefe6f, committed 2016-06-21
- 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
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