Bradley Kohler
/
PulseRate
MAX30100 pulse rate sensor
MAX30100.h@2:d329886938f1, 2017-08-23 (annotated)
- Committer:
- kohlerba
- Date:
- Wed Aug 23 19:04:51 2017 +0000
- Revision:
- 2:d329886938f1
- Parent:
- 1:0c2135629097
- Child:
- 3:fa37b0c705b3
Updated
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 | 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 | 0:faf977308bdc | 63 | I2C i2c(I2C_SDA, I2C_SCL); |
kohlerba | 0:faf977308bdc | 64 | |
kohlerba | 0:faf977308bdc | 65 | uint16_t IR = 0; // Last IR reflectance datapoint |
kohlerba | 0:faf977308bdc | 66 | uint16_t RED = 0; // Last Red reflectance datapoint |
kohlerba | 0:faf977308bdc | 67 | |
kohlerba | 0:faf977308bdc | 68 | class MAX30100 { |
kohlerba | 0:faf977308bdc | 69 | |
kohlerba | 0:faf977308bdc | 70 | protected: |
kohlerba | 0:faf977308bdc | 71 | |
kohlerba | 0:faf977308bdc | 72 | public: |
kohlerba | 0:faf977308bdc | 73 | |
kohlerba | 2:d329886938f1 | 74 | //Wire read and write protocols |
kohlerba | 0:faf977308bdc | 75 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) |
kohlerba | 0:faf977308bdc | 76 | { |
kohlerba | 0:faf977308bdc | 77 | char data_write[2]; |
kohlerba | 0:faf977308bdc | 78 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 79 | data_write[1] = data; |
kohlerba | 0:faf977308bdc | 80 | i2c.write(address, data_write, 2, 0); |
kohlerba | 0:faf977308bdc | 81 | } |
kohlerba | 0:faf977308bdc | 82 | |
kohlerba | 0:faf977308bdc | 83 | char readByte(uint8_t address, uint8_t subAddress) |
kohlerba | 0:faf977308bdc | 84 | { |
kohlerba | 0:faf977308bdc | 85 | char data[1]; // `data` will store the register data |
kohlerba | 0:faf977308bdc | 86 | char data_write[1]; |
kohlerba | 0:faf977308bdc | 87 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 88 | i2c.write(address, data_write, 1, 1); // no stop |
kohlerba | 0:faf977308bdc | 89 | i2c.read(address, data, 1, 0); |
kohlerba | 0:faf977308bdc | 90 | return data[0]; |
kohlerba | 0:faf977308bdc | 91 | } |
kohlerba | 0:faf977308bdc | 92 | |
kohlerba | 0:faf977308bdc | 93 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) |
kohlerba | 0:faf977308bdc | 94 | { |
kohlerba | 0:faf977308bdc | 95 | char data[14]; |
kohlerba | 0:faf977308bdc | 96 | char data_write[1]; |
kohlerba | 0:faf977308bdc | 97 | data_write[0] = subAddress; |
kohlerba | 0:faf977308bdc | 98 | i2c.write(address, data_write, 1, 1); // no stop |
kohlerba | 0:faf977308bdc | 99 | i2c.read(address, data, count, 0); |
kohlerba | 0:faf977308bdc | 100 | for(int ii = 0; ii < count; ii++) { |
kohlerba | 2:d329886938f1 | 101 | dest[ii] = data[ii]; |
kohlerba | 0:faf977308bdc | 102 | } |
kohlerba | 0:faf977308bdc | 103 | } |
kohlerba | 2:d329886938f1 | 104 | // |
kohlerba | 2:d329886938f1 | 105 | |
kohlerba | 0:faf977308bdc | 106 | void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ |
kohlerba | 0:faf977308bdc | 107 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG); |
kohlerba | 0:faf977308bdc | 108 | reg = reg & 0xFC; // Set LED_PW to 00 |
kohlerba | 0:faf977308bdc | 109 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | pw); // Mask LED_PW |
kohlerba | 0:faf977308bdc | 110 | writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, (red<<4) | ir); // write LED configs |
kohlerba | 0:faf977308bdc | 111 | } |
kohlerba | 0:faf977308bdc | 112 | |
kohlerba | 0:faf977308bdc | 113 | void setSPO2(sampleRate sr){ |
kohlerba | 0:faf977308bdc | 114 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG); |
kohlerba | 0:faf977308bdc | 115 | reg = reg & 0xE3; // Set SPO2_SR to 000 |
kohlerba | 0:faf977308bdc | 116 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | (sr<<2)); // Mask SPO2_SR |
kohlerba | 0:faf977308bdc | 117 | reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); |
kohlerba | 0:faf977308bdc | 118 | reg = reg & 0xf8; // Set Mode to 000 |
kohlerba | 0:faf977308bdc | 119 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | 0x03); // Mask MODE |
kohlerba | 0:faf977308bdc | 120 | } |
kohlerba | 0:faf977308bdc | 121 | |
kohlerba | 0:faf977308bdc | 122 | int getNumSamp(void){ |
kohlerba | 0:faf977308bdc | 123 | uint8_t wrPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR); |
kohlerba | 0:faf977308bdc | 124 | uint8_t rdPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR); |
kohlerba | 0:faf977308bdc | 125 | return (abs( 16 + wrPtr - rdPtr ) % 16); |
kohlerba | 0:faf977308bdc | 126 | } |
kohlerba | 0:faf977308bdc | 127 | |
kohlerba | 0:faf977308bdc | 128 | void readSensor(void){ |
kohlerba | 0:faf977308bdc | 129 | uint8_t temp[4] = {0}; // Temporary buffer for read values |
kohlerba | 0:faf977308bdc | 130 | readBytes(MAX30100_ADDRESS, MAX30100_FIFO_DATA, 4, &temp[0]); // Read four times from the FIFO |
kohlerba | 0:faf977308bdc | 131 | IR = (temp[0]<<8) | temp[1]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 132 | RED = (temp[2]<<8) | temp[3]; // Combine values to get the actual number |
kohlerba | 0:faf977308bdc | 133 | } |
kohlerba | 0:faf977308bdc | 134 | |
kohlerba | 0:faf977308bdc | 135 | void shutdown(void){ |
kohlerba | 0:faf977308bdc | 136 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 137 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x80); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 138 | } |
kohlerba | 0:faf977308bdc | 139 | |
kohlerba | 0:faf977308bdc | 140 | void reset(void){ |
kohlerba | 0:faf977308bdc | 141 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 142 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x40); // mask the RESET bit |
kohlerba | 0:faf977308bdc | 143 | } |
kohlerba | 0:faf977308bdc | 144 | |
kohlerba | 0:faf977308bdc | 145 | void startup(void){ |
kohlerba | 0:faf977308bdc | 146 | uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG); // Get the current register |
kohlerba | 0:faf977308bdc | 147 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg & 0x7F); // mask the SHDN bit |
kohlerba | 0:faf977308bdc | 148 | } |
kohlerba | 0:faf977308bdc | 149 | |
kohlerba | 0:faf977308bdc | 150 | int getRevID(void){ |
kohlerba | 0:faf977308bdc | 151 | return readByte(MAX30100_ADDRESS, MAX30100_REV_ID); |
kohlerba | 0:faf977308bdc | 152 | } |
kohlerba | 0:faf977308bdc | 153 | |
kohlerba | 0:faf977308bdc | 154 | int getPartID(void){ |
kohlerba | 0:faf977308bdc | 155 | return readByte(MAX30100_ADDRESS, MAX30100_PART_ID); |
kohlerba | 0:faf977308bdc | 156 | } |
kohlerba | 0:faf977308bdc | 157 | |
kohlerba | 0:faf977308bdc | 158 | void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ |
kohlerba | 0:faf977308bdc | 159 | writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, 0x02); // Heart rate only |
kohlerba | 0:faf977308bdc | 160 | writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ir); |
kohlerba | 0:faf977308bdc | 161 | writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, (sr<<2)|pw); |
kohlerba | 0:faf977308bdc | 162 | } |
kohlerba | 1:0c2135629097 | 163 | }; |
kohlerba | 0:faf977308bdc | 164 | #endif |