MAX30100 pulse rate sensor

Dependencies:   PulseRate

Dependents:   PulseRate

MAX30100.h

Committer:
kohlerba
Date:
2017-08-18
Revision:
0:faf977308bdc
Child:
1:0c2135629097

File content as of revision 0:faf977308bdc:

#ifndef MAX30100_H
#define MAX30100_H

#include "mbed.h"

//definitions
#define MAX30100_ADDRESS 0x57

// Registers
#define MAX30100_INT_STATUS     0x00  // Which interrupts are tripped
#define MAX30100_INT_ENABLE     0x01  // Which interrupts are active
#define MAX30100_FIFO_WR_PTR    0x02  // Where data is being written
#define MAX30100_OVRFLOW_CTR    0x03  // Number of lost samples
#define MAX30100_FIFO_RD_PTR    0x04  // Where to read from
#define MAX30100_FIFO_DATA      0x05  // Ouput data buffer
#define MAX30100_MODE_CONFIG    0x06  // Control register
#define MAX30100_SPO2_CONFIG    0x07  // Oximetry settings
#define MAX30100_LED_CONFIG     0x09  // Pulse width and power of LEDs
#define MAX30100_TEMP_INTG      0x16  // Temperature value, whole number
#define MAX30100_TEMP_FRAC      0x17  // Temperature value, fraction
#define MAX30100_REV_ID         0xFE  // Part revision
#define MAX30100_PART_ID        0xFF  // Part ID, normally 0x11

typedef enum{ // This is the same for both LEDs
  pw200,    // 200us pulse
  pw400,    // 400us pulse
  pw800,    // 800us pulse
  pw1600    // 1600us pulse
}pulseWidth;

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;

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;

//Set up I2C, (SDA,SCL)
I2C i2c(I2C_SDA, I2C_SCL);

uint16_t IR = 0;      // Last IR reflectance datapoint
uint16_t RED = 0;     // Last Red reflectance datapoint

class MAX30100 {
 
    protected:
 
    public:
    
    void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
{
   char data_write[2];
   data_write[0] = subAddress;
   data_write[1] = data;
   i2c.write(address, data_write, 2, 0);
}

    char readByte(uint8_t address, uint8_t subAddress)
{
    char data[1]; // `data` will store the register data     
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no stop
    i2c.read(address, data, 1, 0); 
    return data[0]; 
}

    void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{     
    char data[14];
    char data_write[1];
    data_write[0] = subAddress;
    i2c.write(address, data_write, 1, 1); // no stop
    i2c.read(address, data, count, 0); 
    for(int ii = 0; ii < count; ii++) {
     dest[ii] = data[ii];
    }
}

void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){
  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG);
  reg = reg & 0xFC; // Set LED_PW to 00
  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | pw);     // Mask LED_PW
  writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, (red<<4) | ir); // write LED configs
}

void setSPO2(sampleRate sr){
  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG);
  reg = reg & 0xE3; // Set SPO2_SR to 000
  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | (sr<<2)); // Mask SPO2_SR
  reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);
  reg = reg & 0xf8; // Set Mode to 000
  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | 0x03); // Mask MODE
}

int getNumSamp(void){
    uint8_t wrPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR);
    uint8_t rdPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR);
    return (abs( 16 + wrPtr - rdPtr ) % 16);
}

void readSensor(void){
  uint8_t temp[4] = {0};  // Temporary buffer for read values
  readBytes(MAX30100_ADDRESS, MAX30100_FIFO_DATA, 4, &temp[0]);  // 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){
  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x80);   // mask the SHDN bit
}

void reset(void){
  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x40);   // mask the RESET bit
}

void startup(void){
  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg & 0x7F);   // mask the SHDN bit
}

int getRevID(void){
  return readByte(MAX30100_ADDRESS, MAX30100_REV_ID);
}

int getPartID(void){
  return readByte(MAX30100_ADDRESS, MAX30100_PART_ID);
}

void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){
  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, 0x02); // Heart rate only
  writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ir);
  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, (sr<<2)|pw);
}

void printRegisters(void){
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_INT_STATUS),  BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_INT_ENABLE),  BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR), BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR), BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR), BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_FIFO_DATA),   BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG), BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG), BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG),  BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_TEMP_INTG),   BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_TEMP_FRAC),   BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_REV_ID),      BIN);
  Serial.println(readByte(MAX30100_ADDRESS, MAX30100_PART_ID),     BIN);
}

#endif