MAX30100 pulse rate sensor

Dependencies:   PulseRate

Dependents:   PulseRate

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?

UserRevisionLine numberNew 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*)&register_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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[0], 1); // Mask SPO2_SR
kohlerba 3:fa37b0c705b3 123 i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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, &reg[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