maxrefdes117

Committer:
zinnetyazicii53
Date:
Tue Aug 06 12:19:46 2019 +0000
Revision:
0:78a2573ad768
commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zinnetyazicii53 0:78a2573ad768 1
zinnetyazicii53 0:78a2573ad768 2 #include "mbed.h"
zinnetyazicii53 0:78a2573ad768 3 #include "MAX30105.h"
zinnetyazicii53 0:78a2573ad768 4 #include "millis.h"
zinnetyazicii53 0:78a2573ad768 5
zinnetyazicii53 0:78a2573ad768 6
zinnetyazicii53 0:78a2573ad768 7 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 8
zinnetyazicii53 0:78a2573ad768 9 MAX30105::MAX30105(I2C &i2c): _i2c(i2c)
zinnetyazicii53 0:78a2573ad768 10 {
zinnetyazicii53 0:78a2573ad768 11 }
zinnetyazicii53 0:78a2573ad768 12
zinnetyazicii53 0:78a2573ad768 13 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 14
zinnetyazicii53 0:78a2573ad768 15 int MAX30105::writeRegValue(uint8_t reg, char value)
zinnetyazicii53 0:78a2573ad768 16 {
zinnetyazicii53 0:78a2573ad768 17 char cmdData[2] = { (char)reg, value };
zinnetyazicii53 0:78a2573ad768 18
zinnetyazicii53 0:78a2573ad768 19 if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) {
zinnetyazicii53 0:78a2573ad768 20 return MAX30105_ERROR;
zinnetyazicii53 0:78a2573ad768 21 }
zinnetyazicii53 0:78a2573ad768 22
zinnetyazicii53 0:78a2573ad768 23 return MAX30105_NO_ERROR;
zinnetyazicii53 0:78a2573ad768 24 }
zinnetyazicii53 0:78a2573ad768 25
zinnetyazicii53 0:78a2573ad768 26 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 27
zinnetyazicii53 0:78a2573ad768 28 int MAX30105::writeReg(uint8_t reg )
zinnetyazicii53 0:78a2573ad768 29 {
zinnetyazicii53 0:78a2573ad768 30 char cmdData[1] = { (char)reg };
zinnetyazicii53 0:78a2573ad768 31
zinnetyazicii53 0:78a2573ad768 32 if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) {
zinnetyazicii53 0:78a2573ad768 33 return MAX30105_ERROR;
zinnetyazicii53 0:78a2573ad768 34 }
zinnetyazicii53 0:78a2573ad768 35
zinnetyazicii53 0:78a2573ad768 36 return MAX30105_NO_ERROR;
zinnetyazicii53 0:78a2573ad768 37 }
zinnetyazicii53 0:78a2573ad768 38
zinnetyazicii53 0:78a2573ad768 39
zinnetyazicii53 0:78a2573ad768 40 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 41
zinnetyazicii53 0:78a2573ad768 42 int MAX30105::readReg(uint8_t reg, char *value)
zinnetyazicii53 0:78a2573ad768 43 {
zinnetyazicii53 0:78a2573ad768 44 char cmdData[1] = { (char)reg };
zinnetyazicii53 0:78a2573ad768 45
zinnetyazicii53 0:78a2573ad768 46 if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) {
zinnetyazicii53 0:78a2573ad768 47 return MAX30105_ERROR;
zinnetyazicii53 0:78a2573ad768 48 }
zinnetyazicii53 0:78a2573ad768 49
zinnetyazicii53 0:78a2573ad768 50 if (_i2c.read(MAX30105_ADDRESS, value, 1) != 0) {
zinnetyazicii53 0:78a2573ad768 51 return MAX30105_ERROR;
zinnetyazicii53 0:78a2573ad768 52 }
zinnetyazicii53 0:78a2573ad768 53
zinnetyazicii53 0:78a2573ad768 54 return MAX30105_NO_ERROR;
zinnetyazicii53 0:78a2573ad768 55 }
zinnetyazicii53 0:78a2573ad768 56
zinnetyazicii53 0:78a2573ad768 57
zinnetyazicii53 0:78a2573ad768 58 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 59
zinnetyazicii53 0:78a2573ad768 60 uint8_t MAX30105::readRegister8(uint8_t address, uint8_t reg){
zinnetyazicii53 0:78a2573ad768 61 _i2c.write(reg);
zinnetyazicii53 0:78a2573ad768 62 char *data = new char[5];
zinnetyazicii53 0:78a2573ad768 63 _i2c.read(address,data,5);
zinnetyazicii53 0:78a2573ad768 64 return (uint8_t)data;
zinnetyazicii53 0:78a2573ad768 65
zinnetyazicii53 0:78a2573ad768 66 }
zinnetyazicii53 0:78a2573ad768 67
zinnetyazicii53 0:78a2573ad768 68
zinnetyazicii53 0:78a2573ad768 69 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 70 void MAX30105::writeRegister8(uint8_t address, uint8_t reg, uint8_t value){
zinnetyazicii53 0:78a2573ad768 71
zinnetyazicii53 0:78a2573ad768 72 writeRegValue(reg, value);
zinnetyazicii53 0:78a2573ad768 73
zinnetyazicii53 0:78a2573ad768 74 }
zinnetyazicii53 0:78a2573ad768 75
zinnetyazicii53 0:78a2573ad768 76
zinnetyazicii53 0:78a2573ad768 77 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 78
zinnetyazicii53 0:78a2573ad768 79 bool MAX30105::safeCheck(uint8_t maxTimeToCheck)
zinnetyazicii53 0:78a2573ad768 80 {
zinnetyazicii53 0:78a2573ad768 81 uint32_t markTime = millis();
zinnetyazicii53 0:78a2573ad768 82
zinnetyazicii53 0:78a2573ad768 83 while(1)
zinnetyazicii53 0:78a2573ad768 84 {
zinnetyazicii53 0:78a2573ad768 85 if(millis() - markTime > maxTimeToCheck) return(false);
zinnetyazicii53 0:78a2573ad768 86
zinnetyazicii53 0:78a2573ad768 87 if(check() == true) //We found new data!
zinnetyazicii53 0:78a2573ad768 88 return(true);
zinnetyazicii53 0:78a2573ad768 89
zinnetyazicii53 0:78a2573ad768 90 wait(1);
zinnetyazicii53 0:78a2573ad768 91 }
zinnetyazicii53 0:78a2573ad768 92 }
zinnetyazicii53 0:78a2573ad768 93
zinnetyazicii53 0:78a2573ad768 94
zinnetyazicii53 0:78a2573ad768 95 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 96
zinnetyazicii53 0:78a2573ad768 97 // NOTE: Amplitude values: 0x00 = 0mA, 0x7F = 25.4mA, 0xFF = 50mA (typical)
zinnetyazicii53 0:78a2573ad768 98 // See datasheet, page 21
zinnetyazicii53 0:78a2573ad768 99 void MAX30105::setPulseAmplitudeRed(uint8_t amplitude) {
zinnetyazicii53 0:78a2573ad768 100 writeRegister8(_i2caddr, MAX30105_LED1_PULSEAMP, amplitude);
zinnetyazicii53 0:78a2573ad768 101 }
zinnetyazicii53 0:78a2573ad768 102
zinnetyazicii53 0:78a2573ad768 103
zinnetyazicii53 0:78a2573ad768 104 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 105
zinnetyazicii53 0:78a2573ad768 106 void MAX30105::setPulseAmplitudeIR(uint8_t amplitude) {
zinnetyazicii53 0:78a2573ad768 107 writeRegister8(_i2caddr, MAX30105_LED2_PULSEAMP, amplitude);
zinnetyazicii53 0:78a2573ad768 108 }
zinnetyazicii53 0:78a2573ad768 109
zinnetyazicii53 0:78a2573ad768 110
zinnetyazicii53 0:78a2573ad768 111 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 112
zinnetyazicii53 0:78a2573ad768 113 void MAX30105::setPulseAmplitudeGreen(uint8_t amplitude) {
zinnetyazicii53 0:78a2573ad768 114 writeRegister8(_i2caddr, MAX30105_LED3_PULSEAMP, amplitude);
zinnetyazicii53 0:78a2573ad768 115
zinnetyazicii53 0:78a2573ad768 116
zinnetyazicii53 0:78a2573ad768 117 }
zinnetyazicii53 0:78a2573ad768 118 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 119
zinnetyazicii53 0:78a2573ad768 120 void MAX30105::setPulseAmplitudeProximity(uint8_t amplitude) {
zinnetyazicii53 0:78a2573ad768 121 writeRegister8(_i2caddr, MAX30105_LED_PROX_AMP, amplitude);
zinnetyazicii53 0:78a2573ad768 122 }
zinnetyazicii53 0:78a2573ad768 123 //Begin Interrupt configuration
zinnetyazicii53 0:78a2573ad768 124
zinnetyazicii53 0:78a2573ad768 125
zinnetyazicii53 0:78a2573ad768 126 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 127
zinnetyazicii53 0:78a2573ad768 128 uint8_t MAX30105::getINT1(void) {
zinnetyazicii53 0:78a2573ad768 129 return (readRegister8(_i2caddr, MAX30105_INTSTAT1));
zinnetyazicii53 0:78a2573ad768 130 }
zinnetyazicii53 0:78a2573ad768 131
zinnetyazicii53 0:78a2573ad768 132 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 133
zinnetyazicii53 0:78a2573ad768 134 uint8_t MAX30105::getINT2(void) {
zinnetyazicii53 0:78a2573ad768 135 return (readRegister8(_i2caddr, MAX30105_INTSTAT2));
zinnetyazicii53 0:78a2573ad768 136 }
zinnetyazicii53 0:78a2573ad768 137
zinnetyazicii53 0:78a2573ad768 138
zinnetyazicii53 0:78a2573ad768 139 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 140
zinnetyazicii53 0:78a2573ad768 141 void MAX30105::enableAFULL(void) {
zinnetyazicii53 0:78a2573ad768 142 bitMask(MAX30105_INTENABLE1, MAX30105_INT_A_FULL_MASK, MAX30105_INT_A_FULL_ENABLE);
zinnetyazicii53 0:78a2573ad768 143 }
zinnetyazicii53 0:78a2573ad768 144
zinnetyazicii53 0:78a2573ad768 145
zinnetyazicii53 0:78a2573ad768 146 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 147
zinnetyazicii53 0:78a2573ad768 148 void MAX30105::disableAFULL(void) {
zinnetyazicii53 0:78a2573ad768 149 bitMask(MAX30105_INTENABLE1, MAX30105_INT_A_FULL_MASK, MAX30105_INT_A_FULL_DISABLE);
zinnetyazicii53 0:78a2573ad768 150 }
zinnetyazicii53 0:78a2573ad768 151
zinnetyazicii53 0:78a2573ad768 152
zinnetyazicii53 0:78a2573ad768 153 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 154
zinnetyazicii53 0:78a2573ad768 155 void MAX30105::enableDATARDY(void) {
zinnetyazicii53 0:78a2573ad768 156 bitMask(MAX30105_INTENABLE1, MAX30105_INT_DATA_RDY_MASK, MAX30105_INT_DATA_RDY_ENABLE);
zinnetyazicii53 0:78a2573ad768 157 }
zinnetyazicii53 0:78a2573ad768 158
zinnetyazicii53 0:78a2573ad768 159 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 160
zinnetyazicii53 0:78a2573ad768 161 void MAX30105::disableDATARDY(void) {
zinnetyazicii53 0:78a2573ad768 162 bitMask(MAX30105_INTENABLE1, MAX30105_INT_DATA_RDY_MASK, MAX30105_INT_DATA_RDY_DISABLE);
zinnetyazicii53 0:78a2573ad768 163 }
zinnetyazicii53 0:78a2573ad768 164
zinnetyazicii53 0:78a2573ad768 165
zinnetyazicii53 0:78a2573ad768 166 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 167
zinnetyazicii53 0:78a2573ad768 168 void MAX30105::enableALCOVF(void) {
zinnetyazicii53 0:78a2573ad768 169 bitMask(MAX30105_INTENABLE1, MAX30105_INT_ALC_OVF_MASK, MAX30105_INT_ALC_OVF_ENABLE);
zinnetyazicii53 0:78a2573ad768 170 }
zinnetyazicii53 0:78a2573ad768 171
zinnetyazicii53 0:78a2573ad768 172 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 173
zinnetyazicii53 0:78a2573ad768 174 void MAX30105::disableALCOVF(void) {
zinnetyazicii53 0:78a2573ad768 175 bitMask(MAX30105_INTENABLE1, MAX30105_INT_ALC_OVF_MASK, MAX30105_INT_ALC_OVF_DISABLE);
zinnetyazicii53 0:78a2573ad768 176 }
zinnetyazicii53 0:78a2573ad768 177
zinnetyazicii53 0:78a2573ad768 178
zinnetyazicii53 0:78a2573ad768 179 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 180
zinnetyazicii53 0:78a2573ad768 181 void MAX30105::enablePROXINT(void) {
zinnetyazicii53 0:78a2573ad768 182 bitMask(MAX30105_INTENABLE1, MAX30105_INT_PROX_INT_MASK, MAX30105_INT_PROX_INT_ENABLE);
zinnetyazicii53 0:78a2573ad768 183 }
zinnetyazicii53 0:78a2573ad768 184
zinnetyazicii53 0:78a2573ad768 185 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 186
zinnetyazicii53 0:78a2573ad768 187 void MAX30105::disablePROXINT(void) {
zinnetyazicii53 0:78a2573ad768 188 bitMask(MAX30105_INTENABLE1, MAX30105_INT_PROX_INT_MASK, MAX30105_INT_PROX_INT_DISABLE);
zinnetyazicii53 0:78a2573ad768 189 }
zinnetyazicii53 0:78a2573ad768 190
zinnetyazicii53 0:78a2573ad768 191
zinnetyazicii53 0:78a2573ad768 192 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 193
zinnetyazicii53 0:78a2573ad768 194 void MAX30105::enableDIETEMPRDY(void) {
zinnetyazicii53 0:78a2573ad768 195 bitMask(MAX30105_INTENABLE2, MAX30105_INT_DIE_TEMP_RDY_MASK, MAX30105_INT_DIE_TEMP_RDY_ENABLE);
zinnetyazicii53 0:78a2573ad768 196 }
zinnetyazicii53 0:78a2573ad768 197
zinnetyazicii53 0:78a2573ad768 198 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 199
zinnetyazicii53 0:78a2573ad768 200 void MAX30105::disableDIETEMPRDY(void) {
zinnetyazicii53 0:78a2573ad768 201 bitMask(MAX30105_INTENABLE2, MAX30105_INT_DIE_TEMP_RDY_MASK, MAX30105_INT_DIE_TEMP_RDY_DISABLE);
zinnetyazicii53 0:78a2573ad768 202 }
zinnetyazicii53 0:78a2573ad768 203
zinnetyazicii53 0:78a2573ad768 204 //End Interrupt configuration
zinnetyazicii53 0:78a2573ad768 205 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 206
zinnetyazicii53 0:78a2573ad768 207 void MAX30105::softReset(void) {
zinnetyazicii53 0:78a2573ad768 208 bitMask(MAX30105_MODECONFIG, MAX30105_RESET_MASK, MAX30105_RESET);
zinnetyazicii53 0:78a2573ad768 209
zinnetyazicii53 0:78a2573ad768 210 // Poll for bit to clear, reset is then complete
zinnetyazicii53 0:78a2573ad768 211 // Timeout after 100ms
zinnetyazicii53 0:78a2573ad768 212 unsigned long startTime = millis();
zinnetyazicii53 0:78a2573ad768 213 while (millis() - startTime < 100)
zinnetyazicii53 0:78a2573ad768 214 {
zinnetyazicii53 0:78a2573ad768 215 uint8_t response = readRegister8(_i2caddr, MAX30105_MODECONFIG);
zinnetyazicii53 0:78a2573ad768 216 if ((response & MAX30105_RESET) == 0) break; //We're done!
zinnetyazicii53 0:78a2573ad768 217 wait(1); //Let's not over burden the I2C bus
zinnetyazicii53 0:78a2573ad768 218 }
zinnetyazicii53 0:78a2573ad768 219 }
zinnetyazicii53 0:78a2573ad768 220
zinnetyazicii53 0:78a2573ad768 221 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 222
zinnetyazicii53 0:78a2573ad768 223 void MAX30105::shutDown(void) {
zinnetyazicii53 0:78a2573ad768 224 // Put IC into low power mode (datasheet pg. 19)
zinnetyazicii53 0:78a2573ad768 225 // During shutdown the IC will continue to respond to I2C commands but will
zinnetyazicii53 0:78a2573ad768 226 // not update with or take new readings (such as temperature)
zinnetyazicii53 0:78a2573ad768 227 bitMask(MAX30105_MODECONFIG, MAX30105_SHUTDOWN_MASK, MAX30105_SHUTDOWN);
zinnetyazicii53 0:78a2573ad768 228 }
zinnetyazicii53 0:78a2573ad768 229
zinnetyazicii53 0:78a2573ad768 230
zinnetyazicii53 0:78a2573ad768 231 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 232
zinnetyazicii53 0:78a2573ad768 233 void MAX30105::wakeUp(void) {
zinnetyazicii53 0:78a2573ad768 234 // Pull IC out of low power mode (datasheet pg. 19)
zinnetyazicii53 0:78a2573ad768 235 bitMask(MAX30105_MODECONFIG, MAX30105_SHUTDOWN_MASK, MAX30105_WAKEUP);
zinnetyazicii53 0:78a2573ad768 236 }
zinnetyazicii53 0:78a2573ad768 237
zinnetyazicii53 0:78a2573ad768 238
zinnetyazicii53 0:78a2573ad768 239 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 240
zinnetyazicii53 0:78a2573ad768 241 void MAX30105::setLEDMode(uint8_t mode) {
zinnetyazicii53 0:78a2573ad768 242 // Set which LEDs are used for sampling -- Red only, RED+IR only, or custom.
zinnetyazicii53 0:78a2573ad768 243 // See datasheet, page 19
zinnetyazicii53 0:78a2573ad768 244 bitMask(MAX30105_MODECONFIG, MAX30105_MODE_MASK, mode);
zinnetyazicii53 0:78a2573ad768 245 }
zinnetyazicii53 0:78a2573ad768 246
zinnetyazicii53 0:78a2573ad768 247
zinnetyazicii53 0:78a2573ad768 248 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 249
zinnetyazicii53 0:78a2573ad768 250 void MAX30105::setADCRange(uint8_t adcRange) {
zinnetyazicii53 0:78a2573ad768 251 // adcRange: one of MAX30105_ADCRANGE_2048, _4096, _8192, _16384
zinnetyazicii53 0:78a2573ad768 252 bitMask(MAX30105_PARTICLECONFIG, MAX30105_ADCRANGE_MASK, adcRange);
zinnetyazicii53 0:78a2573ad768 253 }
zinnetyazicii53 0:78a2573ad768 254
zinnetyazicii53 0:78a2573ad768 255
zinnetyazicii53 0:78a2573ad768 256 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 257
zinnetyazicii53 0:78a2573ad768 258 void MAX30105::setSampleRate(uint8_t sampleRate) {
zinnetyazicii53 0:78a2573ad768 259 // sampleRate: one of MAX30105_SAMPLERATE_50, _100, _200, _400, _800, _1000, _1600, _3200
zinnetyazicii53 0:78a2573ad768 260 bitMask(MAX30105_PARTICLECONFIG, MAX30105_SAMPLERATE_MASK, sampleRate);
zinnetyazicii53 0:78a2573ad768 261 }
zinnetyazicii53 0:78a2573ad768 262
zinnetyazicii53 0:78a2573ad768 263
zinnetyazicii53 0:78a2573ad768 264 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 265
zinnetyazicii53 0:78a2573ad768 266 void MAX30105::setPulseWidth(uint8_t pulseWidth) {
zinnetyazicii53 0:78a2573ad768 267 // pulseWidth: one of MAX30105_PULSEWIDTH_69, _188, _215, _411
zinnetyazicii53 0:78a2573ad768 268 bitMask(MAX30105_PARTICLECONFIG, MAX30105_PULSEWIDTH_MASK, pulseWidth);
zinnetyazicii53 0:78a2573ad768 269 }
zinnetyazicii53 0:78a2573ad768 270
zinnetyazicii53 0:78a2573ad768 271
zinnetyazicii53 0:78a2573ad768 272 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 273
zinnetyazicii53 0:78a2573ad768 274 void MAX30105::enableSlot(uint8_t slotNumber, uint8_t device) {
zinnetyazicii53 0:78a2573ad768 275
zinnetyazicii53 0:78a2573ad768 276 uint8_t originalContents;
zinnetyazicii53 0:78a2573ad768 277
zinnetyazicii53 0:78a2573ad768 278 switch (slotNumber) {
zinnetyazicii53 0:78a2573ad768 279 case (1):
zinnetyazicii53 0:78a2573ad768 280 bitMask(MAX30105_MULTILEDCONFIG1, MAX30105_SLOT1_MASK, device);
zinnetyazicii53 0:78a2573ad768 281 break;
zinnetyazicii53 0:78a2573ad768 282 case (2):
zinnetyazicii53 0:78a2573ad768 283 bitMask(MAX30105_MULTILEDCONFIG1, MAX30105_SLOT2_MASK, device << 4);
zinnetyazicii53 0:78a2573ad768 284 break;
zinnetyazicii53 0:78a2573ad768 285 case (3):
zinnetyazicii53 0:78a2573ad768 286 bitMask(MAX30105_MULTILEDCONFIG2, MAX30105_SLOT3_MASK, device);
zinnetyazicii53 0:78a2573ad768 287 break;
zinnetyazicii53 0:78a2573ad768 288 case (4):
zinnetyazicii53 0:78a2573ad768 289 bitMask(MAX30105_MULTILEDCONFIG2, MAX30105_SLOT4_MASK, device << 4);
zinnetyazicii53 0:78a2573ad768 290 break;
zinnetyazicii53 0:78a2573ad768 291 default:
zinnetyazicii53 0:78a2573ad768 292 //Shouldn't be here!
zinnetyazicii53 0:78a2573ad768 293 break;
zinnetyazicii53 0:78a2573ad768 294 }
zinnetyazicii53 0:78a2573ad768 295 }
zinnetyazicii53 0:78a2573ad768 296
zinnetyazicii53 0:78a2573ad768 297
zinnetyazicii53 0:78a2573ad768 298 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 299
zinnetyazicii53 0:78a2573ad768 300 void MAX30105::disableSlots(void) {
zinnetyazicii53 0:78a2573ad768 301 writeRegister8(_i2caddr, MAX30105_MULTILEDCONFIG1, 0);
zinnetyazicii53 0:78a2573ad768 302 writeRegister8(_i2caddr, MAX30105_MULTILEDCONFIG2, 0);
zinnetyazicii53 0:78a2573ad768 303 }
zinnetyazicii53 0:78a2573ad768 304
zinnetyazicii53 0:78a2573ad768 305 //
zinnetyazicii53 0:78a2573ad768 306 // FIFO Configuration
zinnetyazicii53 0:78a2573ad768 307 //
zinnetyazicii53 0:78a2573ad768 308
zinnetyazicii53 0:78a2573ad768 309
zinnetyazicii53 0:78a2573ad768 310 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 311
zinnetyazicii53 0:78a2573ad768 312 //Set sample average (Table 3, Page 18)
zinnetyazicii53 0:78a2573ad768 313 void MAX30105::setFIFOAverage(uint8_t numberOfSamples) {
zinnetyazicii53 0:78a2573ad768 314 bitMask(MAX30105_FIFOCONFIG, MAX30105_SAMPLEAVG_MASK, numberOfSamples);
zinnetyazicii53 0:78a2573ad768 315 }
zinnetyazicii53 0:78a2573ad768 316
zinnetyazicii53 0:78a2573ad768 317 //Resets all points to start in a known state
zinnetyazicii53 0:78a2573ad768 318 //Page 15 recommends clearing FIFO before beginning a read
zinnetyazicii53 0:78a2573ad768 319 void MAX30105::clearFIFO(void) {
zinnetyazicii53 0:78a2573ad768 320 writeRegister8(_i2caddr, MAX30105_FIFOWRITEPTR, 0);
zinnetyazicii53 0:78a2573ad768 321 writeRegister8(_i2caddr, MAX30105_FIFOOVERFLOW, 0);
zinnetyazicii53 0:78a2573ad768 322 writeRegister8(_i2caddr, MAX30105_FIFOREADPTR, 0);
zinnetyazicii53 0:78a2573ad768 323 }
zinnetyazicii53 0:78a2573ad768 324
zinnetyazicii53 0:78a2573ad768 325
zinnetyazicii53 0:78a2573ad768 326 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 327
zinnetyazicii53 0:78a2573ad768 328 //Enable roll over if FIFO over flows
zinnetyazicii53 0:78a2573ad768 329 void MAX30105::enableFIFORollover(void) {
zinnetyazicii53 0:78a2573ad768 330 bitMask(MAX30105_FIFOCONFIG, MAX30105_ROLLOVER_MASK, MAX30105_ROLLOVER_ENABLE);
zinnetyazicii53 0:78a2573ad768 331 }
zinnetyazicii53 0:78a2573ad768 332
zinnetyazicii53 0:78a2573ad768 333
zinnetyazicii53 0:78a2573ad768 334 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 335
zinnetyazicii53 0:78a2573ad768 336 //Disable roll over if FIFO over flows
zinnetyazicii53 0:78a2573ad768 337 void MAX30105::disableFIFORollover(void) {
zinnetyazicii53 0:78a2573ad768 338 bitMask(MAX30105_FIFOCONFIG, MAX30105_ROLLOVER_MASK, MAX30105_ROLLOVER_DISABLE);
zinnetyazicii53 0:78a2573ad768 339 }
zinnetyazicii53 0:78a2573ad768 340
zinnetyazicii53 0:78a2573ad768 341 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 342
zinnetyazicii53 0:78a2573ad768 343 //Set number of samples to trigger the almost full interrupt (Page 18)
zinnetyazicii53 0:78a2573ad768 344 //Power on default is 32 samples
zinnetyazicii53 0:78a2573ad768 345 //Note it is reverse: 0x00 is 32 samples, 0x0F is 17 samples
zinnetyazicii53 0:78a2573ad768 346 void MAX30105::setFIFOAlmostFull(uint8_t numberOfSamples) {
zinnetyazicii53 0:78a2573ad768 347 bitMask(MAX30105_FIFOCONFIG, MAX30105_A_FULL_MASK, numberOfSamples);
zinnetyazicii53 0:78a2573ad768 348 }
zinnetyazicii53 0:78a2573ad768 349
zinnetyazicii53 0:78a2573ad768 350 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 351
zinnetyazicii53 0:78a2573ad768 352 //Read the FIFO Write Pointer
zinnetyazicii53 0:78a2573ad768 353 uint8_t MAX30105::getWritePointer(void) {
zinnetyazicii53 0:78a2573ad768 354 return (readRegister8(_i2caddr, MAX30105_FIFOWRITEPTR));
zinnetyazicii53 0:78a2573ad768 355 }
zinnetyazicii53 0:78a2573ad768 356
zinnetyazicii53 0:78a2573ad768 357
zinnetyazicii53 0:78a2573ad768 358 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 359
zinnetyazicii53 0:78a2573ad768 360 //Read the FIFO Read Pointer
zinnetyazicii53 0:78a2573ad768 361 uint8_t MAX30105::getReadPointer(void) {
zinnetyazicii53 0:78a2573ad768 362 return (readRegister8(_i2caddr, MAX30105_FIFOREADPTR));
zinnetyazicii53 0:78a2573ad768 363 }
zinnetyazicii53 0:78a2573ad768 364
zinnetyazicii53 0:78a2573ad768 365 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 366
zinnetyazicii53 0:78a2573ad768 367 float MAX30105::readTemperature() {
zinnetyazicii53 0:78a2573ad768 368
zinnetyazicii53 0:78a2573ad768 369 //DIE_TEMP_RDY interrupt must be enabled
zinnetyazicii53 0:78a2573ad768 370 //See issue 19: https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/19
zinnetyazicii53 0:78a2573ad768 371
zinnetyazicii53 0:78a2573ad768 372 // Step 1: Config die temperature register to take 1 temperature sample
zinnetyazicii53 0:78a2573ad768 373 writeRegister8(_i2caddr, MAX30105_DIETEMPCONFIG, 0x01);
zinnetyazicii53 0:78a2573ad768 374
zinnetyazicii53 0:78a2573ad768 375 // Poll for bit to clear, reading is then complete
zinnetyazicii53 0:78a2573ad768 376 // Timeout after 100ms
zinnetyazicii53 0:78a2573ad768 377 unsigned long startTime = millis();
zinnetyazicii53 0:78a2573ad768 378 while (millis() - startTime < 100)
zinnetyazicii53 0:78a2573ad768 379 {
zinnetyazicii53 0:78a2573ad768 380 //uint8_t response = readRegister8(_i2caddr, MAX30105_DIETEMPCONFIG); //Original way
zinnetyazicii53 0:78a2573ad768 381 //if ((response & 0x01) == 0) break; //We're done!
zinnetyazicii53 0:78a2573ad768 382
zinnetyazicii53 0:78a2573ad768 383 //Check to see if DIE_TEMP_RDY interrupt is set
zinnetyazicii53 0:78a2573ad768 384 uint8_t response = readRegister8(_i2caddr, MAX30105_INTSTAT2);
zinnetyazicii53 0:78a2573ad768 385 if ((response & MAX30105_INT_DIE_TEMP_RDY_ENABLE) > 0) break; //We're done!
zinnetyazicii53 0:78a2573ad768 386 wait(1); //Let's not over burden the I2C bus
zinnetyazicii53 0:78a2573ad768 387 }
zinnetyazicii53 0:78a2573ad768 388 //TODO How do we want to fail? With what type of error?
zinnetyazicii53 0:78a2573ad768 389 //? if(millis() - startTime >= 100) return(-999.0);
zinnetyazicii53 0:78a2573ad768 390
zinnetyazicii53 0:78a2573ad768 391 // Step 2: Read die temperature register (integer)
zinnetyazicii53 0:78a2573ad768 392 int8_t tempInt = readRegister8(_i2caddr, MAX30105_DIETEMPINT);
zinnetyazicii53 0:78a2573ad768 393 uint8_t tempFrac = readRegister8(_i2caddr, MAX30105_DIETEMPFRAC); //Causes the clearing of the DIE_TEMP_RDY interrupt
zinnetyazicii53 0:78a2573ad768 394
zinnetyazicii53 0:78a2573ad768 395 // Step 3: Calculate temperature (datasheet pg. 23)
zinnetyazicii53 0:78a2573ad768 396 return (float)tempInt + ((float)tempFrac * 0.0625);
zinnetyazicii53 0:78a2573ad768 397 }
zinnetyazicii53 0:78a2573ad768 398
zinnetyazicii53 0:78a2573ad768 399
zinnetyazicii53 0:78a2573ad768 400 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 401
zinnetyazicii53 0:78a2573ad768 402
zinnetyazicii53 0:78a2573ad768 403 // Returns die temp in F
zinnetyazicii53 0:78a2573ad768 404 float MAX30105::readTemperatureF() {
zinnetyazicii53 0:78a2573ad768 405 float temp = readTemperature();
zinnetyazicii53 0:78a2573ad768 406
zinnetyazicii53 0:78a2573ad768 407 if (temp != -999.0) temp = temp * 1.8 + 32.0;
zinnetyazicii53 0:78a2573ad768 408
zinnetyazicii53 0:78a2573ad768 409 return (temp);
zinnetyazicii53 0:78a2573ad768 410 }
zinnetyazicii53 0:78a2573ad768 411
zinnetyazicii53 0:78a2573ad768 412
zinnetyazicii53 0:78a2573ad768 413 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 414
zinnetyazicii53 0:78a2573ad768 415
zinnetyazicii53 0:78a2573ad768 416 // Set the PROX_INT_THRESHold
zinnetyazicii53 0:78a2573ad768 417 void MAX30105::setPROXINTTHRESH(uint8_t val) {
zinnetyazicii53 0:78a2573ad768 418 writeRegister8(_i2caddr, MAX30105_PROXINTTHRESH, val);
zinnetyazicii53 0:78a2573ad768 419 }
zinnetyazicii53 0:78a2573ad768 420
zinnetyazicii53 0:78a2573ad768 421
zinnetyazicii53 0:78a2573ad768 422 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 423
zinnetyazicii53 0:78a2573ad768 424
zinnetyazicii53 0:78a2573ad768 425 //
zinnetyazicii53 0:78a2573ad768 426 // Device ID and Revision
zinnetyazicii53 0:78a2573ad768 427 //
zinnetyazicii53 0:78a2573ad768 428 uint8_t MAX30105::readPartID() {
zinnetyazicii53 0:78a2573ad768 429 return readRegister8(_i2caddr, MAX30105_PARTID);
zinnetyazicii53 0:78a2573ad768 430 }
zinnetyazicii53 0:78a2573ad768 431
zinnetyazicii53 0:78a2573ad768 432
zinnetyazicii53 0:78a2573ad768 433 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 434
zinnetyazicii53 0:78a2573ad768 435
zinnetyazicii53 0:78a2573ad768 436 void MAX30105::readRevisionID() {
zinnetyazicii53 0:78a2573ad768 437 revisionID = readRegister8(_i2caddr, MAX30105_REVISIONID);
zinnetyazicii53 0:78a2573ad768 438 }
zinnetyazicii53 0:78a2573ad768 439
zinnetyazicii53 0:78a2573ad768 440 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 441
zinnetyazicii53 0:78a2573ad768 442
zinnetyazicii53 0:78a2573ad768 443 uint8_t MAX30105::getRevisionID() {
zinnetyazicii53 0:78a2573ad768 444 return revisionID;
zinnetyazicii53 0:78a2573ad768 445 }
zinnetyazicii53 0:78a2573ad768 446
zinnetyazicii53 0:78a2573ad768 447 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 448
zinnetyazicii53 0:78a2573ad768 449
zinnetyazicii53 0:78a2573ad768 450
zinnetyazicii53 0:78a2573ad768 451 //Setup the sensor
zinnetyazicii53 0:78a2573ad768 452 //The MAX30105 has many settings. By default we select:
zinnetyazicii53 0:78a2573ad768 453 // Sample Average = 4
zinnetyazicii53 0:78a2573ad768 454 // Mode = MultiLED
zinnetyazicii53 0:78a2573ad768 455 // ADC Range = 16384 (62.5pA per LSB)
zinnetyazicii53 0:78a2573ad768 456 // Sample rate = 50
zinnetyazicii53 0:78a2573ad768 457 //Use the default setup if you are just getting started with the MAX30105 sensor
zinnetyazicii53 0:78a2573ad768 458 void MAX30105::setup(uint8_t powerLevel, uint8_t sampleAverage, uint8_t ledMode, int sampleRate, int pulseWidth, int adcRange) {
zinnetyazicii53 0:78a2573ad768 459 softReset(); //Reset all configuration, threshold, and data registers to POR values
zinnetyazicii53 0:78a2573ad768 460
zinnetyazicii53 0:78a2573ad768 461 //FIFO Configuration
zinnetyazicii53 0:78a2573ad768 462 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 463 //The chip will average multiple samples of same type together if you wish
zinnetyazicii53 0:78a2573ad768 464 if (sampleAverage == 1) setFIFOAverage(MAX30105_SAMPLEAVG_1); //No averaging per FIFO record
zinnetyazicii53 0:78a2573ad768 465 else if (sampleAverage == 2) setFIFOAverage(MAX30105_SAMPLEAVG_2);
zinnetyazicii53 0:78a2573ad768 466 else if (sampleAverage == 4) setFIFOAverage(MAX30105_SAMPLEAVG_4);
zinnetyazicii53 0:78a2573ad768 467 else if (sampleAverage == 8) setFIFOAverage(MAX30105_SAMPLEAVG_8);
zinnetyazicii53 0:78a2573ad768 468 else if (sampleAverage == 16) setFIFOAverage(MAX30105_SAMPLEAVG_16);
zinnetyazicii53 0:78a2573ad768 469 else if (sampleAverage == 32) setFIFOAverage(MAX30105_SAMPLEAVG_32);
zinnetyazicii53 0:78a2573ad768 470 else setFIFOAverage(MAX30105_SAMPLEAVG_4);
zinnetyazicii53 0:78a2573ad768 471
zinnetyazicii53 0:78a2573ad768 472 //setFIFOAlmostFull(2); //Set to 30 samples to trigger an 'Almost Full' interrupt
zinnetyazicii53 0:78a2573ad768 473 enableFIFORollover(); //Allow FIFO to wrap/roll over
zinnetyazicii53 0:78a2573ad768 474 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 475
zinnetyazicii53 0:78a2573ad768 476 //Mode Configuration
zinnetyazicii53 0:78a2573ad768 477 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 478 if (ledMode == 3) setLEDMode(MAX30105_MODE_MULTILED); //Watch all three LED channels
zinnetyazicii53 0:78a2573ad768 479 else if (ledMode == 2) setLEDMode(MAX30105_MODE_REDIRONLY); //Red and IR
zinnetyazicii53 0:78a2573ad768 480 else setLEDMode(MAX30105_MODE_REDONLY); //Red only
zinnetyazicii53 0:78a2573ad768 481 activeLEDs = ledMode; //Used to control how many uint8_ts to read from FIFO buffer
zinnetyazicii53 0:78a2573ad768 482 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 483
zinnetyazicii53 0:78a2573ad768 484 //Particle Sensing Configuration
zinnetyazicii53 0:78a2573ad768 485 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 486 if(adcRange < 4096) setADCRange(MAX30105_ADCRANGE_2048); //7.81pA per LSB
zinnetyazicii53 0:78a2573ad768 487 else if(adcRange < 8192) setADCRange(MAX30105_ADCRANGE_4096); //15.63pA per LSB
zinnetyazicii53 0:78a2573ad768 488 else if(adcRange < 16384) setADCRange(MAX30105_ADCRANGE_8192); //31.25pA per LSB
zinnetyazicii53 0:78a2573ad768 489 else if(adcRange == 16384) setADCRange(MAX30105_ADCRANGE_16384); //62.5pA per LSB
zinnetyazicii53 0:78a2573ad768 490 else setADCRange(MAX30105_ADCRANGE_2048);
zinnetyazicii53 0:78a2573ad768 491
zinnetyazicii53 0:78a2573ad768 492 if (sampleRate < 100) setSampleRate(MAX30105_SAMPLERATE_50); //Take 50 samples per second
zinnetyazicii53 0:78a2573ad768 493 else if (sampleRate < 200) setSampleRate(MAX30105_SAMPLERATE_100);
zinnetyazicii53 0:78a2573ad768 494 else if (sampleRate < 400) setSampleRate(MAX30105_SAMPLERATE_200);
zinnetyazicii53 0:78a2573ad768 495 else if (sampleRate < 800) setSampleRate(MAX30105_SAMPLERATE_400);
zinnetyazicii53 0:78a2573ad768 496 else if (sampleRate < 1000) setSampleRate(MAX30105_SAMPLERATE_800);
zinnetyazicii53 0:78a2573ad768 497 else if (sampleRate < 1600) setSampleRate(MAX30105_SAMPLERATE_1000);
zinnetyazicii53 0:78a2573ad768 498 else if (sampleRate < 3200) setSampleRate(MAX30105_SAMPLERATE_1600);
zinnetyazicii53 0:78a2573ad768 499 else if (sampleRate == 3200) setSampleRate(MAX30105_SAMPLERATE_3200);
zinnetyazicii53 0:78a2573ad768 500 else setSampleRate(MAX30105_SAMPLERATE_50);
zinnetyazicii53 0:78a2573ad768 501
zinnetyazicii53 0:78a2573ad768 502 //The longer the pulse width the longer range of detection you'll have
zinnetyazicii53 0:78a2573ad768 503 //At 69us and 0.4mA it's about 2 inches
zinnetyazicii53 0:78a2573ad768 504 //At 411us and 0.4mA it's about 6 inches
zinnetyazicii53 0:78a2573ad768 505 if (pulseWidth < 118) setPulseWidth(MAX30105_PULSEWIDTH_69); //Page 26, Gets us 15 bit resolution
zinnetyazicii53 0:78a2573ad768 506 else if (pulseWidth < 215) setPulseWidth(MAX30105_PULSEWIDTH_118); //16 bit resolution
zinnetyazicii53 0:78a2573ad768 507 else if (pulseWidth < 411) setPulseWidth(MAX30105_PULSEWIDTH_215); //17 bit resolution
zinnetyazicii53 0:78a2573ad768 508 else if (pulseWidth == 411) setPulseWidth(MAX30105_PULSEWIDTH_411); //18 bit resolution
zinnetyazicii53 0:78a2573ad768 509 else setPulseWidth(MAX30105_PULSEWIDTH_69);
zinnetyazicii53 0:78a2573ad768 510 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 511
zinnetyazicii53 0:78a2573ad768 512 //LED Pulse Amplitude Configuration
zinnetyazicii53 0:78a2573ad768 513 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 514 //Default is 0x1F which gets us 6.4mA
zinnetyazicii53 0:78a2573ad768 515 //powerLevel = 0x02, 0.4mA - Presence detection of ~4 inch
zinnetyazicii53 0:78a2573ad768 516 //powerLevel = 0x1F, 6.4mA - Presence detection of ~8 inch
zinnetyazicii53 0:78a2573ad768 517 //powerLevel = 0x7F, 25.4mA - Presence detection of ~8 inch
zinnetyazicii53 0:78a2573ad768 518 //powerLevel = 0xFF, 50.0mA - Presence detection of ~12 inch
zinnetyazicii53 0:78a2573ad768 519
zinnetyazicii53 0:78a2573ad768 520 setPulseAmplitudeRed(powerLevel);
zinnetyazicii53 0:78a2573ad768 521 setPulseAmplitudeIR(powerLevel);
zinnetyazicii53 0:78a2573ad768 522 setPulseAmplitudeGreen(powerLevel);
zinnetyazicii53 0:78a2573ad768 523 setPulseAmplitudeProximity(powerLevel);
zinnetyazicii53 0:78a2573ad768 524 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 525
zinnetyazicii53 0:78a2573ad768 526 //Multi-LED Mode Configuration, Enable the reading of the three LEDs
zinnetyazicii53 0:78a2573ad768 527 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 528 enableSlot(1, SLOT_RED_LED);
zinnetyazicii53 0:78a2573ad768 529 if (ledMode > 1) enableSlot(2, SLOT_IR_LED);
zinnetyazicii53 0:78a2573ad768 530 if (ledMode > 2) enableSlot(3, SLOT_GREEN_LED);
zinnetyazicii53 0:78a2573ad768 531 //enableSlot(1, SLOT_RED_PILOT);
zinnetyazicii53 0:78a2573ad768 532 //enableSlot(2, SLOT_IR_PILOT);
zinnetyazicii53 0:78a2573ad768 533 //enableSlot(3, SLOT_GREEN_PILOT);
zinnetyazicii53 0:78a2573ad768 534 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
zinnetyazicii53 0:78a2573ad768 535
zinnetyazicii53 0:78a2573ad768 536 clearFIFO(); //Reset the FIFO before we begin checking the sensor
zinnetyazicii53 0:78a2573ad768 537 }
zinnetyazicii53 0:78a2573ad768 538
zinnetyazicii53 0:78a2573ad768 539 //
zinnetyazicii53 0:78a2573ad768 540 // Data Collection
zinnetyazicii53 0:78a2573ad768 541 //
zinnetyazicii53 0:78a2573ad768 542
zinnetyazicii53 0:78a2573ad768 543 //Tell caller how many samples are available
zinnetyazicii53 0:78a2573ad768 544 uint8_t MAX30105::available(void)
zinnetyazicii53 0:78a2573ad768 545 {
zinnetyazicii53 0:78a2573ad768 546 int8_t numberOfSamples = sense.head - sense.tail;
zinnetyazicii53 0:78a2573ad768 547 if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE;
zinnetyazicii53 0:78a2573ad768 548
zinnetyazicii53 0:78a2573ad768 549 return (numberOfSamples);
zinnetyazicii53 0:78a2573ad768 550 }
zinnetyazicii53 0:78a2573ad768 551
zinnetyazicii53 0:78a2573ad768 552 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 553
zinnetyazicii53 0:78a2573ad768 554
zinnetyazicii53 0:78a2573ad768 555 //Report the most recent red value
zinnetyazicii53 0:78a2573ad768 556 uint32_t MAX30105::getRed(void)
zinnetyazicii53 0:78a2573ad768 557 {
zinnetyazicii53 0:78a2573ad768 558 //Check the sensor for new data for 250ms
zinnetyazicii53 0:78a2573ad768 559 if(safeCheck(250))
zinnetyazicii53 0:78a2573ad768 560 return (sense.red[sense.head]);
zinnetyazicii53 0:78a2573ad768 561 else
zinnetyazicii53 0:78a2573ad768 562 return(0); //Sensor failed to find new data
zinnetyazicii53 0:78a2573ad768 563 }
zinnetyazicii53 0:78a2573ad768 564
zinnetyazicii53 0:78a2573ad768 565
zinnetyazicii53 0:78a2573ad768 566 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 567
zinnetyazicii53 0:78a2573ad768 568
zinnetyazicii53 0:78a2573ad768 569 //Report the most recent IR value
zinnetyazicii53 0:78a2573ad768 570 uint32_t MAX30105::getIR(void)
zinnetyazicii53 0:78a2573ad768 571 {
zinnetyazicii53 0:78a2573ad768 572 //Check the sensor for new data for 250ms
zinnetyazicii53 0:78a2573ad768 573 if(safeCheck(250))
zinnetyazicii53 0:78a2573ad768 574 return (sense.IR[sense.head]);
zinnetyazicii53 0:78a2573ad768 575 else
zinnetyazicii53 0:78a2573ad768 576 return(0); //Sensor failed to find new data
zinnetyazicii53 0:78a2573ad768 577 }
zinnetyazicii53 0:78a2573ad768 578
zinnetyazicii53 0:78a2573ad768 579 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 580
zinnetyazicii53 0:78a2573ad768 581
zinnetyazicii53 0:78a2573ad768 582 //Report the most recent Green value
zinnetyazicii53 0:78a2573ad768 583 uint32_t MAX30105::getGreen(void)
zinnetyazicii53 0:78a2573ad768 584 {
zinnetyazicii53 0:78a2573ad768 585 //Check the sensor for new data for 250ms
zinnetyazicii53 0:78a2573ad768 586 if(safeCheck(250))
zinnetyazicii53 0:78a2573ad768 587 return (sense.green[sense.head]);
zinnetyazicii53 0:78a2573ad768 588 else
zinnetyazicii53 0:78a2573ad768 589 return(0); //Sensor failed to find new data
zinnetyazicii53 0:78a2573ad768 590 }
zinnetyazicii53 0:78a2573ad768 591
zinnetyazicii53 0:78a2573ad768 592 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 593
zinnetyazicii53 0:78a2573ad768 594
zinnetyazicii53 0:78a2573ad768 595 //Report the next Red value in the FIFO
zinnetyazicii53 0:78a2573ad768 596 uint32_t MAX30105::getFIFORed(void)
zinnetyazicii53 0:78a2573ad768 597 {
zinnetyazicii53 0:78a2573ad768 598 return (sense.red[sense.tail]);
zinnetyazicii53 0:78a2573ad768 599 }
zinnetyazicii53 0:78a2573ad768 600
zinnetyazicii53 0:78a2573ad768 601
zinnetyazicii53 0:78a2573ad768 602 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 603
zinnetyazicii53 0:78a2573ad768 604 //Report the next IR value in the FIFO
zinnetyazicii53 0:78a2573ad768 605 uint32_t MAX30105::getFIFOIR(void)
zinnetyazicii53 0:78a2573ad768 606 {
zinnetyazicii53 0:78a2573ad768 607 return (sense.IR[sense.tail]);
zinnetyazicii53 0:78a2573ad768 608 }
zinnetyazicii53 0:78a2573ad768 609
zinnetyazicii53 0:78a2573ad768 610 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 611
zinnetyazicii53 0:78a2573ad768 612
zinnetyazicii53 0:78a2573ad768 613 //Report the next Green value in the FIFO
zinnetyazicii53 0:78a2573ad768 614 uint32_t MAX30105::getFIFOGreen(void)
zinnetyazicii53 0:78a2573ad768 615 {
zinnetyazicii53 0:78a2573ad768 616 return (sense.green[sense.tail]);
zinnetyazicii53 0:78a2573ad768 617 }
zinnetyazicii53 0:78a2573ad768 618
zinnetyazicii53 0:78a2573ad768 619 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 620
zinnetyazicii53 0:78a2573ad768 621
zinnetyazicii53 0:78a2573ad768 622 //Advance the tail
zinnetyazicii53 0:78a2573ad768 623 void MAX30105::nextSample(void)
zinnetyazicii53 0:78a2573ad768 624 {
zinnetyazicii53 0:78a2573ad768 625 if(available()) //Only advance the tail if new data is available
zinnetyazicii53 0:78a2573ad768 626 {
zinnetyazicii53 0:78a2573ad768 627 sense.tail++;
zinnetyazicii53 0:78a2573ad768 628 sense.tail %= STORAGE_SIZE; //Wrap condition
zinnetyazicii53 0:78a2573ad768 629 }
zinnetyazicii53 0:78a2573ad768 630 }
zinnetyazicii53 0:78a2573ad768 631
zinnetyazicii53 0:78a2573ad768 632 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 633
zinnetyazicii53 0:78a2573ad768 634
zinnetyazicii53 0:78a2573ad768 635 //Polls the sensor for new data
zinnetyazicii53 0:78a2573ad768 636 //Call regularly
zinnetyazicii53 0:78a2573ad768 637 //If new data is available, it updates the head and tail in the main struct
zinnetyazicii53 0:78a2573ad768 638 //Returns number of new samples obtained
zinnetyazicii53 0:78a2573ad768 639
zinnetyazicii53 0:78a2573ad768 640 uint16_t MAX30105::check(void)
zinnetyazicii53 0:78a2573ad768 641 {
zinnetyazicii53 0:78a2573ad768 642 /*
zinnetyazicii53 0:78a2573ad768 643 //Read register FIDO_DATA in (3-uint8_t * number of active LED) chunks
zinnetyazicii53 0:78a2573ad768 644 //Until FIFO_RD_PTR = FIFO_WR_PTR
zinnetyazicii53 0:78a2573ad768 645
zinnetyazicii53 0:78a2573ad768 646 uint8_t readPointer = getReadPointer();
zinnetyazicii53 0:78a2573ad768 647 uint8_t writePointer = getWritePointer();
zinnetyazicii53 0:78a2573ad768 648
zinnetyazicii53 0:78a2573ad768 649 int numberOfSamples = 0;
zinnetyazicii53 0:78a2573ad768 650
zinnetyazicii53 0:78a2573ad768 651 //Do we have new data?
zinnetyazicii53 0:78a2573ad768 652 if (readPointer != writePointer)
zinnetyazicii53 0:78a2573ad768 653 {
zinnetyazicii53 0:78a2573ad768 654 //Calculate the number of readings we need to get from sensor
zinnetyazicii53 0:78a2573ad768 655 numberOfSamples = writePointer - readPointer;
zinnetyazicii53 0:78a2573ad768 656 if (numberOfSamples < 0) numberOfSamples += 32; //Wrap condition
zinnetyazicii53 0:78a2573ad768 657
zinnetyazicii53 0:78a2573ad768 658 //We now have the number of readings, now calc uint8_ts to read
zinnetyazicii53 0:78a2573ad768 659 //For this example we are just doing Red and IR (3 uint8_ts each)
zinnetyazicii53 0:78a2573ad768 660 int uint8_tsLeftToRead = numberOfSamples * activeLEDs * 3;
zinnetyazicii53 0:78a2573ad768 661
zinnetyazicii53 0:78a2573ad768 662 //Get ready to read a burst of data from the FIFO register
zinnetyazicii53 0:78a2573ad768 663 //buraya bak
zinnetyazicii53 0:78a2573ad768 664 _i2c.writeReg(MAX30105_FIFODATA);
zinnetyazicii53 0:78a2573ad768 665
zinnetyazicii53 0:78a2573ad768 666
zinnetyazicii53 0:78a2573ad768 667 //We may need to read as many as 288 uint8_ts so we read in blocks no larger than I2C_BUFFER_LENGTH
zinnetyazicii53 0:78a2573ad768 668 //I2C_BUFFER_LENGTH changes based on the platform. 64 uint8_ts for SAMD21, 32 uint8_ts for Uno.
zinnetyazicii53 0:78a2573ad768 669 //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno
zinnetyazicii53 0:78a2573ad768 670 while (uint8_tsLeftToRead > 0)
zinnetyazicii53 0:78a2573ad768 671 {
zinnetyazicii53 0:78a2573ad768 672 int toGet = uint8_tsLeftToRead;
zinnetyazicii53 0:78a2573ad768 673 if (toGet > I2C_BUFFER_LENGTH)
zinnetyazicii53 0:78a2573ad768 674 {
zinnetyazicii53 0:78a2573ad768 675 //If toGet is 32 this is bad because we read 6 uint8_ts (Red+IR * 3 = 6) at a time
zinnetyazicii53 0:78a2573ad768 676 //32 % 6 = 2 left over. We don't want to request 32 uint8_ts, we want to request 30.
zinnetyazicii53 0:78a2573ad768 677 //32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27.
zinnetyazicii53 0:78a2573ad768 678
zinnetyazicii53 0:78a2573ad768 679 toGet = I2C_BUFFER_LENGTH - (I2C_BUFFER_LENGTH % (activeLEDs * 3)); //Trim toGet to be a multiple of the samples we need to read
zinnetyazicii53 0:78a2573ad768 680 }
zinnetyazicii53 0:78a2573ad768 681
zinnetyazicii53 0:78a2573ad768 682 uint8_tsLeftToRead -= toGet;
zinnetyazicii53 0:78a2573ad768 683
zinnetyazicii53 0:78a2573ad768 684 //Request toGet number of uint8_ts from sensor
zinnetyazicii53 0:78a2573ad768 685
zinnetyazicii53 0:78a2573ad768 686 //buraya bak
zinnetyazicii53 0:78a2573ad768 687 _i2c.requestFrom(MAX30105_ADDRESS, toGet);
zinnetyazicii53 0:78a2573ad768 688
zinnetyazicii53 0:78a2573ad768 689 while (toGet > 0)
zinnetyazicii53 0:78a2573ad768 690 {
zinnetyazicii53 0:78a2573ad768 691 sense.head++; //Advance the head of the storage struct
zinnetyazicii53 0:78a2573ad768 692 sense.head %= STORAGE_SIZE; //Wrap condition
zinnetyazicii53 0:78a2573ad768 693
zinnetyazicii53 0:78a2573ad768 694 uint8_t temp[sizeof(uint32_t)]; //Array of 4 uint8_ts that we will convert into long
zinnetyazicii53 0:78a2573ad768 695 uint32_t tempLong;
zinnetyazicii53 0:78a2573ad768 696
zinnetyazicii53 0:78a2573ad768 697 //Burst read three uint8_ts - RED
zinnetyazicii53 0:78a2573ad768 698
zinnetyazicii53 0:78a2573ad768 699 //buraya bak
zinnetyazicii53 0:78a2573ad768 700
zinnetyazicii53 0:78a2573ad768 701 temp[3] = 0;
zinnetyazicii53 0:78a2573ad768 702 temp[2] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 703 temp[1] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 704 temp[0] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 705
zinnetyazicii53 0:78a2573ad768 706 //Convert array to long
zinnetyazicii53 0:78a2573ad768 707 memcpy(&tempLong, temp, sizeof(tempLong));
zinnetyazicii53 0:78a2573ad768 708
zinnetyazicii53 0:78a2573ad768 709 tempLong &= 0x3FFFF; //Zero out all but 18 bits
zinnetyazicii53 0:78a2573ad768 710
zinnetyazicii53 0:78a2573ad768 711 sense.red[sense.head] = tempLong; //Store this reading into the sense array
zinnetyazicii53 0:78a2573ad768 712
zinnetyazicii53 0:78a2573ad768 713 if (activeLEDs > 1)
zinnetyazicii53 0:78a2573ad768 714 {
zinnetyazicii53 0:78a2573ad768 715
zinnetyazicii53 0:78a2573ad768 716 //Burst read three more uint8_ts - IR
zinnetyazicii53 0:78a2573ad768 717 temp[3] = 0;
zinnetyazicii53 0:78a2573ad768 718 temp[2] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 719 temp[1] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 720 temp[0] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 721
zinnetyazicii53 0:78a2573ad768 722 //Convert array to long
zinnetyazicii53 0:78a2573ad768 723 memcpy(&tempLong, temp, sizeof(tempLong));
zinnetyazicii53 0:78a2573ad768 724
zinnetyazicii53 0:78a2573ad768 725 tempLong &= 0x3FFFF; //Zero out all but 18 bits
zinnetyazicii53 0:78a2573ad768 726
zinnetyazicii53 0:78a2573ad768 727 sense.IR[sense.head] = tempLong;
zinnetyazicii53 0:78a2573ad768 728 }
zinnetyazicii53 0:78a2573ad768 729
zinnetyazicii53 0:78a2573ad768 730 if (activeLEDs > 2)
zinnetyazicii53 0:78a2573ad768 731 {
zinnetyazicii53 0:78a2573ad768 732 //Burst read three more uint8_ts - Green
zinnetyazicii53 0:78a2573ad768 733
zinnetyazicii53 0:78a2573ad768 734
zinnetyazicii53 0:78a2573ad768 735 temp[3] = 0;
zinnetyazicii53 0:78a2573ad768 736 temp[2] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 737 temp[1] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 738 temp[0] = _i2cPort->read();
zinnetyazicii53 0:78a2573ad768 739
zinnetyazicii53 0:78a2573ad768 740 //Convert array to long
zinnetyazicii53 0:78a2573ad768 741 memcpy(&tempLong, temp, sizeof(tempLong));
zinnetyazicii53 0:78a2573ad768 742
zinnetyazicii53 0:78a2573ad768 743 tempLong &= 0x3FFFF; //Zero out all but 18 bits
zinnetyazicii53 0:78a2573ad768 744
zinnetyazicii53 0:78a2573ad768 745 sense.green[sense.head] = tempLong;
zinnetyazicii53 0:78a2573ad768 746 }
zinnetyazicii53 0:78a2573ad768 747
zinnetyazicii53 0:78a2573ad768 748 toGet -= activeLEDs * 3;
zinnetyazicii53 0:78a2573ad768 749 }
zinnetyazicii53 0:78a2573ad768 750
zinnetyazicii53 0:78a2573ad768 751 } //End while (uint8_tsLeftToRead > 0)
zinnetyazicii53 0:78a2573ad768 752
zinnetyazicii53 0:78a2573ad768 753 } //End readPtr != writePtr
zinnetyazicii53 0:78a2573ad768 754
zinnetyazicii53 0:78a2573ad768 755 return (numberOfSamples); //Let the world know how much new data we found
zinnetyazicii53 0:78a2573ad768 756
zinnetyazicii53 0:78a2573ad768 757 */
zinnetyazicii53 0:78a2573ad768 758 }
zinnetyazicii53 0:78a2573ad768 759
zinnetyazicii53 0:78a2573ad768 760
zinnetyazicii53 0:78a2573ad768 761 //******************************************************************************
zinnetyazicii53 0:78a2573ad768 762
zinnetyazicii53 0:78a2573ad768 763
zinnetyazicii53 0:78a2573ad768 764 //Check for new data but give up after a certain amount of time
zinnetyazicii53 0:78a2573ad768 765 //Returns true if new data was found
zinnetyazicii53 0:78a2573ad768 766 //Returns false if new data was not found
zinnetyazicii53 0:78a2573ad768 767
zinnetyazicii53 0:78a2573ad768 768
zinnetyazicii53 0:78a2573ad768 769 //Given a register, read it, mask it, and then set the thing
zinnetyazicii53 0:78a2573ad768 770 void MAX30105::bitMask(uint8_t reg, uint8_t mask, uint8_t thing)
zinnetyazicii53 0:78a2573ad768 771 {
zinnetyazicii53 0:78a2573ad768 772 // Grab current register context
zinnetyazicii53 0:78a2573ad768 773 uint8_t originalContents = readRegister8(_i2caddr, reg);
zinnetyazicii53 0:78a2573ad768 774
zinnetyazicii53 0:78a2573ad768 775 // Zero-out the portions of the register we're interested in
zinnetyazicii53 0:78a2573ad768 776 originalContents = originalContents & mask;
zinnetyazicii53 0:78a2573ad768 777
zinnetyazicii53 0:78a2573ad768 778 // Change contents
zinnetyazicii53 0:78a2573ad768 779 writeRegister8(_i2caddr, reg, originalContents | thing);
zinnetyazicii53 0:78a2573ad768 780 }
zinnetyazicii53 0:78a2573ad768 781