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
Diff: max30102.cpp
- Revision:
- 1:02f411fefe6f
- Parent:
- 0:e1e1947a9882
--- /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]); +}