
none
max30102.cpp@1:02f411fefe6f, 2016-06-21 (annotated)
- Committer:
- Filea
- Date:
- Tue Jun 21 09:43:15 2016 +0000
- Revision:
- 1:02f411fefe6f
- Parent:
- max30100.cpp@0:e1e1947a9882
Modified the code from the library MAX30100 to work with MAX30102 pulse oximeter.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ajeje41 | 0:e1e1947a9882 | 1 | /* |
Filea | 1:02f411fefe6f | 2 | * Library for the Maxim MAX30102 pulse oximetry system, I modified a copy of the MAX30100 library in May 2016 |
ajeje41 | 0:e1e1947a9882 | 3 | */ |
ajeje41 | 0:e1e1947a9882 | 4 | |
Filea | 1:02f411fefe6f | 5 | #include "max30102.h" |
ajeje41 | 0:e1e1947a9882 | 6 | #include "functions.h" |
Filea | 1:02f411fefe6f | 7 | |
Filea | 1:02f411fefe6f | 8 | Serial pc(USBTX, USBRX); |
ajeje41 | 0:e1e1947a9882 | 9 | |
Filea | 1:02f411fefe6f | 10 | void MAX30102::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ |
ajeje41 | 0:e1e1947a9882 | 11 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 12 | char data_write[1]; |
Filea | 1:02f411fefe6f | 13 | i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); |
Filea | 1:02f411fefe6f | 14 | data_read[0] = data_read[0] & 0xFD; // Set LED_PW to 01 |
ajeje41 | 0:e1e1947a9882 | 15 | data_write[0] = data_read[0] | pw; |
Filea | 1:02f411fefe6f | 16 | i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); // Mask LED_PW |
Filea | 1:02f411fefe6f | 17 | data_write[0] = (red); |
Filea | 1:02f411fefe6f | 18 | i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1); // write LED1 configs |
Filea | 1:02f411fefe6f | 19 | data_write[0] = (ir); |
Filea | 1:02f411fefe6f | 20 | i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_write, 1); // write LED2 configs |
ajeje41 | 0:e1e1947a9882 | 21 | } |
ajeje41 | 0:e1e1947a9882 | 22 | |
Filea | 1:02f411fefe6f | 23 | void MAX30102::setSPO2(sampleRate sr, high_resolution hi_res){ |
ajeje41 | 0:e1e1947a9882 | 24 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 25 | char data_write[1]; |
Filea | 1:02f411fefe6f | 26 | i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); |
Filea | 1:02f411fefe6f | 27 | data_read[0] = data_read[0] & 0x85; // Set ADC_rge to 00, SPO2_SR to 001 = sr100 and LEDpw to 01 = 118 |
ajeje41 | 0:e1e1947a9882 | 28 | data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6); |
Filea | 1:02f411fefe6f | 29 | i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); // Mask SPO2_SR |
Filea | 1:02f411fefe6f | 30 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 31 | data_write[0] = data_read[0] & 0xF8; // Set Mode to 000 |
Filea | 1:02f411fefe6f | 32 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // Mask MODE |
ajeje41 | 0:e1e1947a9882 | 33 | } |
ajeje41 | 0:e1e1947a9882 | 34 | |
Filea | 1:02f411fefe6f | 35 | void MAX30102::setInterruptSPO2(void){ |
ajeje41 | 0:e1e1947a9882 | 36 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 37 | char data_write[1]; |
Filea | 1:02f411fefe6f | 38 | i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1); |
Filea | 1:02f411fefe6f | 39 | data_write[0] = data_read[0] & 0x00; // Set Interrupt enable for SPO2 | 0x10 // New: disable prox! & ~0x10 |
Filea | 1:02f411fefe6f | 40 | i2c_write(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_write, 1); // Mask ENB_SPO2_RDY |
Filea | 1:02f411fefe6f | 41 | } |
ajeje41 | 0:e1e1947a9882 | 42 | |
Filea | 1:02f411fefe6f | 43 | int MAX30102::getNumSamp(void){ |
Filea | 1:02f411fefe6f | 44 | char data_read[1] = {0}; |
Filea | 1:02f411fefe6f | 45 | // i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); |
Filea | 1:02f411fefe6f | 46 | // i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); |
Filea | 1:02f411fefe6f | 47 | // wait(0.148); |
Filea | 1:02f411fefe6f | 48 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 49 | char wrPtr = data_read[0]; |
Filea | 1:02f411fefe6f | 50 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 51 | char rdPtr = data_read[0]; |
Filea | 1:02f411fefe6f | 52 | return ((int)wrPtr - (int)rdPtr); // New counting |
Filea | 1:02f411fefe6f | 53 | // return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16); |
ajeje41 | 0:e1e1947a9882 | 54 | } |
ajeje41 | 0:e1e1947a9882 | 55 | |
Filea | 1:02f411fefe6f | 56 | void MAX30102::setTemp(void){ |
ajeje41 | 0:e1e1947a9882 | 57 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 58 | char data_write[1]; |
Filea | 1:02f411fefe6f | 59 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); |
Filea | 1:02f411fefe6f | 60 | data_write[0] = data_read[0] | 0x01; // Enable temperature |
Filea | 1:02f411fefe6f | 61 | i2c_write(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_write, 1); // Mask MODE |
Filea | 1:02f411fefe6f | 62 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 63 | } |
ajeje41 | 0:e1e1947a9882 | 64 | |
Filea | 1:02f411fefe6f | 65 | void MAX30102::setSPO2mode(void){ |
ajeje41 | 0:e1e1947a9882 | 66 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 67 | char data_write[1]; |
Filea | 1:02f411fefe6f | 68 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 69 | data_write[0] = data_read[0] | 0x03; // Set SPO2 Mode |
Filea | 1:02f411fefe6f | 70 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); |
ajeje41 | 0:e1e1947a9882 | 71 | } |
ajeje41 | 0:e1e1947a9882 | 72 | |
Filea | 1:02f411fefe6f | 73 | int MAX30102::readTemp(void){ |
ajeje41 | 0:e1e1947a9882 | 74 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 75 | char temp_int, temp_fract; |
ajeje41 | 0:e1e1947a9882 | 76 | int temp_measured; |
Filea | 1:02f411fefe6f | 77 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 78 | temp_int = data_read[0]; |
Filea | 1:02f411fefe6f | 79 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 80 | temp_fract = data_read[0] & 0x0F; |
ajeje41 | 0:e1e1947a9882 | 81 | temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4); |
ajeje41 | 0:e1e1947a9882 | 82 | return temp_measured; |
ajeje41 | 0:e1e1947a9882 | 83 | } |
ajeje41 | 0:e1e1947a9882 | 84 | |
Filea | 1:02f411fefe6f | 85 | void MAX30102::readSensor(void){ |
Filea | 1:02f411fefe6f | 86 | char data_read[6] = {0}; |
Filea | 1:02f411fefe6f | 87 | HR = 0; |
Filea | 1:02f411fefe6f | 88 | SPO2 = 0; |
Filea | 1:02f411fefe6f | 89 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 6); // Read six times from the FIFO |
Filea | 1:02f411fefe6f | 90 | HR = (data_read[0]<<16) | (data_read[1]<<8) | data_read[2]; // Combine values to get the actual number |
Filea | 1:02f411fefe6f | 91 | HR = HR>>2; |
Filea | 1:02f411fefe6f | 92 | SPO2 = (data_read[3]<<16) | (data_read[4]<<8) | data_read[5]; // Combine values to get the actual number |
Filea | 1:02f411fefe6f | 93 | SPO2 = SPO2>>2; |
ajeje41 | 0:e1e1947a9882 | 94 | } |
ajeje41 | 0:e1e1947a9882 | 95 | |
Filea | 1:02f411fefe6f | 96 | void MAX30102::shutdown(void){ |
ajeje41 | 0:e1e1947a9882 | 97 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 98 | char data_write[1]; |
Filea | 1:02f411fefe6f | 99 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register |
ajeje41 | 0:e1e1947a9882 | 100 | data_write[0] = data_read[0] | 0x80; |
Filea | 1:02f411fefe6f | 101 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the SHDN bit |
ajeje41 | 0:e1e1947a9882 | 102 | } |
ajeje41 | 0:e1e1947a9882 | 103 | |
Filea | 1:02f411fefe6f | 104 | void MAX30102::reset(void){ |
ajeje41 | 0:e1e1947a9882 | 105 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 106 | char data_write[1]; |
Filea | 1:02f411fefe6f | 107 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register |
ajeje41 | 0:e1e1947a9882 | 108 | data_write[0] = data_read[0] | 0x40; |
Filea | 1:02f411fefe6f | 109 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the RESET bit |
ajeje41 | 0:e1e1947a9882 | 110 | } |
ajeje41 | 0:e1e1947a9882 | 111 | |
Filea | 1:02f411fefe6f | 112 | void MAX30102::startup(void){ |
ajeje41 | 0:e1e1947a9882 | 113 | char data_read[1]; |
ajeje41 | 0:e1e1947a9882 | 114 | char data_write[1]; |
Filea | 1:02f411fefe6f | 115 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register |
ajeje41 | 0:e1e1947a9882 | 116 | data_write[0] = data_read[0] & 0x7F; |
Filea | 1:02f411fefe6f | 117 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the SHDN bit |
ajeje41 | 0:e1e1947a9882 | 118 | } |
ajeje41 | 0:e1e1947a9882 | 119 | |
Filea | 1:02f411fefe6f | 120 | char MAX30102::getRevID(void){ |
ajeje41 | 0:e1e1947a9882 | 121 | char data_read[1]; |
Filea | 1:02f411fefe6f | 122 | i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 123 | return data_read[0]; |
ajeje41 | 0:e1e1947a9882 | 124 | } |
ajeje41 | 0:e1e1947a9882 | 125 | |
Filea | 1:02f411fefe6f | 126 | char MAX30102::getPartID(void){ |
ajeje41 | 0:e1e1947a9882 | 127 | char data_read[1]; |
Filea | 1:02f411fefe6f | 128 | i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 129 | return data_read[0]; |
ajeje41 | 0:e1e1947a9882 | 130 | } |
ajeje41 | 0:e1e1947a9882 | 131 | |
Filea | 1:02f411fefe6f | 132 | void MAX30102::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ |
ajeje41 | 0:e1e1947a9882 | 133 | char data_write[1]; |
Filea | 1:02f411fefe6f | 134 | data_write[0] = 0x02; |
Filea | 1:02f411fefe6f | 135 | i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // Heart rate only |
ajeje41 | 0:e1e1947a9882 | 136 | data_write[0] = ir; |
Filea | 1:02f411fefe6f | 137 | i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1); |
ajeje41 | 0:e1e1947a9882 | 138 | data_write[0] = ((sr<<2)|pw); |
Filea | 1:02f411fefe6f | 139 | i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); |
ajeje41 | 0:e1e1947a9882 | 140 | } |
ajeje41 | 0:e1e1947a9882 | 141 | |
Filea | 1:02f411fefe6f | 142 | void MAX30102::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){ |
Filea | 1:02f411fefe6f | 143 | char data_write[1]; |
ajeje41 | 0:e1e1947a9882 | 144 | |
ajeje41 | 0:e1e1947a9882 | 145 | setLEDs(pw, red, ir); |
ajeje41 | 0:e1e1947a9882 | 146 | setSPO2(sr, hi_res); |
ajeje41 | 0:e1e1947a9882 | 147 | |
Filea | 1:02f411fefe6f | 148 | data_write[0] = 0x10; |
Filea | 1:02f411fefe6f | 149 | i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_CONFIG, data_write, 1); |
Filea | 1:02f411fefe6f | 150 | |
ajeje41 | 0:e1e1947a9882 | 151 | } |
ajeje41 | 0:e1e1947a9882 | 152 | |
Filea | 1:02f411fefe6f | 153 | void MAX30102::printRegisters(void){ |
ajeje41 | 0:e1e1947a9882 | 154 | char data_read[1]; |
Filea | 1:02f411fefe6f | 155 | i2c_read(MAX30102_ADDRESS, MAX30102_INT_STATUS, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 156 | pc.printf("INT_STATUS: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 157 | i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 158 | pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 159 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 160 | pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 161 | i2c_read(MAX30102_ADDRESS, MAX30102_OVR_COUNTER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 162 | pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 163 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 164 | pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 165 | i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 166 | pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 167 | i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 168 | pc.printf("CONFIG: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 169 | i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 170 | pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 171 | i2c_read(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 172 | pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 173 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 174 | pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 175 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 176 | pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 177 | i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); |
Filea | 1:02f411fefe6f | 178 | pc.printf("TEMP_CONFIG: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 179 | i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 180 | pc.printf("REVISION_ID: %#4X\r\n", data_read[0]); |
Filea | 1:02f411fefe6f | 181 | i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1); |
ajeje41 | 0:e1e1947a9882 | 182 | pc.printf("PART_ID: %#4X\r\n", data_read[0]); |
ajeje41 | 0:e1e1947a9882 | 183 | } |