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

Committer:
ajeje41
Date:
Sun Apr 03 13:43:19 2016 +0000
Revision:
0:e1e1947a9882
StepOne (store accelerometer value)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajeje41 0:e1e1947a9882 1 /*
ajeje41 0:e1e1947a9882 2 Library for the Maxim MAX30100 pulse oximetry system
ajeje41 0:e1e1947a9882 3 */
ajeje41 0:e1e1947a9882 4
ajeje41 0:e1e1947a9882 5 #include "max30100.h"
ajeje41 0:e1e1947a9882 6 #include "functions.h"
ajeje41 0:e1e1947a9882 7
ajeje41 0:e1e1947a9882 8 static Serial pc(SERIAL_TX, SERIAL_RX);
ajeje41 0:e1e1947a9882 9
ajeje41 0:e1e1947a9882 10 void MAX30100::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){
ajeje41 0:e1e1947a9882 11 char data_read[1];
ajeje41 0:e1e1947a9882 12 char data_write[1];
ajeje41 0:e1e1947a9882 13 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 14 data_read[0] = data_read[0] & 0xFC; // Set LED_PW to 00
ajeje41 0:e1e1947a9882 15 data_write[0] = data_read[0] | pw;
ajeje41 0:e1e1947a9882 16 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); // Mask LED_PW
ajeje41 0:e1e1947a9882 17 data_write[0] = ((red<<4) | ir);
ajeje41 0:e1e1947a9882 18 i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1); // write LED configs
ajeje41 0:e1e1947a9882 19 }
ajeje41 0:e1e1947a9882 20
ajeje41 0:e1e1947a9882 21 void MAX30100::setSPO2(sampleRate sr, high_resolution hi_res){
ajeje41 0:e1e1947a9882 22 char data_read[1];
ajeje41 0:e1e1947a9882 23 char data_write[1];
ajeje41 0:e1e1947a9882 24 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 25 data_read[0] = data_read[0] & 0xA3; // Set SPO2_SR to 000 and SPO2_HI_RES_EN to 0
ajeje41 0:e1e1947a9882 26 data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6);
ajeje41 0:e1e1947a9882 27 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); // Mask SPO2_SR
ajeje41 0:e1e1947a9882 28 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 29 data_write[0] = data_read[0] & 0xF8; // Set Mode to 000
ajeje41 0:e1e1947a9882 30 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE
ajeje41 0:e1e1947a9882 31 }
ajeje41 0:e1e1947a9882 32
ajeje41 0:e1e1947a9882 33 void MAX30100::setInterruptSPO2(void){
ajeje41 0:e1e1947a9882 34 char data_read[1];
ajeje41 0:e1e1947a9882 35 char data_write[1];
ajeje41 0:e1e1947a9882 36 i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1);
ajeje41 0:e1e1947a9882 37 data_write[0] = data_read[0] | 0x10; // Set Interrupt enable for SPO2
ajeje41 0:e1e1947a9882 38 i2c_write(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_write, 1); // Mask ENB_SPO2_RDY
ajeje41 0:e1e1947a9882 39 }
ajeje41 0:e1e1947a9882 40
ajeje41 0:e1e1947a9882 41 int MAX30100::getNumSamp(void){
ajeje41 0:e1e1947a9882 42 char data_read[1];
ajeje41 0:e1e1947a9882 43 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1);
ajeje41 0:e1e1947a9882 44 char wrPtr = data_read[0];
ajeje41 0:e1e1947a9882 45 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1);
ajeje41 0:e1e1947a9882 46 char rdPtr = data_read[0];
ajeje41 0:e1e1947a9882 47 return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16);
ajeje41 0:e1e1947a9882 48 }
ajeje41 0:e1e1947a9882 49
ajeje41 0:e1e1947a9882 50 void MAX30100::setTemp(void){
ajeje41 0:e1e1947a9882 51 char data_read[1];
ajeje41 0:e1e1947a9882 52 char data_write[1];
ajeje41 0:e1e1947a9882 53 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 54 data_write[0] = data_read[0] | 0x0B; // Set SPO2 Mode and enable temperature
ajeje41 0:e1e1947a9882 55 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE
ajeje41 0:e1e1947a9882 56 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 57 }
ajeje41 0:e1e1947a9882 58
ajeje41 0:e1e1947a9882 59 void MAX30100::setSPO2mode(void){
ajeje41 0:e1e1947a9882 60 char data_read[1];
ajeje41 0:e1e1947a9882 61 char data_write[1];
ajeje41 0:e1e1947a9882 62 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 63 data_write[0] = data_read[0] | 0x03; // Set SPO2 Mode
ajeje41 0:e1e1947a9882 64 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1);
ajeje41 0:e1e1947a9882 65 }
ajeje41 0:e1e1947a9882 66
ajeje41 0:e1e1947a9882 67 int MAX30100::readTemp(void){
ajeje41 0:e1e1947a9882 68 char data_read[1];
ajeje41 0:e1e1947a9882 69 char temp_int, temp_fract;
ajeje41 0:e1e1947a9882 70 int temp_measured;
ajeje41 0:e1e1947a9882 71 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1);
ajeje41 0:e1e1947a9882 72 temp_int = data_read[0];
ajeje41 0:e1e1947a9882 73 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1);
ajeje41 0:e1e1947a9882 74 temp_fract = data_read[0] & 0x0F;
ajeje41 0:e1e1947a9882 75 temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4);
ajeje41 0:e1e1947a9882 76 return temp_measured;
ajeje41 0:e1e1947a9882 77 }
ajeje41 0:e1e1947a9882 78
ajeje41 0:e1e1947a9882 79 void MAX30100::readSensor(void){
ajeje41 0:e1e1947a9882 80 char data_read[4];
ajeje41 0:e1e1947a9882 81 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 4); // Read four times from the FIFO
ajeje41 0:e1e1947a9882 82 HR = (data_read[0]<<8) | data_read[1]; // Combine values to get the actual number
ajeje41 0:e1e1947a9882 83 SPO2 = (data_read[2]<<8) | data_read[3]; // Combine values to get the actual number
ajeje41 0:e1e1947a9882 84 }
ajeje41 0:e1e1947a9882 85
ajeje41 0:e1e1947a9882 86 void MAX30100::shutdown(void){
ajeje41 0:e1e1947a9882 87 char data_read[1];
ajeje41 0:e1e1947a9882 88 char data_write[1];
ajeje41 0:e1e1947a9882 89 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register
ajeje41 0:e1e1947a9882 90 data_write[0] = data_read[0] | 0x80;
ajeje41 0:e1e1947a9882 91 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the SHDN bit
ajeje41 0:e1e1947a9882 92 }
ajeje41 0:e1e1947a9882 93
ajeje41 0:e1e1947a9882 94 void MAX30100::reset(void){
ajeje41 0:e1e1947a9882 95 char data_read[1];
ajeje41 0:e1e1947a9882 96 char data_write[1];
ajeje41 0:e1e1947a9882 97 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register
ajeje41 0:e1e1947a9882 98 data_write[0] = data_read[0] | 0x40;
ajeje41 0:e1e1947a9882 99 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the RESET bit
ajeje41 0:e1e1947a9882 100 }
ajeje41 0:e1e1947a9882 101
ajeje41 0:e1e1947a9882 102 void MAX30100::startup(void){
ajeje41 0:e1e1947a9882 103 char data_read[1];
ajeje41 0:e1e1947a9882 104 char data_write[1];
ajeje41 0:e1e1947a9882 105 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register
ajeje41 0:e1e1947a9882 106 data_write[0] = data_read[0] & 0x7F;
ajeje41 0:e1e1947a9882 107 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the SHDN bit
ajeje41 0:e1e1947a9882 108 }
ajeje41 0:e1e1947a9882 109
ajeje41 0:e1e1947a9882 110 char MAX30100::getRevID(void){
ajeje41 0:e1e1947a9882 111 char data_read[1];
ajeje41 0:e1e1947a9882 112 i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1);
ajeje41 0:e1e1947a9882 113 return data_read[0];
ajeje41 0:e1e1947a9882 114 }
ajeje41 0:e1e1947a9882 115
ajeje41 0:e1e1947a9882 116 char MAX30100::getPartID(void){
ajeje41 0:e1e1947a9882 117 char data_read[1];
ajeje41 0:e1e1947a9882 118 i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1);
ajeje41 0:e1e1947a9882 119 return data_read[0];
ajeje41 0:e1e1947a9882 120 }
ajeje41 0:e1e1947a9882 121
ajeje41 0:e1e1947a9882 122 void MAX30100::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){
ajeje41 0:e1e1947a9882 123 char data_write[1];
ajeje41 0:e1e1947a9882 124 data_write[0] = 0x03;
ajeje41 0:e1e1947a9882 125 i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Heart rate only
ajeje41 0:e1e1947a9882 126 data_write[0] = ir;
ajeje41 0:e1e1947a9882 127 i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1);
ajeje41 0:e1e1947a9882 128 data_write[0] = ((sr<<2)|pw);
ajeje41 0:e1e1947a9882 129 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1);
ajeje41 0:e1e1947a9882 130 }
ajeje41 0:e1e1947a9882 131
ajeje41 0:e1e1947a9882 132 void MAX30100::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){
ajeje41 0:e1e1947a9882 133
ajeje41 0:e1e1947a9882 134 setLEDs(pw, red, ir);
ajeje41 0:e1e1947a9882 135 setSPO2(sr, hi_res);
ajeje41 0:e1e1947a9882 136
ajeje41 0:e1e1947a9882 137 }
ajeje41 0:e1e1947a9882 138
ajeje41 0:e1e1947a9882 139 void MAX30100::printRegisters(void){
ajeje41 0:e1e1947a9882 140 char data_read[1];
ajeje41 0:e1e1947a9882 141 i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, data_read, 1);
ajeje41 0:e1e1947a9882 142 pc.printf("INT_STATUS: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 143 i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1);
ajeje41 0:e1e1947a9882 144 pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 145 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1);
ajeje41 0:e1e1947a9882 146 pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 147 i2c_read(MAX30100_ADDRESS, MAX30100_OVR_COUNTER, data_read, 1);
ajeje41 0:e1e1947a9882 148 pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 149 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1);
ajeje41 0:e1e1947a9882 150 pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 151 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 1);
ajeje41 0:e1e1947a9882 152 pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 153 i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 154 pc.printf("CONFIG: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 155 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 156 pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 157 i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_read, 1);
ajeje41 0:e1e1947a9882 158 pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 159 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1);
ajeje41 0:e1e1947a9882 160 pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 161 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1);
ajeje41 0:e1e1947a9882 162 pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 163 i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1);
ajeje41 0:e1e1947a9882 164 pc.printf("REVISION_ID: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 165 i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1);
ajeje41 0:e1e1947a9882 166 pc.printf("PART_ID: %#4X\r\n", data_read[0]);
ajeje41 0:e1e1947a9882 167 }