Bradley Kohler
/
PulseRate
MAX30100 pulse rate sensor
MAX30100.h@0:faf977308bdc, 2017-08-18 (annotated)
- Committer:
- kohlerba
- Date:
- Fri Aug 18 01:06:07 2017 +0000
- Revision:
- 0:faf977308bdc
- Child:
- 1:0c2135629097
Finished MAX30100 Library
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 | 0:faf977308bdc | 7 | #define MAX30100_ADDRESS 0x57 |
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 | 0:faf977308bdc | 24 | typedef enum{ // This is the same for both LEDs |
kohlerba | 0:faf977308bdc | 25 | pw200, // 200us pulse |
kohlerba | 0:faf977308bdc | 26 | pw400, // 400us pulse |
kohlerba | 0:faf977308bdc | 27 | pw800, // 800us pulse |
kohlerba | 0:faf977308bdc | 28 | pw1600 // 1600us pulse |
kohlerba | 0:faf977308bdc | 29 | }pulseWidth; |
kohlerba | 0:faf977308bdc | 30 | |
kohlerba | 0:faf977308bdc | 31 | typedef enum{ |
kohlerba | 0:faf977308bdc | 32 | sr50, // 50 samples per second |
kohlerba | 0:faf977308bdc | 33 | sr100, // 100 samples per second |
kohlerba | 0:faf977308bdc | 34 | sr167, // 167 samples per second |
kohlerba | 0:faf977308bdc | 35 | sr200, // 200 samples per second |
kohlerba | 0:faf977308bdc | 36 | sr400, // 400 samples per second |
kohlerba | 0:faf977308bdc | 37 | sr600, // 600 samples per second |
kohlerba | 0:faf977308bdc | 38 | sr800, // 800 samples per second |
kohlerba | 0:faf977308bdc | 39 | sr1000 // 1000 samples per second |
kohlerba | 0:faf977308bdc | 40 | }sampleRate; |
kohlerba | 0:faf977308bdc | 41 | |
kohlerba | 0:faf977308bdc | 42 | typedef enum{ |
kohlerba | 0:faf977308bdc | 43 | i0, // No current |
kohlerba | 0:faf977308bdc | 44 | i4, // 4.4mA |
kohlerba | 0:faf977308bdc | 45 | i8, // 7.6mA |
kohlerba | 0:faf977308bdc | 46 | i11, // 11.0mA |
kohlerba | 0:faf977308bdc | 47 | i14, // 14.2mA |
kohlerba | 0:faf977308bdc | 48 | i17, // 17.4mA |
kohlerba | 0:faf977308bdc | 49 | i21, // 20.8mA |
kohlerba | 0:faf977308bdc | 50 | i27, // 27.1mA |
kohlerba | 0:faf977308bdc | 51 | i31, // 30.6mA |
kohlerba | 0:faf977308bdc | 52 | i34, // 33.8mA |
kohlerba | 0:faf977308bdc | 53 | i37, // 37.0mA |
kohlerba | 0:faf977308bdc | 54 | i40, // 40.2mA |
kohlerba | 0:faf977308bdc | 55 | i44, // 43.6mA |
kohlerba | 0:faf977308bdc | 56 | i47, // 46.8mA |
kohlerba | 0:faf977308bdc | 57 | i50 // 50.0mA |
kohlerba | 0:faf977308bdc | 58 | }ledCurrent; |
kohlerba | 0:faf977308bdc | 59 | |
kohlerba | 0:faf977308bdc | 60 | //Set up I2C, (SDA,SCL) |
kohlerba | 0:faf977308bdc | 61 | I2C i2c(I2C_SDA, I2C_SCL); |
kohlerba | 0:faf977308bdc | 62 | |
kohlerba | 0:faf977308bdc | 63 | uint16_t IR = 0; // Last IR reflectance datapoint |
kohlerba | 0:faf977308bdc | 64 | uint16_t RED = 0; // Last Red reflectance datapoint |
kohlerba | 0:faf977308bdc | 65 | |
kohlerba | 0:faf977308bdc | 66 | class MAX30100 { |
kohlerba | 0:faf977308bdc | 67 | |
kohlerba | 0:faf977308bdc | 68 | protected: |
kohlerba | 0:faf977308bdc | 69 | |
kohlerba | 0:faf977308bdc | 70 | public: |
kohlerba | 0:faf977308bdc | 71 | |
kohlerba | 0:faf977308bdc | 72 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) |
kohlerba | 0:faf977308bdc | 73 | { |
kohlerba | 0:faf977308bdc | 74 | char data_write[2]; |
kohlerba | 0:faf977308bdc | 75 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 76 | data_write[1] = data; |
kohlerba | 0:faf977308bdc | 77 | i2c.write(address, data_write, 2, 0); |
kohlerba | 0:faf977308bdc | 78 | } |
kohlerba | 0:faf977308bdc | 79 | |
kohlerba | 0:faf977308bdc | 80 | char readByte(uint8_t address, uint8_t subAddress) |
kohlerba | 0:faf977308bdc | 81 | { |
kohlerba | 0:faf977308bdc | 82 | char data[1]; // `data` will store the register data |
kohlerba | 0:faf977308bdc | 83 | char data_write[1]; |
kohlerba | 0:faf977308bdc | 84 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 85 | i2c.write(address, data_write, 1, 1); // no stop |
kohlerba | 0:faf977308bdc | 86 | i2c.read(address, data, 1, 0); |
kohlerba | 0:faf977308bdc | 87 | return data[0]; |
kohlerba | 0:faf977308bdc | 88 | } |
kohlerba | 0:faf977308bdc | 89 | |
kohlerba | 0:faf977308bdc | 90 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) |
kohlerba | 0:faf977308bdc | 91 | { |
kohlerba | 0:faf977308bdc | 92 | char data[14]; |
kohlerba | 0:faf977308bdc | 93 | char data_write[1]; |
kohlerba | 0:faf977308bdc | 94 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 95 | i2c.write(address, data_write, 1, 1); // no stop |
kohlerba | 0:faf977308bdc | 96 | i2c.read(address, data, count, 0); |
kohlerba | 0:faf977308bdc | 97 | for(int ii = 0; ii < count; ii++) { |
kohlerba | 0:faf977308bdc | 98 | dest[ii] = data[ii]; |
kohlerba | 0:faf977308bdc | 99 | } |
kohlerba | 0:faf977308bdc | 100 | } |
kohlerba | 0:faf977308bdc | 101 | |
kohlerba | 0:faf977308bdc | 102 | void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ |
kohlerba | 0:faf977308bdc | 103 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG); |
kohlerba | 0:faf977308bdc | 104 | reg = reg & 0xFC; // Set LED_PW to 00 |
kohlerba | 0:faf977308bdc | 105 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | pw); // Mask LED_PW |
kohlerba | 0:faf977308bdc | 106 | writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, (red<<4) | ir); // write LED configs |
kohlerba | 0:faf977308bdc | 107 | } |
kohlerba | 0:faf977308bdc | 108 | |
kohlerba | 0:faf977308bdc | 109 | void setSPO2(sampleRate sr){ |
kohlerba | 0:faf977308bdc | 110 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG); |
kohlerba | 0:faf977308bdc | 111 | reg = reg & 0xE3; // Set SPO2_SR to 000 |
kohlerba | 0:faf977308bdc | 112 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | (sr<<2)); // Mask SPO2_SR |
kohlerba | 0:faf977308bdc | 113 | reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); |
kohlerba | 0:faf977308bdc | 114 | reg = reg & 0xf8; // Set Mode to 000 |
kohlerba | 0:faf977308bdc | 115 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | 0x03); // Mask MODE |
kohlerba | 0:faf977308bdc | 116 | } |
kohlerba | 0:faf977308bdc | 117 | |
kohlerba | 0:faf977308bdc | 118 | int getNumSamp(void){ |
kohlerba | 0:faf977308bdc | 119 | uint8_t wrPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR); |
kohlerba | 0:faf977308bdc | 120 | uint8_t rdPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR); |
kohlerba | 0:faf977308bdc | 121 | return (abs( 16 + wrPtr - rdPtr ) % 16); |
kohlerba | 0:faf977308bdc | 122 | } |
kohlerba | 0:faf977308bdc | 123 | |
kohlerba | 0:faf977308bdc | 124 | void readSensor(void){ |
kohlerba | 0:faf977308bdc | 125 | uint8_t temp[4] = {0}; // Temporary buffer for read values |
kohlerba | 0:faf977308bdc | 126 | readBytes(MAX30100_ADDRESS, MAX30100_FIFO_DATA, 4, &temp[0]); // Read four times from the FIFO |
kohlerba | 0:faf977308bdc | 127 | IR = (temp[0]<<8) | temp[1]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 128 | RED = (temp[2]<<8) | temp[3]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 129 | } |
kohlerba | 0:faf977308bdc | 130 | |
kohlerba | 0:faf977308bdc | 131 | void shutdown(void){ |
kohlerba | 0:faf977308bdc | 132 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 133 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x80); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 134 | } |
kohlerba | 0:faf977308bdc | 135 | |
kohlerba | 0:faf977308bdc | 136 | void reset(void){ |
kohlerba | 0:faf977308bdc | 137 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 138 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x40); // mask the RESET bit |
kohlerba | 0:faf977308bdc | 139 | } |
kohlerba | 0:faf977308bdc | 140 | |
kohlerba | 0:faf977308bdc | 141 | void startup(void){ |
kohlerba | 0:faf977308bdc | 142 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 143 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg & 0x7F); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 144 | } |
kohlerba | 0:faf977308bdc | 145 | |
kohlerba | 0:faf977308bdc | 146 | int getRevID(void){ |
kohlerba | 0:faf977308bdc | 147 | return readByte(MAX30100_ADDRESS, MAX30100_REV_ID); |
kohlerba | 0:faf977308bdc | 148 | } |
kohlerba | 0:faf977308bdc | 149 | |
kohlerba | 0:faf977308bdc | 150 | int getPartID(void){ |
kohlerba | 0:faf977308bdc | 151 | return readByte(MAX30100_ADDRESS, MAX30100_PART_ID); |
kohlerba | 0:faf977308bdc | 152 | } |
kohlerba | 0:faf977308bdc | 153 | |
kohlerba | 0:faf977308bdc | 154 | void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ |
kohlerba | 0:faf977308bdc | 155 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, 0x02); // Heart rate only |
kohlerba | 0:faf977308bdc | 156 | writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ir); |
kohlerba | 0:faf977308bdc | 157 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, (sr<<2)|pw); |
kohlerba | 0:faf977308bdc | 158 | } |
kohlerba | 0:faf977308bdc | 159 | |
kohlerba | 0:faf977308bdc | 160 | void printRegisters(void){ |
kohlerba | 0:faf977308bdc | 161 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_INT_STATUS), BIN); |
kohlerba | 0:faf977308bdc | 162 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_INT_ENABLE), BIN); |
kohlerba | 0:faf977308bdc | 163 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR), BIN); |
kohlerba | 0:faf977308bdc | 164 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR), BIN); |
kohlerba | 0:faf977308bdc | 165 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR), BIN); |
kohlerba | 0:faf977308bdc | 166 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_DATA), BIN); |
kohlerba | 0:faf977308bdc | 167 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG), BIN); |
kohlerba | 0:faf977308bdc | 168 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG), BIN); |
kohlerba | 0:faf977308bdc | 169 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG), BIN); |
kohlerba | 0:faf977308bdc | 170 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_TEMP_INTG), BIN); |
kohlerba | 0:faf977308bdc | 171 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_TEMP_FRAC), BIN); |
kohlerba | 0:faf977308bdc | 172 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_REV_ID), BIN); |
kohlerba | 0:faf977308bdc | 173 | Serial.println(readByte(MAX30100_ADDRESS, MAX30100_PART_ID), BIN); |
kohlerba | 0:faf977308bdc | 174 | } |
kohlerba | 0:faf977308bdc | 175 | |
kohlerba | 0:faf977308bdc | 176 | #endif |