zinnet yazıcı
/
Our_Code_copy
dszds
MAX30102/MAX30102.cpp@0:83277b73a1f8, 2019-07-28 (annotated)
- Committer:
- zinnetyazicii53
- Date:
- Sun Jul 28 08:14:38 2019 +0000
- Revision:
- 0:83277b73a1f8
commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
zinnetyazicii53 | 0:83277b73a1f8 | 1 | /*************************************************** |
zinnetyazicii53 | 0:83277b73a1f8 | 2 | This is a library written for the Maxim MAX30102 Optical Smoke Detector |
zinnetyazicii53 | 0:83277b73a1f8 | 3 | It should also work with the MAX30102. However, the MAX30102 does not have a Green LED. |
zinnetyazicii53 | 0:83277b73a1f8 | 4 | |
zinnetyazicii53 | 0:83277b73a1f8 | 5 | These sensors use I2C to communicate, as well as a single (optional) |
zinnetyazicii53 | 0:83277b73a1f8 | 6 | interrupt line that is not currently supported in this driver. |
zinnetyazicii53 | 0:83277b73a1f8 | 7 | |
zinnetyazicii53 | 0:83277b73a1f8 | 8 | Written by Peter Jansen and Nathan Seidle (SparkFun) |
zinnetyazicii53 | 0:83277b73a1f8 | 9 | BSD license, all text above must be included in any redistribution. |
zinnetyazicii53 | 0:83277b73a1f8 | 10 | *****************************************************/ |
zinnetyazicii53 | 0:83277b73a1f8 | 11 | /* |
zinnetyazicii53 | 0:83277b73a1f8 | 12 | #include "MAX30102.h" |
zinnetyazicii53 | 0:83277b73a1f8 | 13 | |
zinnetyazicii53 | 0:83277b73a1f8 | 14 | #ifdef TARGET_MAX32600MBED |
zinnetyazicii53 | 0:83277b73a1f8 | 15 | I2C i2c(I2C1_SDA, I2C1_SCL); |
zinnetyazicii53 | 0:83277b73a1f8 | 16 | #else |
zinnetyazicii53 | 0:83277b73a1f8 | 17 | I2C i2c(I2C_SDA, I2C_SCL); |
zinnetyazicii53 | 0:83277b73a1f8 | 18 | #endif |
zinnetyazicii53 | 0:83277b73a1f8 | 19 | |
zinnetyazicii53 | 0:83277b73a1f8 | 20 | // Status Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 21 | #define MAX30102_INTSTAT1 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 22 | #define MAX30102_INTSTAT2 0x01; |
zinnetyazicii53 | 0:83277b73a1f8 | 23 | #define MAX30102_INTENABLE1 0x02; |
zinnetyazicii53 | 0:83277b73a1f8 | 24 | #define MAX30102_INTENABLE2 0x03; |
zinnetyazicii53 | 0:83277b73a1f8 | 25 | |
zinnetyazicii53 | 0:83277b73a1f8 | 26 | // FIFO Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 27 | #define MAX30102_FIFOWRITEPTR 0x04; |
zinnetyazicii53 | 0:83277b73a1f8 | 28 | #define MAX30102_FIFOOVERFLOW 0x05; |
zinnetyazicii53 | 0:83277b73a1f8 | 29 | #define MAX30102_FIFOREADPTR 0x06; |
zinnetyazicii53 | 0:83277b73a1f8 | 30 | #define MAX30102_FIFODATA 0x07; |
zinnetyazicii53 | 0:83277b73a1f8 | 31 | |
zinnetyazicii53 | 0:83277b73a1f8 | 32 | // Configuration Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 33 | #define MAX30102_FIFOCONFIG 0x08; |
zinnetyazicii53 | 0:83277b73a1f8 | 34 | #define MAX30102_MODECONFIG 0x09; |
zinnetyazicii53 | 0:83277b73a1f8 | 35 | #define MAX30102_PARTICLECONFIG 0x0A; // Note, sometimes listed as "SPO2" config in datasheet (pg. 11) |
zinnetyazicii53 | 0:83277b73a1f8 | 36 | #define MAX30102_LED1_PULSEAMP 0x0C; |
zinnetyazicii53 | 0:83277b73a1f8 | 37 | #define MAX30102_LED2_PULSEAMP 0x0D; |
zinnetyazicii53 | 0:83277b73a1f8 | 38 | #define MAX30102_LED3_PULSEAMP 0x0E; |
zinnetyazicii53 | 0:83277b73a1f8 | 39 | #define MAX30102_LED_PROX_AMP 0x10; |
zinnetyazicii53 | 0:83277b73a1f8 | 40 | #define MAX30102_MULTILEDCONFIG1 0x11; |
zinnetyazicii53 | 0:83277b73a1f8 | 41 | #define MAX30102_MULTILEDCONFIG2 0x12; |
zinnetyazicii53 | 0:83277b73a1f8 | 42 | |
zinnetyazicii53 | 0:83277b73a1f8 | 43 | // Die Temperature Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 44 | #define MAX30102_DIETEMPINT 0x1F; |
zinnetyazicii53 | 0:83277b73a1f8 | 45 | #define MAX30102_DIETEMPFRAC 0x20; |
zinnetyazicii53 | 0:83277b73a1f8 | 46 | #define MAX30102_DIETEMPCONFIG 0x21; |
zinnetyazicii53 | 0:83277b73a1f8 | 47 | |
zinnetyazicii53 | 0:83277b73a1f8 | 48 | // Proximity Function Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 49 | #define MAX30102_PROXINTTHRESH 0x30; |
zinnetyazicii53 | 0:83277b73a1f8 | 50 | |
zinnetyazicii53 | 0:83277b73a1f8 | 51 | // Part ID Registers |
zinnetyazicii53 | 0:83277b73a1f8 | 52 | #define MAX30102_REVISIONID 0xFE; |
zinnetyazicii53 | 0:83277b73a1f8 | 53 | #define MAX30102_PARTID 0xFF; // Should always be 0x15. Identical to MAX30102. |
zinnetyazicii53 | 0:83277b73a1f8 | 54 | |
zinnetyazicii53 | 0:83277b73a1f8 | 55 | // MAX30102 Commands |
zinnetyazicii53 | 0:83277b73a1f8 | 56 | // Interrupt configuration (pg 13, 14) |
zinnetyazicii53 | 0:83277b73a1f8 | 57 | #define MAX30102_INT_A_FULL_MASK (byte)~0b10000000; |
zinnetyazicii53 | 0:83277b73a1f8 | 58 | #define MAX30102_INT_A_FULL_ENABLE 0x80; |
zinnetyazicii53 | 0:83277b73a1f8 | 59 | #define MAX30102_INT_A_FULL_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 60 | |
zinnetyazicii53 | 0:83277b73a1f8 | 61 | #define MAX30102_INT_DATA_RDY_MASK (byte)~0b01000000; |
zinnetyazicii53 | 0:83277b73a1f8 | 62 | #define MAX30102_INT_DATA_RDY_ENABLE 0x40; |
zinnetyazicii53 | 0:83277b73a1f8 | 63 | #define MAX30102_INT_DATA_RDY_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 64 | |
zinnetyazicii53 | 0:83277b73a1f8 | 65 | #define MAX30102_INT_ALC_OVF_MASK (byte)~0b00100000; |
zinnetyazicii53 | 0:83277b73a1f8 | 66 | #define MAX30102_INT_ALC_OVF_ENABLE 0x20; |
zinnetyazicii53 | 0:83277b73a1f8 | 67 | #define MAX30102_INT_ALC_OVF_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 68 | |
zinnetyazicii53 | 0:83277b73a1f8 | 69 | #define MAX30102_INT_PROX_INT_MASK (byte)~0b00010000; |
zinnetyazicii53 | 0:83277b73a1f8 | 70 | #define MAX30102_INT_PROX_INT_ENABLE 0x10; |
zinnetyazicii53 | 0:83277b73a1f8 | 71 | #define MAX30102_INT_PROX_INT_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 72 | |
zinnetyazicii53 | 0:83277b73a1f8 | 73 | #define MAX30102_INT_DIE_TEMP_RDY_MASK (byte)~0b00000010; |
zinnetyazicii53 | 0:83277b73a1f8 | 74 | #define MAX30102_INT_DIE_TEMP_RDY_ENABLE 0x02; |
zinnetyazicii53 | 0:83277b73a1f8 | 75 | #define MAX30102_INT_DIE_TEMP_RDY_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 76 | |
zinnetyazicii53 | 0:83277b73a1f8 | 77 | #define MAX30102_SAMPLEAVG_MASK (byte)~0b11100000; |
zinnetyazicii53 | 0:83277b73a1f8 | 78 | #define MAX30102_SAMPLEAVG_1 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 79 | #define MAX30102_SAMPLEAVG_2 0x20; |
zinnetyazicii53 | 0:83277b73a1f8 | 80 | #define MAX30102_SAMPLEAVG_4 0x40; |
zinnetyazicii53 | 0:83277b73a1f8 | 81 | #define MAX30102_SAMPLEAVG_8 0x60; |
zinnetyazicii53 | 0:83277b73a1f8 | 82 | #define MAX30102_SAMPLEAVG_16 0x80; |
zinnetyazicii53 | 0:83277b73a1f8 | 83 | #define MAX30102_SAMPLEAVG_32 0xA0; |
zinnetyazicii53 | 0:83277b73a1f8 | 84 | |
zinnetyazicii53 | 0:83277b73a1f8 | 85 | #define MAX30102_ROLLOVER_MASK 0xEF; |
zinnetyazicii53 | 0:83277b73a1f8 | 86 | #define MAX30102_ROLLOVER_ENABLE 0x10; |
zinnetyazicii53 | 0:83277b73a1f8 | 87 | #define MAX30102_ROLLOVER_DISABLE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 88 | |
zinnetyazicii53 | 0:83277b73a1f8 | 89 | #define MAX30102_A_FULL_MASK 0xF0; |
zinnetyazicii53 | 0:83277b73a1f8 | 90 | |
zinnetyazicii53 | 0:83277b73a1f8 | 91 | // Mode configuration commands (page 19) |
zinnetyazicii53 | 0:83277b73a1f8 | 92 | #define MAX30102_SHUTDOWN_MASK 0x7F; |
zinnetyazicii53 | 0:83277b73a1f8 | 93 | #define MAX30102_SHUTDOWN 0x80; |
zinnetyazicii53 | 0:83277b73a1f8 | 94 | #define MAX30102_WAKEUP 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 95 | |
zinnetyazicii53 | 0:83277b73a1f8 | 96 | #define MAX30102_RESET_MASK 0xBF; |
zinnetyazicii53 | 0:83277b73a1f8 | 97 | #define MAX30102_RESET 0x40; |
zinnetyazicii53 | 0:83277b73a1f8 | 98 | |
zinnetyazicii53 | 0:83277b73a1f8 | 99 | #define MAX30102_MODE_MASK 0xF8; |
zinnetyazicii53 | 0:83277b73a1f8 | 100 | #define MAX30102_MODE_REDONLY 0x02; |
zinnetyazicii53 | 0:83277b73a1f8 | 101 | #define MAX30102_MODE_REDIRONLY 0x03; |
zinnetyazicii53 | 0:83277b73a1f8 | 102 | #define MAX30102_MODE_MULTILED 0x07; |
zinnetyazicii53 | 0:83277b73a1f8 | 103 | |
zinnetyazicii53 | 0:83277b73a1f8 | 104 | // Particle sensing configuration commands (pgs 19-20) |
zinnetyazicii53 | 0:83277b73a1f8 | 105 | #define MAX30102_ADCRANGE_MASK 0x9F; |
zinnetyazicii53 | 0:83277b73a1f8 | 106 | #define MAX30102_ADCRANGE_2048 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 107 | #define MAX30102_ADCRANGE_4096 0x20; |
zinnetyazicii53 | 0:83277b73a1f8 | 108 | #define MAX30102_ADCRANGE_8192 0x40; |
zinnetyazicii53 | 0:83277b73a1f8 | 109 | #define MAX30102_ADCRANGE_16384 0x60; |
zinnetyazicii53 | 0:83277b73a1f8 | 110 | |
zinnetyazicii53 | 0:83277b73a1f8 | 111 | #define MAX30102_SAMPLERATE_MASK 0xE3; |
zinnetyazicii53 | 0:83277b73a1f8 | 112 | #define MAX30102_SAMPLERATE_50 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 113 | #define MAX30102_SAMPLERATE_100 0x04; |
zinnetyazicii53 | 0:83277b73a1f8 | 114 | #define MAX30102_SAMPLERATE_200 0x08; |
zinnetyazicii53 | 0:83277b73a1f8 | 115 | #define MAX30102_SAMPLERATE_400 0x0C; |
zinnetyazicii53 | 0:83277b73a1f8 | 116 | #define MAX30102_SAMPLERATE_800 0x10; |
zinnetyazicii53 | 0:83277b73a1f8 | 117 | #define MAX30102_SAMPLERATE_1000 0x14; |
zinnetyazicii53 | 0:83277b73a1f8 | 118 | #define MAX30102_SAMPLERATE_1600 0x18; |
zinnetyazicii53 | 0:83277b73a1f8 | 119 | #define MAX30102_SAMPLERATE_3200 0x1C; |
zinnetyazicii53 | 0:83277b73a1f8 | 120 | |
zinnetyazicii53 | 0:83277b73a1f8 | 121 | #define MAX30102_PULSEWIDTH_MASK 0xFC; |
zinnetyazicii53 | 0:83277b73a1f8 | 122 | #define MAX30102_PULSEWIDTH_69 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 123 | #define MAX30102_PULSEWIDTH_118 0x01; |
zinnetyazicii53 | 0:83277b73a1f8 | 124 | #define MAX30102_PULSEWIDTH_215 0x02; |
zinnetyazicii53 | 0:83277b73a1f8 | 125 | #define MAX30102_PULSEWIDTH_411 0x03; |
zinnetyazicii53 | 0:83277b73a1f8 | 126 | |
zinnetyazicii53 | 0:83277b73a1f8 | 127 | //Multi-LED Mode configuration (pg 22) |
zinnetyazicii53 | 0:83277b73a1f8 | 128 | #define MAX30102_SLOT1_MASK 0xF8; |
zinnetyazicii53 | 0:83277b73a1f8 | 129 | #define MAX30102_SLOT2_MASK 0x8F; |
zinnetyazicii53 | 0:83277b73a1f8 | 130 | #define MAX30102_SLOT3_MASK 0xF8; |
zinnetyazicii53 | 0:83277b73a1f8 | 131 | #define MAX30102_SLOT4_MASK 0x8F; |
zinnetyazicii53 | 0:83277b73a1f8 | 132 | |
zinnetyazicii53 | 0:83277b73a1f8 | 133 | #define SLOT_NONE 0x00; |
zinnetyazicii53 | 0:83277b73a1f8 | 134 | #define SLOT_RED_LED 0x01; |
zinnetyazicii53 | 0:83277b73a1f8 | 135 | #define SLOT_IR_LED 0x02; |
zinnetyazicii53 | 0:83277b73a1f8 | 136 | #define SLOT_GREEN_LED 0x03; |
zinnetyazicii53 | 0:83277b73a1f8 | 137 | #define SLOT_NONE_PILOT 0x04; |
zinnetyazicii53 | 0:83277b73a1f8 | 138 | #define SLOT_RED_PILOT 0x05; |
zinnetyazicii53 | 0:83277b73a1f8 | 139 | #define SLOT_IR_PILOT 0x06; |
zinnetyazicii53 | 0:83277b73a1f8 | 140 | #define SLOT_GREEN_PILOT 0x07; |
zinnetyazicii53 | 0:83277b73a1f8 | 141 | |
zinnetyazicii53 | 0:83277b73a1f8 | 142 | |
zinnetyazicii53 | 0:83277b73a1f8 | 143 | #define MAX_30105_EXPECTEDPARTID 0x15; |
zinnetyazicii53 | 0:83277b73a1f8 | 144 | |
zinnetyazicii53 | 0:83277b73a1f8 | 145 | bool begin(TwoWire &wirePort, uint32_t i2cSpeed, uint8_t i2caddr) {//?? |
zinnetyazicii53 | 0:83277b73a1f8 | 146 | |
zinnetyazicii53 | 0:83277b73a1f8 | 147 | _i2cPort = &wirePort; //Grab which port the user wants us to use |
zinnetyazicii53 | 0:83277b73a1f8 | 148 | |
zinnetyazicii53 | 0:83277b73a1f8 | 149 | _i2cPort->begin(); |
zinnetyazicii53 | 0:83277b73a1f8 | 150 | _i2cPort->setClock(i2cSpeed); |
zinnetyazicii53 | 0:83277b73a1f8 | 151 | |
zinnetyazicii53 | 0:83277b73a1f8 | 152 | _i2caddr = i2caddr; |
zinnetyazicii53 | 0:83277b73a1f8 | 153 | |
zinnetyazicii53 | 0:83277b73a1f8 | 154 | // Step 1: Initial Communication and Verification |
zinnetyazicii53 | 0:83277b73a1f8 | 155 | // Check that a MAX30102 is connected |
zinnetyazicii53 | 0:83277b73a1f8 | 156 | if (readPartID() != MAX_30105_EXPECTEDPARTID) { |
zinnetyazicii53 | 0:83277b73a1f8 | 157 | // Error -- Part ID read from MAX30102 does not match expected part ID. |
zinnetyazicii53 | 0:83277b73a1f8 | 158 | // This may mean there is a physical connectivity problem (broken wire, unpowered, etc). |
zinnetyazicii53 | 0:83277b73a1f8 | 159 | return false; |
zinnetyazicii53 | 0:83277b73a1f8 | 160 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 161 | |
zinnetyazicii53 | 0:83277b73a1f8 | 162 | // Populate revision ID |
zinnetyazicii53 | 0:83277b73a1f8 | 163 | readRevisionID(); |
zinnetyazicii53 | 0:83277b73a1f8 | 164 | |
zinnetyazicii53 | 0:83277b73a1f8 | 165 | return true; |
zinnetyazicii53 | 0:83277b73a1f8 | 166 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 167 | |
zinnetyazicii53 | 0:83277b73a1f8 | 168 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 169 | // Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 170 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 171 | |
zinnetyazicii53 | 0:83277b73a1f8 | 172 | //Begin Interrupt configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 173 | uint8_t MAX30102::getINT1(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 174 | return (readRegister8(_i2caddr, MAX30102_INTSTAT1)); |
zinnetyazicii53 | 0:83277b73a1f8 | 175 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 176 | uint8_t getINT2(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 177 | return (readRegister8(_i2caddr, MAX30102_INTSTAT2)); |
zinnetyazicii53 | 0:83277b73a1f8 | 178 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 179 | |
zinnetyazicii53 | 0:83277b73a1f8 | 180 | void enableAFULL(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 181 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_A_FULL_MASK, MAX30102_INT_A_FULL_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 182 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 183 | void disableAFULL(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 184 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_A_FULL_MASK, MAX30102_INT_A_FULL_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 185 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 186 | |
zinnetyazicii53 | 0:83277b73a1f8 | 187 | void enableDATARDY(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 188 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_DATA_RDY_MASK, MAX30102_INT_DATA_RDY_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 189 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 190 | void disableDATARDY(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 191 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_DATA_RDY_MASK, MAX30102_INT_DATA_RDY_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 192 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 193 | |
zinnetyazicii53 | 0:83277b73a1f8 | 194 | void enableALCOVF(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 195 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_ALC_OVF_MASK, MAX30102_INT_ALC_OVF_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 196 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 197 | void disableALCOVF(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 198 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_ALC_OVF_MASK, MAX30102_INT_ALC_OVF_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 199 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 200 | |
zinnetyazicii53 | 0:83277b73a1f8 | 201 | void enablePROXINT(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 202 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_PROX_INT_MASK, MAX30102_INT_PROX_INT_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 203 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 204 | void disablePROXINT(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 205 | bitMask(MAX30102_INTENABLE1, MAX30102_INT_PROX_INT_MASK, MAX30102_INT_PROX_INT_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 206 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 207 | |
zinnetyazicii53 | 0:83277b73a1f8 | 208 | void enableDIETEMPRDY(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 209 | bitMask(MAX30102_INTENABLE2, MAX30102_INT_DIE_TEMP_RDY_MASK, MAX30102_INT_DIE_TEMP_RDY_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 210 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 211 | void disableDIETEMPRDY(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 212 | bitMask(MAX30102_INTENABLE2, MAX30102_INT_DIE_TEMP_RDY_MASK, MAX30102_INT_DIE_TEMP_RDY_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 213 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 214 | |
zinnetyazicii53 | 0:83277b73a1f8 | 215 | //End Interrupt configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 216 | |
zinnetyazicii53 | 0:83277b73a1f8 | 217 | void softReset(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 218 | bitMask(MAX30102_MODECONFIG, MAX30102_RESET_MASK, MAX30102_RESET); |
zinnetyazicii53 | 0:83277b73a1f8 | 219 | |
zinnetyazicii53 | 0:83277b73a1f8 | 220 | // Poll for bit to clear, reset is then complete |
zinnetyazicii53 | 0:83277b73a1f8 | 221 | // Timeout after 100ms |
zinnetyazicii53 | 0:83277b73a1f8 | 222 | unsigned long startTime = millis(); |
zinnetyazicii53 | 0:83277b73a1f8 | 223 | while (millis() - startTime < 100) |
zinnetyazicii53 | 0:83277b73a1f8 | 224 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 225 | uint8_t response = readRegister8(_i2caddr, MAX30102_MODECONFIG); |
zinnetyazicii53 | 0:83277b73a1f8 | 226 | if ((response & MAX30102_RESET) == 0) break; //We're done! |
zinnetyazicii53 | 0:83277b73a1f8 | 227 | delay(1); //Let's not over burden the I2C bus |
zinnetyazicii53 | 0:83277b73a1f8 | 228 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 229 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 230 | |
zinnetyazicii53 | 0:83277b73a1f8 | 231 | void shutDown(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 232 | // Put IC into low power mode (datasheet pg. 19) |
zinnetyazicii53 | 0:83277b73a1f8 | 233 | // During shutdown the IC will continue to respond to I2C commands but will |
zinnetyazicii53 | 0:83277b73a1f8 | 234 | // not update with or take new readings (such as temperature) |
zinnetyazicii53 | 0:83277b73a1f8 | 235 | bitMask(MAX30102_MODECONFIG, MAX30102_SHUTDOWN_MASK, MAX30102_SHUTDOWN); |
zinnetyazicii53 | 0:83277b73a1f8 | 236 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 237 | |
zinnetyazicii53 | 0:83277b73a1f8 | 238 | void wakeUp(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 239 | // Pull IC out of low power mode (datasheet pg. 19) |
zinnetyazicii53 | 0:83277b73a1f8 | 240 | bitMask(MAX30102_MODECONFIG, MAX30102_SHUTDOWN_MASK, MAX30102_WAKEUP); |
zinnetyazicii53 | 0:83277b73a1f8 | 241 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 242 | |
zinnetyazicii53 | 0:83277b73a1f8 | 243 | void setLEDMode(uint8_t mode) { |
zinnetyazicii53 | 0:83277b73a1f8 | 244 | // Set which LEDs are used for sampling -- Red only, RED+IR only, or custom. |
zinnetyazicii53 | 0:83277b73a1f8 | 245 | // See datasheet, page 19 |
zinnetyazicii53 | 0:83277b73a1f8 | 246 | bitMask(MAX30102_MODECONFIG, MAX30102_MODE_MASK, mode); |
zinnetyazicii53 | 0:83277b73a1f8 | 247 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 248 | |
zinnetyazicii53 | 0:83277b73a1f8 | 249 | void setADCRange(uint8_t adcRange) { |
zinnetyazicii53 | 0:83277b73a1f8 | 250 | // adcRange: one of MAX30102_ADCRANGE_2048, _4096, _8192, _16384 |
zinnetyazicii53 | 0:83277b73a1f8 | 251 | bitMask(MAX30102_PARTICLECONFIG, MAX30102_ADCRANGE_MASK, adcRange); |
zinnetyazicii53 | 0:83277b73a1f8 | 252 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 253 | |
zinnetyazicii53 | 0:83277b73a1f8 | 254 | void setSampleRate(uint8_t sampleRate) { |
zinnetyazicii53 | 0:83277b73a1f8 | 255 | // sampleRate: one of MAX30102_SAMPLERATE_50, _100, _200, _400, _800, _1000, _1600, _3200 |
zinnetyazicii53 | 0:83277b73a1f8 | 256 | bitMask(MAX30102_PARTICLECONFIG, MAX30102_SAMPLERATE_MASK, sampleRate); |
zinnetyazicii53 | 0:83277b73a1f8 | 257 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 258 | |
zinnetyazicii53 | 0:83277b73a1f8 | 259 | void setPulseWidth(uint8_t pulseWidth) { |
zinnetyazicii53 | 0:83277b73a1f8 | 260 | // pulseWidth: one of MAX30102_PULSEWIDTH_69, _188, _215, _411 |
zinnetyazicii53 | 0:83277b73a1f8 | 261 | bitMask(MAX30102_PARTICLECONFIG, MAX30102_PULSEWIDTH_MASK, pulseWidth); |
zinnetyazicii53 | 0:83277b73a1f8 | 262 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 263 | |
zinnetyazicii53 | 0:83277b73a1f8 | 264 | // NOTE: Amplitude values: 0x00 = 0mA, 0x7F = 25.4mA, 0xFF = 50mA (typical) |
zinnetyazicii53 | 0:83277b73a1f8 | 265 | // See datasheet, page 21 |
zinnetyazicii53 | 0:83277b73a1f8 | 266 | void setPulseAmplitudeRed(uint8_t amplitude) { |
zinnetyazicii53 | 0:83277b73a1f8 | 267 | writeRegister8(_i2caddr, MAX30102_LED1_PULSEAMP, amplitude); |
zinnetyazicii53 | 0:83277b73a1f8 | 268 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 269 | |
zinnetyazicii53 | 0:83277b73a1f8 | 270 | void setPulseAmplitudeIR(uint8_t amplitude) { |
zinnetyazicii53 | 0:83277b73a1f8 | 271 | writeRegister8(_i2caddr, MAX30102_LED2_PULSEAMP, amplitude); |
zinnetyazicii53 | 0:83277b73a1f8 | 272 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 273 | |
zinnetyazicii53 | 0:83277b73a1f8 | 274 | void setPulseAmplitudeGreen(uint8_t amplitude) { |
zinnetyazicii53 | 0:83277b73a1f8 | 275 | writeRegister8(_i2caddr, MAX30102_LED3_PULSEAMP, amplitude); |
zinnetyazicii53 | 0:83277b73a1f8 | 276 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 277 | |
zinnetyazicii53 | 0:83277b73a1f8 | 278 | void setPulseAmplitudeProximity(uint8_t amplitude) { |
zinnetyazicii53 | 0:83277b73a1f8 | 279 | writeRegister8(_i2caddr, MAX30102_LED_PROX_AMP, amplitude); |
zinnetyazicii53 | 0:83277b73a1f8 | 280 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 281 | |
zinnetyazicii53 | 0:83277b73a1f8 | 282 | void setProximityThreshold(uint8_t threshMSB) { |
zinnetyazicii53 | 0:83277b73a1f8 | 283 | // Set the IR ADC count that will trigger the beginning of particle-sensing mode. |
zinnetyazicii53 | 0:83277b73a1f8 | 284 | // The threshMSB signifies only the 8 most significant-bits of the ADC count. |
zinnetyazicii53 | 0:83277b73a1f8 | 285 | // See datasheet, page 24. |
zinnetyazicii53 | 0:83277b73a1f8 | 286 | writeRegister8(_i2caddr, MAX30102_PROXINTTHRESH, threshMSB); |
zinnetyazicii53 | 0:83277b73a1f8 | 287 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 288 | |
zinnetyazicii53 | 0:83277b73a1f8 | 289 | //Given a slot number assign a thing to it |
zinnetyazicii53 | 0:83277b73a1f8 | 290 | //Devices are SLOT_RED_LED or SLOT_RED_PILOT (proximity) |
zinnetyazicii53 | 0:83277b73a1f8 | 291 | //Assigning a SLOT_RED_LED will pulse LED |
zinnetyazicii53 | 0:83277b73a1f8 | 292 | //Assigning a SLOT_RED_PILOT will ?? |
zinnetyazicii53 | 0:83277b73a1f8 | 293 | void enableSlot(uint8_t slotNumber, uint8_t device) { |
zinnetyazicii53 | 0:83277b73a1f8 | 294 | |
zinnetyazicii53 | 0:83277b73a1f8 | 295 | uint8_t originalContents; |
zinnetyazicii53 | 0:83277b73a1f8 | 296 | |
zinnetyazicii53 | 0:83277b73a1f8 | 297 | switch (slotNumber) { |
zinnetyazicii53 | 0:83277b73a1f8 | 298 | case (1): |
zinnetyazicii53 | 0:83277b73a1f8 | 299 | bitMask(MAX30102_MULTILEDCONFIG1, MAX30102_SLOT1_MASK, device); |
zinnetyazicii53 | 0:83277b73a1f8 | 300 | break; |
zinnetyazicii53 | 0:83277b73a1f8 | 301 | case (2): |
zinnetyazicii53 | 0:83277b73a1f8 | 302 | bitMask(MAX30102_MULTILEDCONFIG1, MAX30102_SLOT2_MASK, device << 4); |
zinnetyazicii53 | 0:83277b73a1f8 | 303 | break; |
zinnetyazicii53 | 0:83277b73a1f8 | 304 | case (3): |
zinnetyazicii53 | 0:83277b73a1f8 | 305 | bitMask(MAX30102_MULTILEDCONFIG2, MAX30102_SLOT3_MASK, device); |
zinnetyazicii53 | 0:83277b73a1f8 | 306 | break; |
zinnetyazicii53 | 0:83277b73a1f8 | 307 | case (4): |
zinnetyazicii53 | 0:83277b73a1f8 | 308 | bitMask(MAX30102_MULTILEDCONFIG2, MAX30102_SLOT4_MASK, device << 4); |
zinnetyazicii53 | 0:83277b73a1f8 | 309 | break; |
zinnetyazicii53 | 0:83277b73a1f8 | 310 | default: |
zinnetyazicii53 | 0:83277b73a1f8 | 311 | //Shouldn't be here! |
zinnetyazicii53 | 0:83277b73a1f8 | 312 | break; |
zinnetyazicii53 | 0:83277b73a1f8 | 313 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 314 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 315 | |
zinnetyazicii53 | 0:83277b73a1f8 | 316 | //Clears all slot assignments |
zinnetyazicii53 | 0:83277b73a1f8 | 317 | void disableSlots(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 318 | writeRegister8(_i2caddr, MAX30102_MULTILEDCONFIG1, 0); |
zinnetyazicii53 | 0:83277b73a1f8 | 319 | writeRegister8(_i2caddr, MAX30102_MULTILEDCONFIG2, 0); |
zinnetyazicii53 | 0:83277b73a1f8 | 320 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 321 | |
zinnetyazicii53 | 0:83277b73a1f8 | 322 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 323 | // FIFO Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 324 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 325 | |
zinnetyazicii53 | 0:83277b73a1f8 | 326 | //Set sample average (Table 3, Page 18) |
zinnetyazicii53 | 0:83277b73a1f8 | 327 | void setFIFOAverage(uint8_t numberOfSamples) { |
zinnetyazicii53 | 0:83277b73a1f8 | 328 | bitMask(MAX30102_FIFOCONFIG, MAX30102_SAMPLEAVG_MASK, numberOfSamples); |
zinnetyazicii53 | 0:83277b73a1f8 | 329 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 330 | |
zinnetyazicii53 | 0:83277b73a1f8 | 331 | //Resets all points to start in a known state |
zinnetyazicii53 | 0:83277b73a1f8 | 332 | //Page 15 recommends clearing FIFO before beginning a read |
zinnetyazicii53 | 0:83277b73a1f8 | 333 | void clearFIFO(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 334 | writeRegister8(_i2caddr, MAX30102_FIFOWRITEPTR, 0); |
zinnetyazicii53 | 0:83277b73a1f8 | 335 | writeRegister8(_i2caddr, MAX30102_FIFOOVERFLOW, 0); |
zinnetyazicii53 | 0:83277b73a1f8 | 336 | writeRegister8(_i2caddr, MAX30102_FIFOREADPTR, 0); |
zinnetyazicii53 | 0:83277b73a1f8 | 337 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 338 | |
zinnetyazicii53 | 0:83277b73a1f8 | 339 | //Enable roll over if FIFO over flows |
zinnetyazicii53 | 0:83277b73a1f8 | 340 | void enableFIFORollover(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 341 | bitMask(MAX30102_FIFOCONFIG, MAX30102_ROLLOVER_MASK, MAX30102_ROLLOVER_ENABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 342 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 343 | |
zinnetyazicii53 | 0:83277b73a1f8 | 344 | //Disable roll over if FIFO over flows |
zinnetyazicii53 | 0:83277b73a1f8 | 345 | void disableFIFORollover(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 346 | bitMask(MAX30102_FIFOCONFIG, MAX30102_ROLLOVER_MASK, MAX30102_ROLLOVER_DISABLE); |
zinnetyazicii53 | 0:83277b73a1f8 | 347 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 348 | |
zinnetyazicii53 | 0:83277b73a1f8 | 349 | //Set number of samples to trigger the almost full interrupt (Page 18) |
zinnetyazicii53 | 0:83277b73a1f8 | 350 | //Power on default is 32 samples |
zinnetyazicii53 | 0:83277b73a1f8 | 351 | //Note it is reverse: 0x00 is 32 samples, 0x0F is 17 samples |
zinnetyazicii53 | 0:83277b73a1f8 | 352 | void setFIFOAlmostFull(uint8_t numberOfSamples) { |
zinnetyazicii53 | 0:83277b73a1f8 | 353 | bitMask(MAX30102_FIFOCONFIG, MAX30102_A_FULL_MASK, numberOfSamples); |
zinnetyazicii53 | 0:83277b73a1f8 | 354 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 355 | |
zinnetyazicii53 | 0:83277b73a1f8 | 356 | //Read the FIFO Write Pointer |
zinnetyazicii53 | 0:83277b73a1f8 | 357 | uint8_t getWritePointer(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 358 | return (readRegister8(_i2caddr, MAX30102_FIFOWRITEPTR)); |
zinnetyazicii53 | 0:83277b73a1f8 | 359 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 360 | |
zinnetyazicii53 | 0:83277b73a1f8 | 361 | //Read the FIFO Read Pointer |
zinnetyazicii53 | 0:83277b73a1f8 | 362 | uint8_t getReadPointer(void) { |
zinnetyazicii53 | 0:83277b73a1f8 | 363 | return (readRegister8(_i2caddr, MAX30102_FIFOREADPTR)); |
zinnetyazicii53 | 0:83277b73a1f8 | 364 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 365 | |
zinnetyazicii53 | 0:83277b73a1f8 | 366 | |
zinnetyazicii53 | 0:83277b73a1f8 | 367 | // Die Temperature |
zinnetyazicii53 | 0:83277b73a1f8 | 368 | // Returns temp in C |
zinnetyazicii53 | 0:83277b73a1f8 | 369 | float readTemperature() { |
zinnetyazicii53 | 0:83277b73a1f8 | 370 | |
zinnetyazicii53 | 0:83277b73a1f8 | 371 | //DIE_TEMP_RDY interrupt must be enabled |
zinnetyazicii53 | 0:83277b73a1f8 | 372 | //See issue 19: https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/19 |
zinnetyazicii53 | 0:83277b73a1f8 | 373 | |
zinnetyazicii53 | 0:83277b73a1f8 | 374 | // Step 1: Config die temperature register to take 1 temperature sample |
zinnetyazicii53 | 0:83277b73a1f8 | 375 | writeRegister8(_i2caddr, MAX30102_DIETEMPCONFIG, 0x01); |
zinnetyazicii53 | 0:83277b73a1f8 | 376 | |
zinnetyazicii53 | 0:83277b73a1f8 | 377 | // Poll for bit to clear, reading is then complete |
zinnetyazicii53 | 0:83277b73a1f8 | 378 | // Timeout after 100ms |
zinnetyazicii53 | 0:83277b73a1f8 | 379 | unsigned long startTime = millis(); |
zinnetyazicii53 | 0:83277b73a1f8 | 380 | while (millis() - startTime < 100) |
zinnetyazicii53 | 0:83277b73a1f8 | 381 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 382 | //uint8_t response = readRegister8(_i2caddr, MAX30102_DIETEMPCONFIG); //Original way |
zinnetyazicii53 | 0:83277b73a1f8 | 383 | //if ((response & 0x01) == 0) break; //We're done! |
zinnetyazicii53 | 0:83277b73a1f8 | 384 | |
zinnetyazicii53 | 0:83277b73a1f8 | 385 | //Check to see if DIE_TEMP_RDY interrupt is set |
zinnetyazicii53 | 0:83277b73a1f8 | 386 | uint8_t response = readRegister8(_i2caddr, MAX30102_INTSTAT2); |
zinnetyazicii53 | 0:83277b73a1f8 | 387 | if ((response & MAX30102_INT_DIE_TEMP_RDY_ENABLE) > 0) break; //We're done! |
zinnetyazicii53 | 0:83277b73a1f8 | 388 | delay(1); //Let's not over burden the I2C bus |
zinnetyazicii53 | 0:83277b73a1f8 | 389 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 390 | //TODO How do we want to fail? With what type of error? |
zinnetyazicii53 | 0:83277b73a1f8 | 391 | //? if(millis() - startTime >= 100) return(-999.0); |
zinnetyazicii53 | 0:83277b73a1f8 | 392 | |
zinnetyazicii53 | 0:83277b73a1f8 | 393 | // Step 2: Read die temperature register (integer) |
zinnetyazicii53 | 0:83277b73a1f8 | 394 | int8_t tempInt = readRegister8(_i2caddr, MAX30102_DIETEMPINT); |
zinnetyazicii53 | 0:83277b73a1f8 | 395 | uint8_t tempFrac = readRegister8(_i2caddr, MAX30102_DIETEMPFRAC); //Causes the clearing of the DIE_TEMP_RDY interrupt |
zinnetyazicii53 | 0:83277b73a1f8 | 396 | |
zinnetyazicii53 | 0:83277b73a1f8 | 397 | // Step 3: Calculate temperature (datasheet pg. 23) |
zinnetyazicii53 | 0:83277b73a1f8 | 398 | return (float)tempInt + ((float)tempFrac * 0.0625); |
zinnetyazicii53 | 0:83277b73a1f8 | 399 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 400 | |
zinnetyazicii53 | 0:83277b73a1f8 | 401 | // Returns die temp in F |
zinnetyazicii53 | 0:83277b73a1f8 | 402 | float readTemperatureF() { |
zinnetyazicii53 | 0:83277b73a1f8 | 403 | float temp = readTemperature(); |
zinnetyazicii53 | 0:83277b73a1f8 | 404 | |
zinnetyazicii53 | 0:83277b73a1f8 | 405 | if (temp != -999.0) temp = temp * 1.8 + 32.0; |
zinnetyazicii53 | 0:83277b73a1f8 | 406 | |
zinnetyazicii53 | 0:83277b73a1f8 | 407 | return (temp); |
zinnetyazicii53 | 0:83277b73a1f8 | 408 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 409 | |
zinnetyazicii53 | 0:83277b73a1f8 | 410 | // Set the PROX_INT_THRESHold |
zinnetyazicii53 | 0:83277b73a1f8 | 411 | void setPROXINTTHRESH(uint8_t val) { |
zinnetyazicii53 | 0:83277b73a1f8 | 412 | writeRegister8(_i2caddr, MAX30102_PROXINTTHRESH, val); |
zinnetyazicii53 | 0:83277b73a1f8 | 413 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 414 | |
zinnetyazicii53 | 0:83277b73a1f8 | 415 | |
zinnetyazicii53 | 0:83277b73a1f8 | 416 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 417 | // Device ID and Revision |
zinnetyazicii53 | 0:83277b73a1f8 | 418 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 419 | uint8_t readPartID() { |
zinnetyazicii53 | 0:83277b73a1f8 | 420 | return readRegister8(_i2caddr, MAX30102_PARTID); |
zinnetyazicii53 | 0:83277b73a1f8 | 421 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 422 | |
zinnetyazicii53 | 0:83277b73a1f8 | 423 | void readRevisionID() { |
zinnetyazicii53 | 0:83277b73a1f8 | 424 | revisionID = readRegister8(_i2caddr, MAX30102_REVISIONID); |
zinnetyazicii53 | 0:83277b73a1f8 | 425 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 426 | |
zinnetyazicii53 | 0:83277b73a1f8 | 427 | uint8_t getRevisionID() { |
zinnetyazicii53 | 0:83277b73a1f8 | 428 | return revisionID; |
zinnetyazicii53 | 0:83277b73a1f8 | 429 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 430 | |
zinnetyazicii53 | 0:83277b73a1f8 | 431 | |
zinnetyazicii53 | 0:83277b73a1f8 | 432 | //Setup the sensor |
zinnetyazicii53 | 0:83277b73a1f8 | 433 | //The MAX30102 has many settings. By default we select: |
zinnetyazicii53 | 0:83277b73a1f8 | 434 | // Sample Average = 4 |
zinnetyazicii53 | 0:83277b73a1f8 | 435 | // Mode = MultiLED |
zinnetyazicii53 | 0:83277b73a1f8 | 436 | // ADC Range = 16384 (62.5pA per LSB) |
zinnetyazicii53 | 0:83277b73a1f8 | 437 | // Sample rate = 50 |
zinnetyazicii53 | 0:83277b73a1f8 | 438 | //Use the default setup if you are just getting started with the MAX30102 sensor |
zinnetyazicii53 | 0:83277b73a1f8 | 439 | void setup(byte powerLevel, byte sampleAverage, byte ledMode, int sampleRate, int pulseWidth, int adcRange) { |
zinnetyazicii53 | 0:83277b73a1f8 | 440 | softReset(); //Reset all configuration, threshold, and data registers to POR values |
zinnetyazicii53 | 0:83277b73a1f8 | 441 | |
zinnetyazicii53 | 0:83277b73a1f8 | 442 | //FIFO Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 443 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 444 | //The chip will average multiple samples of same type together if you wish |
zinnetyazicii53 | 0:83277b73a1f8 | 445 | if (sampleAverage == 1) setFIFOAverage(MAX30102_SAMPLEAVG_1); //No averaging per FIFO record |
zinnetyazicii53 | 0:83277b73a1f8 | 446 | else if (sampleAverage == 2) setFIFOAverage(MAX30102_SAMPLEAVG_2); |
zinnetyazicii53 | 0:83277b73a1f8 | 447 | else if (sampleAverage == 4) setFIFOAverage(MAX30102_SAMPLEAVG_4); |
zinnetyazicii53 | 0:83277b73a1f8 | 448 | else if (sampleAverage == 8) setFIFOAverage(MAX30102_SAMPLEAVG_8); |
zinnetyazicii53 | 0:83277b73a1f8 | 449 | else if (sampleAverage == 16) setFIFOAverage(MAX30102_SAMPLEAVG_16); |
zinnetyazicii53 | 0:83277b73a1f8 | 450 | else if (sampleAverage == 32) setFIFOAverage(MAX30102_SAMPLEAVG_32); |
zinnetyazicii53 | 0:83277b73a1f8 | 451 | else setFIFOAverage(MAX30102_SAMPLEAVG_4); |
zinnetyazicii53 | 0:83277b73a1f8 | 452 | |
zinnetyazicii53 | 0:83277b73a1f8 | 453 | //setFIFOAlmostFull(2); //Set to 30 samples to trigger an 'Almost Full' interrupt |
zinnetyazicii53 | 0:83277b73a1f8 | 454 | enableFIFORollover(); //Allow FIFO to wrap/roll over |
zinnetyazicii53 | 0:83277b73a1f8 | 455 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 456 | |
zinnetyazicii53 | 0:83277b73a1f8 | 457 | //Mode Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 458 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 459 | if (ledMode == 3) setLEDMode(MAX30102_MODE_MULTILED); //Watch all three LED channels |
zinnetyazicii53 | 0:83277b73a1f8 | 460 | else if (ledMode == 2) setLEDMode(MAX30102_MODE_REDIRONLY); //Red and IR |
zinnetyazicii53 | 0:83277b73a1f8 | 461 | else setLEDMode(MAX30102_MODE_REDONLY); //Red only |
zinnetyazicii53 | 0:83277b73a1f8 | 462 | activeLEDs = ledMode; //Used to control how many bytes to read from FIFO buffer |
zinnetyazicii53 | 0:83277b73a1f8 | 463 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 464 | |
zinnetyazicii53 | 0:83277b73a1f8 | 465 | //Particle Sensing Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 466 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 467 | if(adcRange < 4096) setADCRange(MAX30102_ADCRANGE_2048); //7.81pA per LSB |
zinnetyazicii53 | 0:83277b73a1f8 | 468 | else if(adcRange < 8192) setADCRange(MAX30102_ADCRANGE_4096); //15.63pA per LSB |
zinnetyazicii53 | 0:83277b73a1f8 | 469 | else if(adcRange < 16384) setADCRange(MAX30102_ADCRANGE_8192); //31.25pA per LSB |
zinnetyazicii53 | 0:83277b73a1f8 | 470 | else if(adcRange == 16384) setADCRange(MAX30102_ADCRANGE_16384); //62.5pA per LSB |
zinnetyazicii53 | 0:83277b73a1f8 | 471 | else setADCRange(MAX30102_ADCRANGE_2048); |
zinnetyazicii53 | 0:83277b73a1f8 | 472 | |
zinnetyazicii53 | 0:83277b73a1f8 | 473 | if (sampleRate < 100) setSampleRate(MAX30102_SAMPLERATE_50); //Take 50 samples per second |
zinnetyazicii53 | 0:83277b73a1f8 | 474 | else if (sampleRate < 200) setSampleRate(MAX30102_SAMPLERATE_100); |
zinnetyazicii53 | 0:83277b73a1f8 | 475 | else if (sampleRate < 400) setSampleRate(MAX30102_SAMPLERATE_200); |
zinnetyazicii53 | 0:83277b73a1f8 | 476 | else if (sampleRate < 800) setSampleRate(MAX30102_SAMPLERATE_400); |
zinnetyazicii53 | 0:83277b73a1f8 | 477 | else if (sampleRate < 1000) setSampleRate(MAX30102_SAMPLERATE_800); |
zinnetyazicii53 | 0:83277b73a1f8 | 478 | else if (sampleRate < 1600) setSampleRate(MAX30102_SAMPLERATE_1000); |
zinnetyazicii53 | 0:83277b73a1f8 | 479 | else if (sampleRate < 3200) setSampleRate(MAX30102_SAMPLERATE_1600); |
zinnetyazicii53 | 0:83277b73a1f8 | 480 | else if (sampleRate == 3200) setSampleRate(MAX30102_SAMPLERATE_3200); |
zinnetyazicii53 | 0:83277b73a1f8 | 481 | else setSampleRate(MAX30102_SAMPLERATE_50); |
zinnetyazicii53 | 0:83277b73a1f8 | 482 | |
zinnetyazicii53 | 0:83277b73a1f8 | 483 | //The longer the pulse width the longer range of detection you'll have |
zinnetyazicii53 | 0:83277b73a1f8 | 484 | //At 69us and 0.4mA it's about 2 inches |
zinnetyazicii53 | 0:83277b73a1f8 | 485 | //At 411us and 0.4mA it's about 6 inches |
zinnetyazicii53 | 0:83277b73a1f8 | 486 | if (pulseWidth < 118) setPulseWidth(MAX30102_PULSEWIDTH_69); //Page 26, Gets us 15 bit resolution |
zinnetyazicii53 | 0:83277b73a1f8 | 487 | else if (pulseWidth < 215) setPulseWidth(MAX30102_PULSEWIDTH_118); //16 bit resolution |
zinnetyazicii53 | 0:83277b73a1f8 | 488 | else if (pulseWidth < 411) setPulseWidth(MAX30102_PULSEWIDTH_215); //17 bit resolution |
zinnetyazicii53 | 0:83277b73a1f8 | 489 | else if (pulseWidth == 411) setPulseWidth(MAX30102_PULSEWIDTH_411); //18 bit resolution |
zinnetyazicii53 | 0:83277b73a1f8 | 490 | else setPulseWidth(MAX30102_PULSEWIDTH_69); |
zinnetyazicii53 | 0:83277b73a1f8 | 491 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 492 | |
zinnetyazicii53 | 0:83277b73a1f8 | 493 | //LED Pulse Amplitude Configuration |
zinnetyazicii53 | 0:83277b73a1f8 | 494 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 495 | //Default is 0x1F which gets us 6.4mA |
zinnetyazicii53 | 0:83277b73a1f8 | 496 | //powerLevel = 0x02, 0.4mA - Presence detection of ~4 inch |
zinnetyazicii53 | 0:83277b73a1f8 | 497 | //powerLevel = 0x1F, 6.4mA - Presence detection of ~8 inch |
zinnetyazicii53 | 0:83277b73a1f8 | 498 | //powerLevel = 0x7F, 25.4mA - Presence detection of ~8 inch |
zinnetyazicii53 | 0:83277b73a1f8 | 499 | //powerLevel = 0xFF, 50.0mA - Presence detection of ~12 inch |
zinnetyazicii53 | 0:83277b73a1f8 | 500 | |
zinnetyazicii53 | 0:83277b73a1f8 | 501 | setPulseAmplitudeRed(powerLevel); |
zinnetyazicii53 | 0:83277b73a1f8 | 502 | setPulseAmplitudeIR(powerLevel); |
zinnetyazicii53 | 0:83277b73a1f8 | 503 | setPulseAmplitudeGreen(powerLevel); |
zinnetyazicii53 | 0:83277b73a1f8 | 504 | setPulseAmplitudeProximity(powerLevel); |
zinnetyazicii53 | 0:83277b73a1f8 | 505 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 506 | |
zinnetyazicii53 | 0:83277b73a1f8 | 507 | //Multi-LED Mode Configuration, Enable the reading of the three LEDs |
zinnetyazicii53 | 0:83277b73a1f8 | 508 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 509 | enableSlot(1, SLOT_RED_LED); |
zinnetyazicii53 | 0:83277b73a1f8 | 510 | if (ledMode > 1) enableSlot(2, SLOT_IR_LED); |
zinnetyazicii53 | 0:83277b73a1f8 | 511 | if (ledMode > 2) enableSlot(3, SLOT_GREEN_LED); |
zinnetyazicii53 | 0:83277b73a1f8 | 512 | //enableSlot(1, SLOT_RED_PILOT); |
zinnetyazicii53 | 0:83277b73a1f8 | 513 | //enableSlot(2, SLOT_IR_PILOT); |
zinnetyazicii53 | 0:83277b73a1f8 | 514 | //enableSlot(3, SLOT_GREEN_PILOT); |
zinnetyazicii53 | 0:83277b73a1f8 | 515 | //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- |
zinnetyazicii53 | 0:83277b73a1f8 | 516 | |
zinnetyazicii53 | 0:83277b73a1f8 | 517 | clearFIFO(); //Reset the FIFO before we begin checking the sensor |
zinnetyazicii53 | 0:83277b73a1f8 | 518 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 519 | |
zinnetyazicii53 | 0:83277b73a1f8 | 520 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 521 | // Data Collection |
zinnetyazicii53 | 0:83277b73a1f8 | 522 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 523 | |
zinnetyazicii53 | 0:83277b73a1f8 | 524 | //Tell caller how many samples are available |
zinnetyazicii53 | 0:83277b73a1f8 | 525 | uint8_t available(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 526 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 527 | int8_t numberOfSamples = sense.head - sense.tail; |
zinnetyazicii53 | 0:83277b73a1f8 | 528 | if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE; |
zinnetyazicii53 | 0:83277b73a1f8 | 529 | |
zinnetyazicii53 | 0:83277b73a1f8 | 530 | return (numberOfSamples); |
zinnetyazicii53 | 0:83277b73a1f8 | 531 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 532 | |
zinnetyazicii53 | 0:83277b73a1f8 | 533 | //Report the most recent red value |
zinnetyazicii53 | 0:83277b73a1f8 | 534 | uint32_t getRed(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 535 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 536 | //Check the sensor for new data for 250ms |
zinnetyazicii53 | 0:83277b73a1f8 | 537 | if(safeCheck(250)) |
zinnetyazicii53 | 0:83277b73a1f8 | 538 | return (sense.red[sense.head]); |
zinnetyazicii53 | 0:83277b73a1f8 | 539 | else |
zinnetyazicii53 | 0:83277b73a1f8 | 540 | return(0); //Sensor failed to find new data |
zinnetyazicii53 | 0:83277b73a1f8 | 541 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 542 | |
zinnetyazicii53 | 0:83277b73a1f8 | 543 | //Report the most recent IR value |
zinnetyazicii53 | 0:83277b73a1f8 | 544 | uint32_t getIR(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 545 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 546 | //Check the sensor for new data for 250ms |
zinnetyazicii53 | 0:83277b73a1f8 | 547 | if(safeCheck(250)) |
zinnetyazicii53 | 0:83277b73a1f8 | 548 | return (sense.IR[sense.head]); |
zinnetyazicii53 | 0:83277b73a1f8 | 549 | else |
zinnetyazicii53 | 0:83277b73a1f8 | 550 | return(0); //Sensor failed to find new data |
zinnetyazicii53 | 0:83277b73a1f8 | 551 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 552 | |
zinnetyazicii53 | 0:83277b73a1f8 | 553 | //Report the most recent Green value |
zinnetyazicii53 | 0:83277b73a1f8 | 554 | uint32_t getGreen(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 555 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 556 | //Check the sensor for new data for 250ms |
zinnetyazicii53 | 0:83277b73a1f8 | 557 | if(safeCheck(250)) |
zinnetyazicii53 | 0:83277b73a1f8 | 558 | return (sense.green[sense.head]); |
zinnetyazicii53 | 0:83277b73a1f8 | 559 | else |
zinnetyazicii53 | 0:83277b73a1f8 | 560 | return(0); //Sensor failed to find new data |
zinnetyazicii53 | 0:83277b73a1f8 | 561 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 562 | |
zinnetyazicii53 | 0:83277b73a1f8 | 563 | //Report the next Red value in the FIFO |
zinnetyazicii53 | 0:83277b73a1f8 | 564 | uint32_t getFIFORed(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 565 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 566 | return (sense.red[sense.tail]); |
zinnetyazicii53 | 0:83277b73a1f8 | 567 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 568 | |
zinnetyazicii53 | 0:83277b73a1f8 | 569 | //Report the next IR value in the FIFO |
zinnetyazicii53 | 0:83277b73a1f8 | 570 | uint32_t getFIFOIR(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 571 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 572 | return (sense.IR[sense.tail]); |
zinnetyazicii53 | 0:83277b73a1f8 | 573 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 574 | |
zinnetyazicii53 | 0:83277b73a1f8 | 575 | //Report the next Green value in the FIFO |
zinnetyazicii53 | 0:83277b73a1f8 | 576 | uint32_t getFIFOGreen(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 577 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 578 | return (sense.green[sense.tail]); |
zinnetyazicii53 | 0:83277b73a1f8 | 579 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 580 | |
zinnetyazicii53 | 0:83277b73a1f8 | 581 | //Advance the tail |
zinnetyazicii53 | 0:83277b73a1f8 | 582 | void nextSample(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 583 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 584 | if(available()) //Only advance the tail if new data is available |
zinnetyazicii53 | 0:83277b73a1f8 | 585 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 586 | sense.tail++; |
zinnetyazicii53 | 0:83277b73a1f8 | 587 | sense.tail %= STORAGE_SIZE; //Wrap condition |
zinnetyazicii53 | 0:83277b73a1f8 | 588 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 589 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 590 | |
zinnetyazicii53 | 0:83277b73a1f8 | 591 | //Polls the sensor for new data |
zinnetyazicii53 | 0:83277b73a1f8 | 592 | //Call regularly |
zinnetyazicii53 | 0:83277b73a1f8 | 593 | //If new data is available, it updates the head and tail in the main struct |
zinnetyazicii53 | 0:83277b73a1f8 | 594 | //Returns number of new samples obtained |
zinnetyazicii53 | 0:83277b73a1f8 | 595 | uint16_t check(void) |
zinnetyazicii53 | 0:83277b73a1f8 | 596 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 597 | //Read register FIDO_DATA in (3-byte * number of active LED) chunks |
zinnetyazicii53 | 0:83277b73a1f8 | 598 | //Until FIFO_RD_PTR = FIFO_WR_PTR |
zinnetyazicii53 | 0:83277b73a1f8 | 599 | |
zinnetyazicii53 | 0:83277b73a1f8 | 600 | byte readPointer = getReadPointer(); |
zinnetyazicii53 | 0:83277b73a1f8 | 601 | byte writePointer = getWritePointer(); |
zinnetyazicii53 | 0:83277b73a1f8 | 602 | |
zinnetyazicii53 | 0:83277b73a1f8 | 603 | int numberOfSamples = 0; |
zinnetyazicii53 | 0:83277b73a1f8 | 604 | |
zinnetyazicii53 | 0:83277b73a1f8 | 605 | //Do we have new data? |
zinnetyazicii53 | 0:83277b73a1f8 | 606 | if (readPointer != writePointer) |
zinnetyazicii53 | 0:83277b73a1f8 | 607 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 608 | //Calculate the number of readings we need to get from sensor |
zinnetyazicii53 | 0:83277b73a1f8 | 609 | numberOfSamples = writePointer - readPointer; |
zinnetyazicii53 | 0:83277b73a1f8 | 610 | if (numberOfSamples < 0) numberOfSamples += 32; //Wrap condition |
zinnetyazicii53 | 0:83277b73a1f8 | 611 | |
zinnetyazicii53 | 0:83277b73a1f8 | 612 | //We now have the number of readings, now calc bytes to read |
zinnetyazicii53 | 0:83277b73a1f8 | 613 | //For this example we are just doing Red and IR (3 bytes each) |
zinnetyazicii53 | 0:83277b73a1f8 | 614 | int bytesLeftToRead = numberOfSamples * activeLEDs * 3; |
zinnetyazicii53 | 0:83277b73a1f8 | 615 | |
zinnetyazicii53 | 0:83277b73a1f8 | 616 | //Get ready to read a burst of data from the FIFO register |
zinnetyazicii53 | 0:83277b73a1f8 | 617 | _i2cPort->beginTransmission(MAX30102_ADDRESS); |
zinnetyazicii53 | 0:83277b73a1f8 | 618 | _i2cPort->write(MAX30102_FIFODATA); |
zinnetyazicii53 | 0:83277b73a1f8 | 619 | _i2cPort->endTransmission(); |
zinnetyazicii53 | 0:83277b73a1f8 | 620 | |
zinnetyazicii53 | 0:83277b73a1f8 | 621 | //We may need to read as many as 288 bytes so we read in blocks no larger than I2C_BUFFER_LENGTH |
zinnetyazicii53 | 0:83277b73a1f8 | 622 | //I2C_BUFFER_LENGTH changes based on the platform. 64 bytes for SAMD21, 32 bytes for Uno. |
zinnetyazicii53 | 0:83277b73a1f8 | 623 | //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno |
zinnetyazicii53 | 0:83277b73a1f8 | 624 | while (bytesLeftToRead > 0) |
zinnetyazicii53 | 0:83277b73a1f8 | 625 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 626 | int toGet = bytesLeftToRead; |
zinnetyazicii53 | 0:83277b73a1f8 | 627 | if (toGet > I2C_BUFFER_LENGTH) |
zinnetyazicii53 | 0:83277b73a1f8 | 628 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 629 | //If toGet is 32 this is bad because we read 6 bytes (Red+IR * 3 = 6) at a time |
zinnetyazicii53 | 0:83277b73a1f8 | 630 | //32 % 6 = 2 left over. We don't want to request 32 bytes, we want to request 30. |
zinnetyazicii53 | 0:83277b73a1f8 | 631 | //32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27. |
zinnetyazicii53 | 0:83277b73a1f8 | 632 | |
zinnetyazicii53 | 0:83277b73a1f8 | 633 | toGet = I2C_BUFFER_LENGTH - (I2C_BUFFER_LENGTH % (activeLEDs * 3)); //Trim toGet to be a multiple of the samples we need to read |
zinnetyazicii53 | 0:83277b73a1f8 | 634 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 635 | |
zinnetyazicii53 | 0:83277b73a1f8 | 636 | bytesLeftToRead -= toGet; |
zinnetyazicii53 | 0:83277b73a1f8 | 637 | |
zinnetyazicii53 | 0:83277b73a1f8 | 638 | //Request toGet number of bytes from sensor |
zinnetyazicii53 | 0:83277b73a1f8 | 639 | _i2cPort->requestFrom(MAX30102_ADDRESS, toGet); |
zinnetyazicii53 | 0:83277b73a1f8 | 640 | |
zinnetyazicii53 | 0:83277b73a1f8 | 641 | while (toGet > 0) |
zinnetyazicii53 | 0:83277b73a1f8 | 642 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 643 | sense.head++; //Advance the head of the storage struct |
zinnetyazicii53 | 0:83277b73a1f8 | 644 | sense.head %= STORAGE_SIZE; //Wrap condition |
zinnetyazicii53 | 0:83277b73a1f8 | 645 | |
zinnetyazicii53 | 0:83277b73a1f8 | 646 | byte temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long |
zinnetyazicii53 | 0:83277b73a1f8 | 647 | uint32_t tempLong; |
zinnetyazicii53 | 0:83277b73a1f8 | 648 | |
zinnetyazicii53 | 0:83277b73a1f8 | 649 | //Burst read three bytes - RED |
zinnetyazicii53 | 0:83277b73a1f8 | 650 | temp[3] = 0; |
zinnetyazicii53 | 0:83277b73a1f8 | 651 | temp[2] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 652 | temp[1] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 653 | temp[0] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 654 | |
zinnetyazicii53 | 0:83277b73a1f8 | 655 | //Convert array to long |
zinnetyazicii53 | 0:83277b73a1f8 | 656 | memcpy(&tempLong, temp, sizeof(tempLong)); |
zinnetyazicii53 | 0:83277b73a1f8 | 657 | |
zinnetyazicii53 | 0:83277b73a1f8 | 658 | tempLong &= 0x3FFFF; //Zero out all but 18 bits |
zinnetyazicii53 | 0:83277b73a1f8 | 659 | |
zinnetyazicii53 | 0:83277b73a1f8 | 660 | sense.red[sense.head] = tempLong; //Store this reading into the sense array |
zinnetyazicii53 | 0:83277b73a1f8 | 661 | |
zinnetyazicii53 | 0:83277b73a1f8 | 662 | if (activeLEDs > 1) |
zinnetyazicii53 | 0:83277b73a1f8 | 663 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 664 | //Burst read three more bytes - IR |
zinnetyazicii53 | 0:83277b73a1f8 | 665 | temp[3] = 0; |
zinnetyazicii53 | 0:83277b73a1f8 | 666 | temp[2] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 667 | temp[1] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 668 | temp[0] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 669 | |
zinnetyazicii53 | 0:83277b73a1f8 | 670 | //Convert array to long |
zinnetyazicii53 | 0:83277b73a1f8 | 671 | memcpy(&tempLong, temp, sizeof(tempLong)); |
zinnetyazicii53 | 0:83277b73a1f8 | 672 | |
zinnetyazicii53 | 0:83277b73a1f8 | 673 | tempLong &= 0x3FFFF; //Zero out all but 18 bits |
zinnetyazicii53 | 0:83277b73a1f8 | 674 | |
zinnetyazicii53 | 0:83277b73a1f8 | 675 | sense.IR[sense.head] = tempLong; |
zinnetyazicii53 | 0:83277b73a1f8 | 676 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 677 | |
zinnetyazicii53 | 0:83277b73a1f8 | 678 | if (activeLEDs > 2) |
zinnetyazicii53 | 0:83277b73a1f8 | 679 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 680 | //Burst read three more bytes - Green |
zinnetyazicii53 | 0:83277b73a1f8 | 681 | temp[3] = 0; |
zinnetyazicii53 | 0:83277b73a1f8 | 682 | temp[2] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 683 | temp[1] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 684 | temp[0] = _i2cPort->read(); |
zinnetyazicii53 | 0:83277b73a1f8 | 685 | |
zinnetyazicii53 | 0:83277b73a1f8 | 686 | //Convert array to long |
zinnetyazicii53 | 0:83277b73a1f8 | 687 | memcpy(&tempLong, temp, sizeof(tempLong)); |
zinnetyazicii53 | 0:83277b73a1f8 | 688 | |
zinnetyazicii53 | 0:83277b73a1f8 | 689 | tempLong &= 0x3FFFF; //Zero out all but 18 bits |
zinnetyazicii53 | 0:83277b73a1f8 | 690 | |
zinnetyazicii53 | 0:83277b73a1f8 | 691 | sense.green[sense.head] = tempLong; |
zinnetyazicii53 | 0:83277b73a1f8 | 692 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 693 | |
zinnetyazicii53 | 0:83277b73a1f8 | 694 | toGet -= activeLEDs * 3; |
zinnetyazicii53 | 0:83277b73a1f8 | 695 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 696 | |
zinnetyazicii53 | 0:83277b73a1f8 | 697 | } //End while (bytesLeftToRead > 0) |
zinnetyazicii53 | 0:83277b73a1f8 | 698 | |
zinnetyazicii53 | 0:83277b73a1f8 | 699 | } //End readPtr != writePtr |
zinnetyazicii53 | 0:83277b73a1f8 | 700 | |
zinnetyazicii53 | 0:83277b73a1f8 | 701 | return (numberOfSamples); //Let the world know how much new data we found |
zinnetyazicii53 | 0:83277b73a1f8 | 702 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 703 | |
zinnetyazicii53 | 0:83277b73a1f8 | 704 | //Check for new data but give up after a certain amount of time |
zinnetyazicii53 | 0:83277b73a1f8 | 705 | //Returns true if new data was found |
zinnetyazicii53 | 0:83277b73a1f8 | 706 | //Returns false if new data was not found |
zinnetyazicii53 | 0:83277b73a1f8 | 707 | bool safeCheck(uint8_t maxTimeToCheck) |
zinnetyazicii53 | 0:83277b73a1f8 | 708 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 709 | uint32_t markTime = millis(); |
zinnetyazicii53 | 0:83277b73a1f8 | 710 | |
zinnetyazicii53 | 0:83277b73a1f8 | 711 | while(1) |
zinnetyazicii53 | 0:83277b73a1f8 | 712 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 713 | if(millis() - markTime > maxTimeToCheck) return(false); |
zinnetyazicii53 | 0:83277b73a1f8 | 714 | |
zinnetyazicii53 | 0:83277b73a1f8 | 715 | if(check() == true) //We found new data! |
zinnetyazicii53 | 0:83277b73a1f8 | 716 | return(true); |
zinnetyazicii53 | 0:83277b73a1f8 | 717 | |
zinnetyazicii53 | 0:83277b73a1f8 | 718 | delay(1); |
zinnetyazicii53 | 0:83277b73a1f8 | 719 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 720 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 721 | |
zinnetyazicii53 | 0:83277b73a1f8 | 722 | //Given a register, read it, mask it, and then set the thing |
zinnetyazicii53 | 0:83277b73a1f8 | 723 | void bitMask(uint8_t reg, uint8_t mask, uint8_t thing) |
zinnetyazicii53 | 0:83277b73a1f8 | 724 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 725 | // Grab current register context |
zinnetyazicii53 | 0:83277b73a1f8 | 726 | uint8_t originalContents = readRegister8(_i2caddr, reg); |
zinnetyazicii53 | 0:83277b73a1f8 | 727 | |
zinnetyazicii53 | 0:83277b73a1f8 | 728 | // Zero-out the portions of the register we're interested in |
zinnetyazicii53 | 0:83277b73a1f8 | 729 | originalContents = originalContents & mask; |
zinnetyazicii53 | 0:83277b73a1f8 | 730 | |
zinnetyazicii53 | 0:83277b73a1f8 | 731 | // Change contents |
zinnetyazicii53 | 0:83277b73a1f8 | 732 | writeRegister8(_i2caddr, reg, originalContents | thing); |
zinnetyazicii53 | 0:83277b73a1f8 | 733 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 734 | |
zinnetyazicii53 | 0:83277b73a1f8 | 735 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 736 | // Low-level I2C Communication |
zinnetyazicii53 | 0:83277b73a1f8 | 737 | // |
zinnetyazicii53 | 0:83277b73a1f8 | 738 | uint8_t readRegister8(uint8_t address, uint8_t reg) { |
zinnetyazicii53 | 0:83277b73a1f8 | 739 | _i2cPort->beginTransmission(address); |
zinnetyazicii53 | 0:83277b73a1f8 | 740 | _i2cPort->write(reg); |
zinnetyazicii53 | 0:83277b73a1f8 | 741 | _i2cPort->endTransmission(false); |
zinnetyazicii53 | 0:83277b73a1f8 | 742 | |
zinnetyazicii53 | 0:83277b73a1f8 | 743 | _i2cPort->requestFrom((uint8_t)address, (uint8_t)1); // Request 1 byte |
zinnetyazicii53 | 0:83277b73a1f8 | 744 | if (_i2cPort->available()) |
zinnetyazicii53 | 0:83277b73a1f8 | 745 | { |
zinnetyazicii53 | 0:83277b73a1f8 | 746 | return(_i2cPort->read()); |
zinnetyazicii53 | 0:83277b73a1f8 | 747 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 748 | |
zinnetyazicii53 | 0:83277b73a1f8 | 749 | return (0); //Fail |
zinnetyazicii53 | 0:83277b73a1f8 | 750 | |
zinnetyazicii53 | 0:83277b73a1f8 | 751 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 752 | |
zinnetyazicii53 | 0:83277b73a1f8 | 753 | void writeRegister8(uint8_t address, uint8_t reg, uint8_t value) { |
zinnetyazicii53 | 0:83277b73a1f8 | 754 | _i2cPort->beginTransmission(address); |
zinnetyazicii53 | 0:83277b73a1f8 | 755 | _i2cPort->write(reg); |
zinnetyazicii53 | 0:83277b73a1f8 | 756 | _i2cPort->write(value); |
zinnetyazicii53 | 0:83277b73a1f8 | 757 | _i2cPort->endTransmission(); |
zinnetyazicii53 | 0:83277b73a1f8 | 758 | } |
zinnetyazicii53 | 0:83277b73a1f8 | 759 | */ |