MAX30100 pulse and oximeter sensor library
Ported from Arduino library
max30100.cpp@0:0307ce7b7033, 2017-11-21 (annotated)
- Committer:
- kohlerba
- Date:
- Tue Nov 21 20:34:45 2017 +0000
- Revision:
- 0:0307ce7b7033
MAX30100 sensor
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kohlerba | 0:0307ce7b7033 | 1 | #include "max30100.h" |
kohlerba | 0:0307ce7b7033 | 2 | |
kohlerba | 0:0307ce7b7033 | 3 | //Set up I2C, (SDA,SCL) |
kohlerba | 0:0307ce7b7033 | 4 | static I2C i2c(I2C_SDA, I2C_SCL); |
kohlerba | 0:0307ce7b7033 | 5 | static Serial pc(USBTX, USBRX); // tx, rx |
kohlerba | 0:0307ce7b7033 | 6 | |
kohlerba | 0:0307ce7b7033 | 7 | uint16_t IR = 0; // Last IR reflectance datapoint |
kohlerba | 0:0307ce7b7033 | 8 | uint16_t RED = 0; // Last Red reflectance datapoint |
kohlerba | 0:0307ce7b7033 | 9 | |
kohlerba | 0:0307ce7b7033 | 10 | //Wire read and write protocols |
kohlerba | 0:0307ce7b7033 | 11 | int max30100::i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) |
kohlerba | 0:0307ce7b7033 | 12 | { |
kohlerba | 0:0307ce7b7033 | 13 | int ret; |
kohlerba | 0:0307ce7b7033 | 14 | char *tmp_buffer; |
kohlerba | 0:0307ce7b7033 | 15 | |
kohlerba | 0:0307ce7b7033 | 16 | tmp_buffer = (char*)malloc(sizeof(char)*(Nbyte+1)); |
kohlerba | 0:0307ce7b7033 | 17 | |
kohlerba | 0:0307ce7b7033 | 18 | /* First, send device address. Then, send data and STOP condition */ |
kohlerba | 0:0307ce7b7033 | 19 | tmp_buffer[0] = register_addr; |
kohlerba | 0:0307ce7b7033 | 20 | memcpy(tmp_buffer+1, buffer, Nbyte); |
kohlerba | 0:0307ce7b7033 | 21 | |
kohlerba | 0:0307ce7b7033 | 22 | ret = i2c.write(i2c_addr, tmp_buffer, Nbyte+1, false); |
kohlerba | 0:0307ce7b7033 | 23 | |
kohlerba | 0:0307ce7b7033 | 24 | return ret; |
kohlerba | 0:0307ce7b7033 | 25 | } |
kohlerba | 0:0307ce7b7033 | 26 | |
kohlerba | 0:0307ce7b7033 | 27 | int max30100::i2c_read (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) |
kohlerba | 0:0307ce7b7033 | 28 | { |
kohlerba | 0:0307ce7b7033 | 29 | int ret; |
kohlerba | 0:0307ce7b7033 | 30 | |
kohlerba | 0:0307ce7b7033 | 31 | /* Send device address, with no STOP condition */ |
kohlerba | 0:0307ce7b7033 | 32 | ret = i2c.write(i2c_addr, (const char*)®ister_addr, 1, true); |
kohlerba | 0:0307ce7b7033 | 33 | if(!ret) { |
kohlerba | 0:0307ce7b7033 | 34 | /* Read data, with STOP condition */ |
kohlerba | 0:0307ce7b7033 | 35 | ret = i2c.read((i2c_addr|0x01), buffer, Nbyte, false); |
kohlerba | 0:0307ce7b7033 | 36 | } |
kohlerba | 0:0307ce7b7033 | 37 | |
kohlerba | 0:0307ce7b7033 | 38 | return ret; |
kohlerba | 0:0307ce7b7033 | 39 | } |
kohlerba | 0:0307ce7b7033 | 40 | // |
kohlerba | 0:0307ce7b7033 | 41 | |
kohlerba | 0:0307ce7b7033 | 42 | void max30100::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ |
kohlerba | 0:0307ce7b7033 | 43 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 44 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 45 | reg[0] = reg[0] & 0xFC; // Set LED_PW to 00 |
kohlerba | 0:0307ce7b7033 | 46 | reg[0] = reg[0] | pw; |
kohlerba | 0:0307ce7b7033 | 47 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask LED_PW |
kohlerba | 0:0307ce7b7033 | 48 | reg[0] = (red<<4) | ir; |
kohlerba | 0:0307ce7b7033 | 49 | i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); // write LED configs |
kohlerba | 0:0307ce7b7033 | 50 | } |
kohlerba | 0:0307ce7b7033 | 51 | |
kohlerba | 0:0307ce7b7033 | 52 | void max30100::setSPO2(sampleRate sr){ |
kohlerba | 0:0307ce7b7033 | 53 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 54 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 55 | reg[0] = reg[0] & 0xE3; // Set SPO2_SR to 000 |
kohlerba | 0:0307ce7b7033 | 56 | reg[0] = reg[0] | (sr<<2); |
kohlerba | 0:0307ce7b7033 | 57 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask SPO2_SR |
kohlerba | 0:0307ce7b7033 | 58 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 59 | reg[0] = reg[0] & 0xf8; // Set Mode to 000 |
kohlerba | 0:0307ce7b7033 | 60 | reg[0] = reg[0] | 0x03; |
kohlerba | 0:0307ce7b7033 | 61 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask MODE |
kohlerba | 0:0307ce7b7033 | 62 | } |
kohlerba | 0:0307ce7b7033 | 63 | |
kohlerba | 0:0307ce7b7033 | 64 | int max30100::getNumSamp(void){ |
kohlerba | 0:0307ce7b7033 | 65 | char wrPtr[1]; |
kohlerba | 0:0307ce7b7033 | 66 | char rdPtr[1]; |
kohlerba | 0:0307ce7b7033 | 67 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, &wrPtr[0], 1); |
kohlerba | 0:0307ce7b7033 | 68 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, &rdPtr[0], 1); |
kohlerba | 0:0307ce7b7033 | 69 | return (abs( 16 + wrPtr[0] - rdPtr[0] ) % 16); |
kohlerba | 0:0307ce7b7033 | 70 | } |
kohlerba | 0:0307ce7b7033 | 71 | |
kohlerba | 0:0307ce7b7033 | 72 | void max30100::readSensor(void){ |
kohlerba | 0:0307ce7b7033 | 73 | char temp[4] = {0}; // Temporary buffer for read values |
kohlerba | 0:0307ce7b7033 | 74 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &temp[0], 4); // Read four times from the FIFO |
kohlerba | 0:0307ce7b7033 | 75 | IR = (temp[0]<<8) | temp[1]; // Combine values to get the actual number |
kohlerba | 0:0307ce7b7033 | 76 | RED = (temp[2]<<8) | temp[3]; // Combine values to get the actual number |
kohlerba | 0:0307ce7b7033 | 77 | } |
kohlerba | 0:0307ce7b7033 | 78 | |
kohlerba | 0:0307ce7b7033 | 79 | void max30100::shutdown(void){ |
kohlerba | 0:0307ce7b7033 | 80 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 81 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 0:0307ce7b7033 | 82 | reg[0] = reg[0] | 0x80; |
kohlerba | 0:0307ce7b7033 | 83 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit |
kohlerba | 0:0307ce7b7033 | 84 | } |
kohlerba | 0:0307ce7b7033 | 85 | |
kohlerba | 0:0307ce7b7033 | 86 | void max30100::reset(void){ |
kohlerba | 0:0307ce7b7033 | 87 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 88 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 0:0307ce7b7033 | 89 | reg[0] = reg[0] | 0x40; |
kohlerba | 0:0307ce7b7033 | 90 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the RESET bit |
kohlerba | 0:0307ce7b7033 | 91 | } |
kohlerba | 0:0307ce7b7033 | 92 | |
kohlerba | 0:0307ce7b7033 | 93 | void max30100::startup(void){ |
kohlerba | 0:0307ce7b7033 | 94 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 95 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 0:0307ce7b7033 | 96 | reg[0] = reg[0] & 0x7F; |
kohlerba | 0:0307ce7b7033 | 97 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit |
kohlerba | 0:0307ce7b7033 | 98 | } |
kohlerba | 0:0307ce7b7033 | 99 | |
kohlerba | 0:0307ce7b7033 | 100 | uint8_t max30100::getRevID(void){ |
kohlerba | 0:0307ce7b7033 | 101 | char buffer[1]; |
kohlerba | 0:0307ce7b7033 | 102 | i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, &buffer[0], 1); |
kohlerba | 0:0307ce7b7033 | 103 | return buffer[0]; |
kohlerba | 0:0307ce7b7033 | 104 | } |
kohlerba | 0:0307ce7b7033 | 105 | |
kohlerba | 0:0307ce7b7033 | 106 | uint8_t max30100::getPartID(void){ |
kohlerba | 0:0307ce7b7033 | 107 | char buffer[1]; |
kohlerba | 0:0307ce7b7033 | 108 | i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, &buffer[0], 1); |
kohlerba | 0:0307ce7b7033 | 109 | return buffer[0]; |
kohlerba | 0:0307ce7b7033 | 110 | } |
kohlerba | 0:0307ce7b7033 | 111 | |
kohlerba | 0:0307ce7b7033 | 112 | void max30100::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ |
kohlerba | 0:0307ce7b7033 | 113 | char buffer[1]; |
kohlerba | 0:0307ce7b7033 | 114 | buffer[0] = 0x02; |
kohlerba | 0:0307ce7b7033 | 115 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &buffer[0], 1); // Heart rate only |
kohlerba | 0:0307ce7b7033 | 116 | buffer[0] = ir; |
kohlerba | 0:0307ce7b7033 | 117 | i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &buffer[0], 1); |
kohlerba | 0:0307ce7b7033 | 118 | buffer[0] = (sr<<2)|pw; |
kohlerba | 0:0307ce7b7033 | 119 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &buffer[0], 1); |
kohlerba | 0:0307ce7b7033 | 120 | } |
kohlerba | 0:0307ce7b7033 | 121 | |
kohlerba | 0:0307ce7b7033 | 122 | void max30100::printRegisters(void){ |
kohlerba | 0:0307ce7b7033 | 123 | char reg[1]; |
kohlerba | 0:0307ce7b7033 | 124 | i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 125 | pc.printf("MAX30100_INT_STATUS: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 126 | i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 127 | pc.printf("MAX30100_INT_ENABLE: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 128 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 129 | pc.printf("MAX30100_FIFO_WR_PTR: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 130 | i2c_read(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 131 | pc.printf("MAX30100_OVRFLOW_CTR: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 132 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 133 | pc.printf("MAX30100_FIFO_RD_PTR: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 134 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 135 | pc.printf("MAX30100_FIFO_DATA: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 136 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 137 | pc.printf("MAX30100_MODE_CONFIG: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 138 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 139 | pc.printf("MAX30100_SPO2_CONFIG: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 140 | i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 141 | pc.printf("MAX30100_LED_CONFIG: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 142 | i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 143 | pc.printf("MAX30100_TEMP_INTG: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 144 | i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 145 | pc.printf("MAX30100_TEMP_FRAC: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 146 | i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 147 | pc.printf("MAX30100_REV_ID: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 148 | i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, ®[0], 1); |
kohlerba | 0:0307ce7b7033 | 149 | pc.printf("MAX30100_PART_ID: %d\r\n",reg[0]); |
kohlerba | 0:0307ce7b7033 | 150 | } |