MAX30100 pulse rate sensor
Revision 4:008e40a7d035, committed 2017-11-26
- 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, ®[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
Bradley Kohler