![](/media/cache/profiles/DSC_0020.jpg.50x50_q85.jpg)
MAX30100 pulse rate sensor
Diff: MAX30100.h
- Revision:
- 4:008e40a7d035
- Parent:
- 3:fa37b0c705b3
diff -r fa37b0c705b3 -r 008e40a7d035 MAX30100.h --- a/MAX30100.h Sun Nov 26 21:56:10 2017 +0000 +++ b/MAX30100.h Sun Nov 26 21:59:11 2017 +0000 @@ -23,55 +23,79 @@ #define POR_PART_ID 0x11 -typedef enum{ // This is the same for both LEDs - pw200, // 200us pulse - pw400, // 400us pulse - pw800, // 800us pulse - pw1600 // 1600us pulse -}pulseWidth; +//Mode Configuration register +#define MAX30100_MC_TEMP_EN (1 << 3) +#define MAX30100_MC_RESET (1 << 6) +#define MAX30100_MC_SHDN (1 << 7) + +typedef enum Mode { + MAX30100_MODE_HRONLY = 0x02, + MAX30100_MODE_SPO2_HR = 0x03 +} Mode; -typedef enum{ - sr50, // 50 samples per second - sr100, // 100 samples per second - sr167, // 167 samples per second - sr200, // 200 samples per second - sr400, // 400 samples per second - sr600, // 600 samples per second - sr800, // 800 samples per second - sr1000 // 1000 samples per second -}sampleRate; +// SpO2 Configuration register +// Check tables 8 and 9, p19 of the MAX30100 datasheet to see the permissible +// combinations of sampling rates and pulse widths +#define MAX30100_SPC_SPO2_HI_RES_EN (1 << 6) +typedef enum SamplingRate { + MAX30100_SAMPRATE_50HZ = 0x00, + MAX30100_SAMPRATE_100HZ = 0x01, + MAX30100_SAMPRATE_167HZ = 0x02, + MAX30100_SAMPRATE_200HZ = 0x03, + MAX30100_SAMPRATE_400HZ = 0x04, + MAX30100_SAMPRATE_600HZ = 0x05, + MAX30100_SAMPRATE_800HZ = 0x06, + MAX30100_SAMPRATE_1000HZ = 0x07 +} SamplingRate; -typedef enum{ - i0, // No current - i4, // 4.4mA - i8, // 7.6mA - i11, // 11.0mA - i14, // 14.2mA - i17, // 17.4mA - i21, // 20.8mA - i27, // 27.1mA - i31, // 30.6mA - i34, // 33.8mA - i37, // 37.0mA - i40, // 40.2mA - i44, // 43.6mA - i47, // 46.8mA - i50 // 50.0mA -}ledCurrent; +typedef enum LEDPulseWidth { + MAX30100_SPC_PW_200US_13BITS = 0x00, + MAX30100_SPC_PW_400US_14BITS = 0x01, + MAX30100_SPC_PW_800US_15BITS = 0x02, + MAX30100_SPC_PW_1600US_16BITS = 0x03 +} LEDPulseWidth; + +// LED Configuration register +typedef enum LEDCurrent { + MAX30100_LED_CURR_0MA = 0x00, + MAX30100_LED_CURR_4_4MA = 0x01, + MAX30100_LED_CURR_7_6MA = 0x02, + MAX30100_LED_CURR_11MA = 0x03, + MAX30100_LED_CURR_14_2MA = 0x04, + MAX30100_LED_CURR_17_4MA = 0x05, + MAX30100_LED_CURR_20_8MA = 0x06, + MAX30100_LED_CURR_24MA = 0x07, + MAX30100_LED_CURR_27_1MA = 0x08, + MAX30100_LED_CURR_30_6MA = 0x09, + MAX30100_LED_CURR_33_8MA = 0x0a, + MAX30100_LED_CURR_37MA = 0x0b, + MAX30100_LED_CURR_40_2MA = 0x0c, + MAX30100_LED_CURR_43_6MA = 0x0d, + MAX30100_LED_CURR_46_8MA = 0x0e, + MAX30100_LED_CURR_50MA = 0x0f +} LEDCurrent; + +#define DEFAULT_MODE MAX30100_MODE_HRONLY +#define DEFAULT_SAMPLING_RATE MAX30100_SAMPRATE_100HZ +#define DEFAULT_PULSE_WIDTH MAX30100_SPC_PW_1600US_16BITS +#define DEFAULT_RED_LED_CURRENT MAX30100_LED_CURR_50MA +#define DEFAULT_IR_LED_CURRENT MAX30100_LED_CURR_50MA +#define EXPECTED_PART_ID 0x11 //Set up I2C, (SDA,SCL) static I2C i2c(I2C_SDA, I2C_SCL); static Serial pc(USBTX, USBRX); // tx, rx -uint16_t IR = 0; // Last IR reflectance datapoint -uint16_t RED = 0; // Last Red reflectance datapoint - class MAX30100 { protected: public: + //Variables + uint16_t rawIRValue; + uint16_t rawRedValue; + //Wire read and write protocols static int i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) { @@ -103,64 +127,6 @@ return ret; } // - -void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ - char reg[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); - reg[0] = reg[0] & 0xFC; // Set LED_PW to 00 - reg[0] = reg[0] | pw; - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask LED_PW - reg[0] = (red<<4) | ir; - i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); // write LED configs -} - -void setSPO2(sampleRate sr){ - char reg[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); - reg[0] = reg[0] & 0xE3; // Set SPO2_SR to 000 - reg[0] = reg[0] | (sr<<2); - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask SPO2_SR - i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); - reg[0] = reg[0] & 0xf8; // Set Mode to 000 - reg[0] = reg[0] | 0x03; - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); // Mask MODE -} - -int getNumSamp(void){ - char wrPtr[1]; - char rdPtr[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, &wrPtr[0], 1); - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, &rdPtr[0], 1); - return (abs( 16 + wrPtr[0] - rdPtr[0] ) % 16); -} - -void readSensor(void){ - char temp[4] = {0}; // Temporary buffer for read values - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &temp[0], 4); // Read four times from the FIFO - IR = (temp[0]<<8) | temp[1]; // Combine values to get the actual number - RED = (temp[2]<<8) | temp[3]; // Combine values to get the actual number -} - -void shutdown(void){ - char reg[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register - reg[0] = reg[0] | 0x80; - i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit -} - -void reset(void){ - char reg[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register - reg[0] = reg[0] | 0x40; - i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the RESET bit -} - -void startup(void){ - char reg[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // Get the current register - reg[0] = reg[0] & 0x7F; - i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); // mask the SHDN bit -} uint8_t getRevID(void){ char buffer[1]; @@ -174,17 +140,25 @@ return buffer[0]; } -void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ - char buffer[1]; - buffer[0] = 0x02; - i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &buffer[0], 1); // Heart rate only - buffer[0] = ir; - i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &buffer[0], 1); - buffer[0] = (sr<<2)|pw; - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &buffer[0], 1); +void shutdown(void){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); + reg[0] = reg[0] | MAX30100_MC_SHDN; + i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); } -void printRegisters(){ +void resume(void){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); + reg[0] = reg[0] & ~MAX30100_MC_SHDN; + i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); +} + +void update(void){ + readFifoData(); +} + +void printRegisters(void){ char reg[1]; i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, ®[0], 1); pc.printf("MAX30100_INT_STATUS: %d\r\n",reg[0]); @@ -214,5 +188,85 @@ pc.printf("MAX30100_PART_ID: %d\r\n",reg[0]); } +bool begin(){ + if(getPartID() != POR_PART_ID){ + return false; + } + setMode(DEFAULT_MODE); + setLedsPulseWidth(DEFAULT_PULSE_WIDTH); + setSamplingRate(DEFAULT_SAMPLING_RATE); + setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT); + setHighresModeEnabled(true); + + return true; +} + +void setMode(Mode mode){ + char reg[1]; + reg[0] = mode; + i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); +} + +void setLedsPulseWidth(LEDPulseWidth ledPulseWidth){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); + reg[0] = (reg[0] & 0xfc) | ledPulseWidth; + i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); +} + +void setSamplingRate(SamplingRate samplingRate){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); + reg[0] = (reg[0] & 0xe3) | (samplingRate << 2); + i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); +} + +void setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent){ + char reg[1]; + reg[0] = (redLedCurrent << 4) | irLedCurrent; + i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); +} + +void setHighresModeEnabled(bool enabled){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); + if(enabled){ + reg[0] = reg[0] | MAX30100_SPC_SPO2_HI_RES_EN; + } + else{ + reg[0] = reg[0] & ~MAX30100_SPC_SPO2_HI_RES_EN; + } + i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); +} + +void readFifoData(void){ + char reg[4]; + i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, ®[0], 4); + rawIRValue = (reg[0] << 8) | reg[1]; + rawRedValue = (reg[2] << 8) | reg[3]; +} + +void startTemperatureSampling(void){ + char reg[1]; + i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); + reg[0] = reg[0] | MAX30100_MC_TEMP_EN; + i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); +} + +bool isTemperatureReady(void){ + char reg[1]; + bool ret; + ret = i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); + ret = ret & MAX30100_MC_TEMP_EN; + return !ret; +} + +float retrieveTemperature(void){ + char reg[2]; + i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, ®[0], 1); + i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, ®[1], 1); + return reg[0] + (reg[1] * 0.0625); +} + }; #endif \ No newline at end of file