Bradley Kohler
/
PulseRate
MAX30100 pulse rate sensor
MAX30100.h@3:fa37b0c705b3, 2017-11-26 (annotated)
- Committer:
- kohlerba
- Date:
- Sun Nov 26 21:56:10 2017 +0000
- Revision:
- 3:fa37b0c705b3
- Parent:
- 2:d329886938f1
- Child:
- 4:008e40a7d035
PulseRate example using serial COM
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kohlerba | 0:faf977308bdc | 1 | #ifndef MAX30100_H |
kohlerba | 0:faf977308bdc | 2 | #define MAX30100_H |
kohlerba | 0:faf977308bdc | 3 | |
kohlerba | 0:faf977308bdc | 4 | #include "mbed.h" |
kohlerba | 0:faf977308bdc | 5 | |
kohlerba | 0:faf977308bdc | 6 | //definitions |
kohlerba | 3:fa37b0c705b3 | 7 | #define MAX30100_ADDRESS 0xAE |
kohlerba | 0:faf977308bdc | 8 | |
kohlerba | 0:faf977308bdc | 9 | // Registers |
kohlerba | 0:faf977308bdc | 10 | #define MAX30100_INT_STATUS 0x00 // Which interrupts are tripped |
kohlerba | 0:faf977308bdc | 11 | #define MAX30100_INT_ENABLE 0x01 // Which interrupts are active |
kohlerba | 0:faf977308bdc | 12 | #define MAX30100_FIFO_WR_PTR 0x02 // Where data is being written |
kohlerba | 0:faf977308bdc | 13 | #define MAX30100_OVRFLOW_CTR 0x03 // Number of lost samples |
kohlerba | 0:faf977308bdc | 14 | #define MAX30100_FIFO_RD_PTR 0x04 // Where to read from |
kohlerba | 0:faf977308bdc | 15 | #define MAX30100_FIFO_DATA 0x05 // Ouput data buffer |
kohlerba | 0:faf977308bdc | 16 | #define MAX30100_MODE_CONFIG 0x06 // Control register |
kohlerba | 0:faf977308bdc | 17 | #define MAX30100_SPO2_CONFIG 0x07 // Oximetry settings |
kohlerba | 0:faf977308bdc | 18 | #define MAX30100_LED_CONFIG 0x09 // Pulse width and power of LEDs |
kohlerba | 0:faf977308bdc | 19 | #define MAX30100_TEMP_INTG 0x16 // Temperature value, whole number |
kohlerba | 0:faf977308bdc | 20 | #define MAX30100_TEMP_FRAC 0x17 // Temperature value, fraction |
kohlerba | 0:faf977308bdc | 21 | #define MAX30100_REV_ID 0xFE // Part revision |
kohlerba | 0:faf977308bdc | 22 | #define MAX30100_PART_ID 0xFF // Part ID, normally 0x11 |
kohlerba | 0:faf977308bdc | 23 | |
kohlerba | 2:d329886938f1 | 24 | #define POR_PART_ID 0x11 |
kohlerba | 2:d329886938f1 | 25 | |
kohlerba | 0:faf977308bdc | 26 | typedef enum{ // This is the same for both LEDs |
kohlerba | 0:faf977308bdc | 27 | pw200, // 200us pulse |
kohlerba | 0:faf977308bdc | 28 | pw400, // 400us pulse |
kohlerba | 0:faf977308bdc | 29 | pw800, // 800us pulse |
kohlerba | 0:faf977308bdc | 30 | pw1600 // 1600us pulse |
kohlerba | 0:faf977308bdc | 31 | }pulseWidth; |
kohlerba | 0:faf977308bdc | 32 | |
kohlerba | 0:faf977308bdc | 33 | typedef enum{ |
kohlerba | 0:faf977308bdc | 34 | sr50, // 50 samples per second |
kohlerba | 0:faf977308bdc | 35 | sr100, // 100 samples per second |
kohlerba | 0:faf977308bdc | 36 | sr167, // 167 samples per second |
kohlerba | 0:faf977308bdc | 37 | sr200, // 200 samples per second |
kohlerba | 0:faf977308bdc | 38 | sr400, // 400 samples per second |
kohlerba | 0:faf977308bdc | 39 | sr600, // 600 samples per second |
kohlerba | 0:faf977308bdc | 40 | sr800, // 800 samples per second |
kohlerba | 0:faf977308bdc | 41 | sr1000 // 1000 samples per second |
kohlerba | 0:faf977308bdc | 42 | }sampleRate; |
kohlerba | 0:faf977308bdc | 43 | |
kohlerba | 0:faf977308bdc | 44 | typedef enum{ |
kohlerba | 0:faf977308bdc | 45 | i0, // No current |
kohlerba | 0:faf977308bdc | 46 | i4, // 4.4mA |
kohlerba | 0:faf977308bdc | 47 | i8, // 7.6mA |
kohlerba | 0:faf977308bdc | 48 | i11, // 11.0mA |
kohlerba | 0:faf977308bdc | 49 | i14, // 14.2mA |
kohlerba | 0:faf977308bdc | 50 | i17, // 17.4mA |
kohlerba | 0:faf977308bdc | 51 | i21, // 20.8mA |
kohlerba | 0:faf977308bdc | 52 | i27, // 27.1mA |
kohlerba | 0:faf977308bdc | 53 | i31, // 30.6mA |
kohlerba | 0:faf977308bdc | 54 | i34, // 33.8mA |
kohlerba | 0:faf977308bdc | 55 | i37, // 37.0mA |
kohlerba | 0:faf977308bdc | 56 | i40, // 40.2mA |
kohlerba | 0:faf977308bdc | 57 | i44, // 43.6mA |
kohlerba | 0:faf977308bdc | 58 | i47, // 46.8mA |
kohlerba | 0:faf977308bdc | 59 | i50 // 50.0mA |
kohlerba | 0:faf977308bdc | 60 | }ledCurrent; |
kohlerba | 0:faf977308bdc | 61 | |
kohlerba | 0:faf977308bdc | 62 | //Set up I2C, (SDA,SCL) |
kohlerba | 3:fa37b0c705b3 | 63 | static I2C i2c(I2C_SDA, I2C_SCL); |
kohlerba | 3:fa37b0c705b3 | 64 | static Serial pc(USBTX, USBRX); // tx, rx |
kohlerba | 0:faf977308bdc | 65 | |
kohlerba | 0:faf977308bdc | 66 | uint16_t IR = 0; // Last IR reflectance datapoint |
kohlerba | 0:faf977308bdc | 67 | uint16_t RED = 0; // Last Red reflectance datapoint |
kohlerba | 0:faf977308bdc | 68 | |
kohlerba | 0:faf977308bdc | 69 | class MAX30100 { |
kohlerba | 0:faf977308bdc | 70 | |
kohlerba | 0:faf977308bdc | 71 | protected: |
kohlerba | 0:faf977308bdc | 72 | |
kohlerba | 0:faf977308bdc | 73 | public: |
kohlerba | 0:faf977308bdc | 74 | |
kohlerba | 2:d329886938f1 | 75 | //Wire read and write protocols |
kohlerba | 3:fa37b0c705b3 | 76 | static int i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) |
kohlerba | 0:faf977308bdc | 77 | { |
kohlerba | 3:fa37b0c705b3 | 78 | int ret; |
kohlerba | 3:fa37b0c705b3 | 79 | char *tmp_buffer; |
kohlerba | 3:fa37b0c705b3 | 80 | |
kohlerba | 3:fa37b0c705b3 | 81 | tmp_buffer = (char*)malloc(sizeof(char)*(Nbyte+1)); |
kohlerba | 0:faf977308bdc | 82 | |
kohlerba | 3:fa37b0c705b3 | 83 | /* First, send device address. Then, send data and STOP condition */ |
kohlerba | 3:fa37b0c705b3 | 84 | tmp_buffer[0] = register_addr; |
kohlerba | 3:fa37b0c705b3 | 85 | memcpy(tmp_buffer+1, buffer, Nbyte); |
kohlerba | 3:fa37b0c705b3 | 86 | |
kohlerba | 3:fa37b0c705b3 | 87 | ret = i2c.write(i2c_addr, tmp_buffer, Nbyte+1, false); |
kohlerba | 3:fa37b0c705b3 | 88 | |
kohlerba | 3:fa37b0c705b3 | 89 | return ret; |
kohlerba | 0:faf977308bdc | 90 | } |
kohlerba | 0:faf977308bdc | 91 | |
kohlerba | 3:fa37b0c705b3 | 92 | static int i2c_read (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) |
kohlerba | 3:fa37b0c705b3 | 93 | { |
kohlerba | 3:fa37b0c705b3 | 94 | int ret; |
kohlerba | 3:fa37b0c705b3 | 95 | |
kohlerba | 3:fa37b0c705b3 | 96 | /* Send device address, with no STOP condition */ |
kohlerba | 3:fa37b0c705b3 | 97 | ret = i2c.write(i2c_addr, (const char*)®ister_addr, 1, true); |
kohlerba | 3:fa37b0c705b3 | 98 | if(!ret) { |
kohlerba | 3:fa37b0c705b3 | 99 | /* Read data, with STOP condition */ |
kohlerba | 3:fa37b0c705b3 | 100 | ret = i2c.read((i2c_addr|0x01), buffer, Nbyte, false); |
kohlerba | 0:faf977308bdc | 101 | } |
kohlerba | 3:fa37b0c705b3 | 102 | |
kohlerba | 3:fa37b0c705b3 | 103 | return ret; |
kohlerba | 0:faf977308bdc | 104 | } |
kohlerba | 2:d329886938f1 | 105 | // |
kohlerba | 3:fa37b0c705b3 | 106 | |
kohlerba | 0:faf977308bdc | 107 | void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ |
kohlerba | 3:fa37b0c705b3 | 108 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 109 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 110 | reg[0] = reg[0] & 0xFC; // Set LED_PW to 00 |
kohlerba | 3:fa37b0c705b3 | 111 | reg[0] = reg[0] | pw; |
kohlerba | 3:fa37b0c705b3 | 112 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask LED_PW |
kohlerba | 3:fa37b0c705b3 | 113 | reg[0] = (red<<4) | ir; |
kohlerba | 3:fa37b0c705b3 | 114 | i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); // write LED configs |
kohlerba | 0:faf977308bdc | 115 | } |
kohlerba | 0:faf977308bdc | 116 | |
kohlerba | 0:faf977308bdc | 117 | void setSPO2(sampleRate sr){ |
kohlerba | 3:fa37b0c705b3 | 118 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 119 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 120 | reg[0] = reg[0] & 0xE3; // Set SPO2_SR to 000 |
kohlerba | 3:fa37b0c705b3 | 121 | reg[0] = reg[0] | (sr<<2); |
kohlerba | 3:fa37b0c705b3 | 122 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask SPO2_SR |
kohlerba | 3:fa37b0c705b3 | 123 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 124 | reg[0] = reg[0] & 0xf8; // Set Mode to 000 |
kohlerba | 3:fa37b0c705b3 | 125 | reg[0] = reg[0] | 0x03; |
kohlerba | 3:fa37b0c705b3 | 126 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask MODE |
kohlerba | 0:faf977308bdc | 127 | } |
kohlerba | 0:faf977308bdc | 128 | |
kohlerba | 0:faf977308bdc | 129 | int getNumSamp(void){ |
kohlerba | 3:fa37b0c705b3 | 130 | char wrPtr[1]; |
kohlerba | 3:fa37b0c705b3 | 131 | char rdPtr[1]; |
kohlerba | 3:fa37b0c705b3 | 132 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, &wrPtr[0], 1); |
kohlerba | 3:fa37b0c705b3 | 133 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, &rdPtr[0], 1); |
kohlerba | 3:fa37b0c705b3 | 134 | return (abs( 16 + wrPtr[0] - rdPtr[0] ) % 16); |
kohlerba | 0:faf977308bdc | 135 | } |
kohlerba | 0:faf977308bdc | 136 | |
kohlerba | 0:faf977308bdc | 137 | void readSensor(void){ |
kohlerba | 3:fa37b0c705b3 | 138 | char temp[4] = {0}; // Temporary buffer for read values |
kohlerba | 3:fa37b0c705b3 | 139 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &temp[0], 4); // Read four times from the FIFO |
kohlerba | 0:faf977308bdc | 140 | IR = (temp[0]<<8) | temp[1]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 141 | RED = (temp[2]<<8) | temp[3]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 142 | } |
kohlerba | 0:faf977308bdc | 143 | |
kohlerba | 0:faf977308bdc | 144 | void shutdown(void){ |
kohlerba | 3:fa37b0c705b3 | 145 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 146 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 3:fa37b0c705b3 | 147 | reg[0] = reg[0] | 0x80; |
kohlerba | 3:fa37b0c705b3 | 148 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 149 | } |
kohlerba | 0:faf977308bdc | 150 | |
kohlerba | 0:faf977308bdc | 151 | void reset(void){ |
kohlerba | 3:fa37b0c705b3 | 152 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 153 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 3:fa37b0c705b3 | 154 | reg[0] = reg[0] | 0x40; |
kohlerba | 3:fa37b0c705b3 | 155 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the RESET bit |
kohlerba | 0:faf977308bdc | 156 | } |
kohlerba | 0:faf977308bdc | 157 | |
kohlerba | 0:faf977308bdc | 158 | void startup(void){ |
kohlerba | 3:fa37b0c705b3 | 159 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 160 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register |
kohlerba | 3:fa37b0c705b3 | 161 | reg[0] = reg[0] & 0x7F; |
kohlerba | 3:fa37b0c705b3 | 162 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 163 | } |
kohlerba | 0:faf977308bdc | 164 | |
kohlerba | 3:fa37b0c705b3 | 165 | uint8_t getRevID(void){ |
kohlerba | 3:fa37b0c705b3 | 166 | char buffer[1]; |
kohlerba | 3:fa37b0c705b3 | 167 | i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, &buffer[0], 1); |
kohlerba | 3:fa37b0c705b3 | 168 | return buffer[0]; |
kohlerba | 0:faf977308bdc | 169 | } |
kohlerba | 0:faf977308bdc | 170 | |
kohlerba | 3:fa37b0c705b3 | 171 | uint8_t getPartID(void){ |
kohlerba | 3:fa37b0c705b3 | 172 | char buffer[1]; |
kohlerba | 3:fa37b0c705b3 | 173 | i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, &buffer[0], 1); |
kohlerba | 3:fa37b0c705b3 | 174 | return buffer[0]; |
kohlerba | 0:faf977308bdc | 175 | } |
kohlerba | 0:faf977308bdc | 176 | |
kohlerba | 0:faf977308bdc | 177 | void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ |
kohlerba | 3:fa37b0c705b3 | 178 | char buffer[1]; |
kohlerba | 3:fa37b0c705b3 | 179 | buffer[0] = 0x02; |
kohlerba | 3:fa37b0c705b3 | 180 | i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &buffer[0], 1); // Heart rate only |
kohlerba | 3:fa37b0c705b3 | 181 | buffer[0] = ir; |
kohlerba | 3:fa37b0c705b3 | 182 | i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &buffer[0], 1); |
kohlerba | 3:fa37b0c705b3 | 183 | buffer[0] = (sr<<2)|pw; |
kohlerba | 3:fa37b0c705b3 | 184 | i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &buffer[0], 1); |
kohlerba | 0:faf977308bdc | 185 | } |
kohlerba | 3:fa37b0c705b3 | 186 | |
kohlerba | 3:fa37b0c705b3 | 187 | void printRegisters(){ |
kohlerba | 3:fa37b0c705b3 | 188 | char reg[1]; |
kohlerba | 3:fa37b0c705b3 | 189 | i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 190 | pc.printf("MAX30100_INT_STATUS: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 191 | i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 192 | pc.printf("MAX30100_INT_ENABLE: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 193 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 194 | pc.printf("MAX30100_FIFO_WR_PTR: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 195 | i2c_read(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 196 | pc.printf("MAX30100_OVRFLOW_CTR: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 197 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 198 | pc.printf("MAX30100_FIFO_RD_PTR: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 199 | i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 200 | pc.printf("MAX30100_FIFO_DATA: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 201 | i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 202 | pc.printf("MAX30100_MODE_CONFIG: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 203 | i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 204 | pc.printf("MAX30100_SPO2_CONFIG: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 205 | i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 206 | pc.printf("MAX30100_LED_CONFIG: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 207 | i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 208 | pc.printf("MAX30100_TEMP_INTG: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 209 | i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 210 | pc.printf("MAX30100_TEMP_FRAC: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 211 | i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 212 | pc.printf("MAX30100_REV_ID: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 213 | i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, ®[0], 1); |
kohlerba | 3:fa37b0c705b3 | 214 | pc.printf("MAX30100_PART_ID: %d\r\n",reg[0]); |
kohlerba | 3:fa37b0c705b3 | 215 | } |
kohlerba | 3:fa37b0c705b3 | 216 | |
kohlerba | 1:0c2135629097 | 217 | }; |
kohlerba | 0:faf977308bdc | 218 | #endif |