MAX30100 pulse rate sensor

Dependencies:   PulseRate

Dependents:   PulseRate

Files at this revision

API Documentation at this revision

Comitter:
kohlerba
Date:
Sun Nov 26 21:59:11 2017 +0000
Parent:
3:fa37b0c705b3
Commit message:
Header file error fix

Changed in this revision

MAX30100.h Show annotated file Show diff for this revision Revisions of this file
--- 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, &reg[0], 1);
-  reg[0] = reg[0] & 0xFC; // Set LED_PW to 00
-  reg[0] = reg[0] | pw;
-  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);     // Mask LED_PW
-  reg[0] = (red<<4) | ir;
-  i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &reg[0], 1); // write LED configs
-}
-
-void setSPO2(sampleRate sr){
-  char reg[1];
-  i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[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, &reg[0], 1); // Mask SPO2_SR
-  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
-  reg[0] = reg[0] & 0xf8; // Set Mode to 000
-  reg[0] = reg[0] | 0x03;
-  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[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, &reg[0], 1);  // Get the current register
-  reg[0] = reg[0] | 0x80;
-  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);   // mask the SHDN bit
-}
-
-void reset(void){
-  char reg[1];
-  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);  // Get the current register
-  reg[0] = reg[0] | 0x40;
-  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);   // mask the RESET bit
-}
-
-void startup(void){
-  char reg[1];
-  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);  // Get the current register
-  reg[0] = reg[0] & 0x7F;
-  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[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, &reg[0], 1);
+    reg[0] = reg[0] | MAX30100_MC_SHDN;
+    i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
 }
 
-void printRegisters(){
+void resume(void){
+    char reg[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+    reg[0] = reg[0] & ~MAX30100_MC_SHDN;
+    i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+}
+
+void update(void){
+    readFifoData();
+}
+
+void printRegisters(void){
     char reg[1];
     i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, &reg[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, &reg[0], 1);
+}
+
+void setLedsPulseWidth(LEDPulseWidth ledPulseWidth){
+    char reg[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+    reg[0] = (reg[0] & 0xfc) | ledPulseWidth;
+    i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+}
+
+void setSamplingRate(SamplingRate samplingRate){
+    char reg[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+    reg[0] = (reg[0] & 0xe3) | (samplingRate << 2);
+    i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+}
+
+void setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent){
+    char reg[1];
+    reg[0] = (redLedCurrent << 4) | irLedCurrent;
+    i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &reg[0], 1);
+}
+
+void setHighresModeEnabled(bool enabled){
+    char reg[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[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, &reg[0], 1);
+}
+
+void readFifoData(void){
+    char reg[4];
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &reg[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, &reg[0], 1);
+    reg[0] = reg[0] | MAX30100_MC_TEMP_EN;
+    i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+}
+
+bool isTemperatureReady(void){
+    char reg[1];
+    bool ret;
+    ret = i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+    ret = ret & MAX30100_MC_TEMP_EN;
+    return !ret;
+}
+
+float retrieveTemperature(void){
+    char reg[2];
+    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, &reg[0], 1);
+    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, &reg[1], 1);
+    return reg[0] + (reg[1] * 0.0625);
+}
+
 };
 #endif
\ No newline at end of file