Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MAX30100.h
00001 #ifndef MAX30100_H 00002 #define MAX30100_H 00003 00004 #include "mbed.h" 00005 00006 //definitions 00007 #define MAX30100_ADDRESS 0xAE 00008 00009 // Registers 00010 #define MAX30100_INT_STATUS 0x00 // Which interrupts are tripped 00011 #define MAX30100_INT_ENABLE 0x01 // Which interrupts are active 00012 #define MAX30100_FIFO_WR_PTR 0x02 // Where data is being written 00013 #define MAX30100_OVRFLOW_CTR 0x03 // Number of lost samples 00014 #define MAX30100_FIFO_RD_PTR 0x04 // Where to read from 00015 #define MAX30100_FIFO_DATA 0x05 // Ouput data buffer 00016 #define MAX30100_MODE_CONFIG 0x06 // Control register 00017 #define MAX30100_SPO2_CONFIG 0x07 // Oximetry settings 00018 #define MAX30100_LED_CONFIG 0x09 // Pulse width and power of LEDs 00019 #define MAX30100_TEMP_INTG 0x16 // Temperature value, whole number 00020 #define MAX30100_TEMP_FRAC 0x17 // Temperature value, fraction 00021 #define MAX30100_REV_ID 0xFE // Part revision 00022 #define MAX30100_PART_ID 0xFF // Part ID, normally 0x11 00023 00024 #define POR_PART_ID 0x11 00025 00026 //Mode Configuration register 00027 #define MAX30100_MC_TEMP_EN (1 << 3) 00028 #define MAX30100_MC_RESET (1 << 6) 00029 #define MAX30100_MC_SHDN (1 << 7) 00030 00031 typedef enum Mode { 00032 MAX30100_MODE_HRONLY = 0x02, 00033 MAX30100_MODE_SPO2_HR = 0x03 00034 } Mode; 00035 00036 // SpO2 Configuration register 00037 // Check tables 8 and 9, p19 of the MAX30100 datasheet to see the permissible 00038 // combinations of sampling rates and pulse widths 00039 #define MAX30100_SPC_SPO2_HI_RES_EN (1 << 6) 00040 typedef enum SamplingRate { 00041 MAX30100_SAMPRATE_50HZ = 0x00, 00042 MAX30100_SAMPRATE_100HZ = 0x01, 00043 MAX30100_SAMPRATE_167HZ = 0x02, 00044 MAX30100_SAMPRATE_200HZ = 0x03, 00045 MAX30100_SAMPRATE_400HZ = 0x04, 00046 MAX30100_SAMPRATE_600HZ = 0x05, 00047 MAX30100_SAMPRATE_800HZ = 0x06, 00048 MAX30100_SAMPRATE_1000HZ = 0x07 00049 } SamplingRate; 00050 00051 typedef enum LEDPulseWidth { 00052 MAX30100_SPC_PW_200US_13BITS = 0x00, 00053 MAX30100_SPC_PW_400US_14BITS = 0x01, 00054 MAX30100_SPC_PW_800US_15BITS = 0x02, 00055 MAX30100_SPC_PW_1600US_16BITS = 0x03 00056 } LEDPulseWidth; 00057 00058 // LED Configuration register 00059 typedef enum LEDCurrent { 00060 MAX30100_LED_CURR_0MA = 0x00, 00061 MAX30100_LED_CURR_4_4MA = 0x01, 00062 MAX30100_LED_CURR_7_6MA = 0x02, 00063 MAX30100_LED_CURR_11MA = 0x03, 00064 MAX30100_LED_CURR_14_2MA = 0x04, 00065 MAX30100_LED_CURR_17_4MA = 0x05, 00066 MAX30100_LED_CURR_20_8MA = 0x06, 00067 MAX30100_LED_CURR_24MA = 0x07, 00068 MAX30100_LED_CURR_27_1MA = 0x08, 00069 MAX30100_LED_CURR_30_6MA = 0x09, 00070 MAX30100_LED_CURR_33_8MA = 0x0a, 00071 MAX30100_LED_CURR_37MA = 0x0b, 00072 MAX30100_LED_CURR_40_2MA = 0x0c, 00073 MAX30100_LED_CURR_43_6MA = 0x0d, 00074 MAX30100_LED_CURR_46_8MA = 0x0e, 00075 MAX30100_LED_CURR_50MA = 0x0f 00076 } LEDCurrent; 00077 00078 #define DEFAULT_MODE MAX30100_MODE_HRONLY 00079 #define DEFAULT_SAMPLING_RATE MAX30100_SAMPRATE_100HZ 00080 #define DEFAULT_PULSE_WIDTH MAX30100_SPC_PW_1600US_16BITS 00081 #define DEFAULT_RED_LED_CURRENT MAX30100_LED_CURR_50MA 00082 #define DEFAULT_IR_LED_CURRENT MAX30100_LED_CURR_50MA 00083 #define EXPECTED_PART_ID 0x11 00084 00085 //Set up I2C, (SDA,SCL) 00086 static I2C i2c(I2C_SDA, I2C_SCL); 00087 static Serial pc(USBTX, USBRX); // tx, rx 00088 00089 class MAX30100 { 00090 00091 protected: 00092 00093 public: 00094 00095 //Variables 00096 uint16_t rawIRValue; 00097 uint16_t rawRedValue; 00098 00099 //Wire read and write protocols 00100 static int i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) 00101 { 00102 int ret; 00103 char *tmp_buffer; 00104 00105 tmp_buffer = (char*)malloc(sizeof(char)*(Nbyte+1)); 00106 00107 /* First, send device address. Then, send data and STOP condition */ 00108 tmp_buffer[0] = register_addr; 00109 memcpy(tmp_buffer+1, buffer, Nbyte); 00110 00111 ret = i2c.write(i2c_addr, tmp_buffer, Nbyte+1, false); 00112 00113 return ret; 00114 } 00115 00116 static int i2c_read (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte ) 00117 { 00118 int ret; 00119 00120 /* Send device address, with no STOP condition */ 00121 ret = i2c.write(i2c_addr, (const char*)®ister_addr, 1, true); 00122 if(!ret) { 00123 /* Read data, with STOP condition */ 00124 ret = i2c.read((i2c_addr|0x01), buffer, Nbyte, false); 00125 } 00126 00127 return ret; 00128 } 00129 // 00130 00131 uint8_t getRevID(void){ 00132 char buffer[1]; 00133 i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, &buffer[0], 1); 00134 return buffer[0]; 00135 } 00136 00137 uint8_t getPartID(void){ 00138 char buffer[1]; 00139 i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, &buffer[0], 1); 00140 return buffer[0]; 00141 } 00142 00143 void shutdown(void){ 00144 char reg[1]; 00145 i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00146 reg[0] = reg[0] | MAX30100_MC_SHDN; 00147 i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00148 } 00149 00150 void resume(void){ 00151 char reg[1]; 00152 i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00153 reg[0] = reg[0] & ~MAX30100_MC_SHDN; 00154 i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00155 } 00156 00157 void update(void){ 00158 readFifoData(); 00159 } 00160 00161 void printRegisters(void){ 00162 char reg[1]; 00163 i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, ®[0], 1); 00164 pc.printf("MAX30100_INT_STATUS: %d\r\n",reg[0]); 00165 i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, ®[0], 1); 00166 pc.printf("MAX30100_INT_ENABLE: %d\r\n",reg[0]); 00167 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, ®[0], 1); 00168 pc.printf("MAX30100_FIFO_WR_PTR: %d\r\n",reg[0]); 00169 i2c_read(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR, ®[0], 1); 00170 pc.printf("MAX30100_OVRFLOW_CTR: %d\r\n",reg[0]); 00171 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, ®[0], 1); 00172 pc.printf("MAX30100_FIFO_RD_PTR: %d\r\n",reg[0]); 00173 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, ®[0], 1); 00174 pc.printf("MAX30100_FIFO_DATA: %d\r\n",reg[0]); 00175 i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00176 pc.printf("MAX30100_MODE_CONFIG: %d\r\n",reg[0]); 00177 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00178 pc.printf("MAX30100_SPO2_CONFIG: %d\r\n",reg[0]); 00179 i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); 00180 pc.printf("MAX30100_LED_CONFIG: %d\r\n",reg[0]); 00181 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, ®[0], 1); 00182 pc.printf("MAX30100_TEMP_INTG: %d\r\n",reg[0]); 00183 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, ®[0], 1); 00184 pc.printf("MAX30100_TEMP_FRAC: %d\r\n",reg[0]); 00185 i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, ®[0], 1); 00186 pc.printf("MAX30100_REV_ID: %d\r\n",reg[0]); 00187 i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, ®[0], 1); 00188 pc.printf("MAX30100_PART_ID: %d\r\n",reg[0]); 00189 } 00190 00191 bool begin(){ 00192 if(getPartID() != POR_PART_ID){ 00193 return false; 00194 } 00195 setMode(DEFAULT_MODE); 00196 setLedsPulseWidth(DEFAULT_PULSE_WIDTH); 00197 setSamplingRate(DEFAULT_SAMPLING_RATE); 00198 setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT); 00199 setHighresModeEnabled(true); 00200 00201 return true; 00202 } 00203 00204 void setMode(Mode mode){ 00205 char reg[1]; 00206 reg[0] = mode; 00207 i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00208 } 00209 00210 void setLedsPulseWidth(LEDPulseWidth ledPulseWidth){ 00211 char reg[1]; 00212 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00213 reg[0] = (reg[0] & 0xfc) | ledPulseWidth; 00214 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00215 } 00216 00217 void setSamplingRate(SamplingRate samplingRate){ 00218 char reg[1]; 00219 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00220 reg[0] = (reg[0] & 0xe3) | (samplingRate << 2); 00221 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00222 } 00223 00224 void setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent){ 00225 char reg[1]; 00226 reg[0] = (redLedCurrent << 4) | irLedCurrent; 00227 i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ®[0], 1); 00228 } 00229 00230 void setHighresModeEnabled(bool enabled){ 00231 char reg[1]; 00232 i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00233 if(enabled){ 00234 reg[0] = reg[0] | MAX30100_SPC_SPO2_HI_RES_EN; 00235 } 00236 else{ 00237 reg[0] = reg[0] & ~MAX30100_SPC_SPO2_HI_RES_EN; 00238 } 00239 i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, ®[0], 1); 00240 } 00241 00242 void readFifoData(void){ 00243 char reg[4]; 00244 i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, ®[0], 4); 00245 rawIRValue = (reg[0] << 8) | reg[1]; 00246 rawRedValue = (reg[2] << 8) | reg[3]; 00247 } 00248 00249 void startTemperatureSampling(void){ 00250 char reg[1]; 00251 i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00252 reg[0] = reg[0] | MAX30100_MC_TEMP_EN; 00253 i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00254 } 00255 00256 bool isTemperatureReady(void){ 00257 char reg[1]; 00258 bool ret; 00259 ret = i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, ®[0], 1); 00260 ret = ret & MAX30100_MC_TEMP_EN; 00261 return !ret; 00262 } 00263 00264 float retrieveTemperature(void){ 00265 char reg[2]; 00266 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, ®[0], 1); 00267 i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, ®[1], 1); 00268 return reg[0] + (reg[1] * 0.0625); 00269 } 00270 00271 }; 00272 #endif
Generated on Tue Jul 12 2022 19:32:30 by
1.7.2