HAND
MAX30100.cpp@1:a9cc51956082, 2021-11-03 (annotated)
- Committer:
- condato_mbed
- Date:
- Wed Nov 03 15:59:01 2021 +0000
- Revision:
- 1:a9cc51956082
- Parent:
- 0:010b908e2187
HAND
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AVELARDEV | 0:010b908e2187 | 1 | /* |
AVELARDEV | 0:010b908e2187 | 2 | Arduino-MAX30100 oximetry / heart rate integrated sensor library |
AVELARDEV | 0:010b908e2187 | 3 | Copyright (C) 2016 OXullo Intersecans <x@brainrapers.org> |
AVELARDEV | 0:010b908e2187 | 4 | This program is free software: you can redistribute it and/or modify |
AVELARDEV | 0:010b908e2187 | 5 | it under the terms of the GNU General Public License as published by |
AVELARDEV | 0:010b908e2187 | 6 | the Free Software Foundation, either version 3 of the License, or |
AVELARDEV | 0:010b908e2187 | 7 | (at your option) any later version. |
AVELARDEV | 0:010b908e2187 | 8 | This program is distributed in the hope that it will be useful, |
AVELARDEV | 0:010b908e2187 | 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
AVELARDEV | 0:010b908e2187 | 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
AVELARDEV | 0:010b908e2187 | 11 | GNU General Public License for more details. |
AVELARDEV | 0:010b908e2187 | 12 | You should have received a copy of the GNU General Public License |
AVELARDEV | 0:010b908e2187 | 13 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
AVELARDEV | 0:010b908e2187 | 14 | */ |
AVELARDEV | 0:010b908e2187 | 15 | |
AVELARDEV | 0:010b908e2187 | 16 | #include "MAX30100.h" |
AVELARDEV | 0:010b908e2187 | 17 | |
condato_mbed | 1:a9cc51956082 | 18 | extern I2C i2c; |
condato_mbed | 1:a9cc51956082 | 19 | //I2C Wire(P3_4 , P3_5 ); |
AVELARDEV | 0:010b908e2187 | 20 | |
AVELARDEV | 0:010b908e2187 | 21 | MAX30100::MAX30100() |
AVELARDEV | 0:010b908e2187 | 22 | { |
AVELARDEV | 0:010b908e2187 | 23 | |
AVELARDEV | 0:010b908e2187 | 24 | } |
AVELARDEV | 0:010b908e2187 | 25 | |
AVELARDEV | 0:010b908e2187 | 26 | bool MAX30100::begin() |
AVELARDEV | 0:010b908e2187 | 27 | { |
AVELARDEV | 0:010b908e2187 | 28 | // Wire.begin(); |
AVELARDEV | 0:010b908e2187 | 29 | // Wire.setClock(I2C_BUS_SPEED); |
AVELARDEV | 0:010b908e2187 | 30 | |
condato_mbed | 1:a9cc51956082 | 31 | //Wire.frequency(I2C_BUS_SPEED); |
AVELARDEV | 0:010b908e2187 | 32 | |
AVELARDEV | 0:010b908e2187 | 33 | if(!setMode(DEFAULT_MODE)) |
AVELARDEV | 0:010b908e2187 | 34 | return false; |
AVELARDEV | 0:010b908e2187 | 35 | if(!setLedsPulseWidth(DEFAULT_PULSE_WIDTH)) |
AVELARDEV | 0:010b908e2187 | 36 | return false; |
AVELARDEV | 0:010b908e2187 | 37 | if(!setSamplingRate(DEFAULT_SAMPLING_RATE)) |
AVELARDEV | 0:010b908e2187 | 38 | return false; |
AVELARDEV | 0:010b908e2187 | 39 | if(!setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT)) |
AVELARDEV | 0:010b908e2187 | 40 | return false; |
AVELARDEV | 0:010b908e2187 | 41 | if(!setHighresModeEnabled(true)) |
AVELARDEV | 0:010b908e2187 | 42 | return false; |
AVELARDEV | 0:010b908e2187 | 43 | |
AVELARDEV | 0:010b908e2187 | 44 | return true; |
AVELARDEV | 0:010b908e2187 | 45 | } |
AVELARDEV | 0:010b908e2187 | 46 | |
AVELARDEV | 0:010b908e2187 | 47 | bool MAX30100::setMode(Mode mode) |
AVELARDEV | 0:010b908e2187 | 48 | { |
AVELARDEV | 0:010b908e2187 | 49 | if(!writeRegister(MAX30100_REG_MODE_CONFIGURATION, mode)) |
AVELARDEV | 0:010b908e2187 | 50 | return false; |
AVELARDEV | 0:010b908e2187 | 51 | else |
AVELARDEV | 0:010b908e2187 | 52 | return true; |
AVELARDEV | 0:010b908e2187 | 53 | } |
AVELARDEV | 0:010b908e2187 | 54 | |
AVELARDEV | 0:010b908e2187 | 55 | bool MAX30100::setLedsPulseWidth(LEDPulseWidth ledPulseWidth) |
AVELARDEV | 0:010b908e2187 | 56 | { |
AVELARDEV | 0:010b908e2187 | 57 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 58 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 59 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xfc) | ledPulseWidth)) |
AVELARDEV | 0:010b908e2187 | 60 | return false; |
AVELARDEV | 0:010b908e2187 | 61 | else |
AVELARDEV | 0:010b908e2187 | 62 | return true; |
AVELARDEV | 0:010b908e2187 | 63 | else |
AVELARDEV | 0:010b908e2187 | 64 | return false; |
AVELARDEV | 0:010b908e2187 | 65 | } |
AVELARDEV | 0:010b908e2187 | 66 | |
AVELARDEV | 0:010b908e2187 | 67 | bool MAX30100::setSamplingRate(SamplingRate samplingRate) |
AVELARDEV | 0:010b908e2187 | 68 | { |
AVELARDEV | 0:010b908e2187 | 69 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 70 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 71 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xe3) | (samplingRate << 2))) |
AVELARDEV | 0:010b908e2187 | 72 | return false; |
AVELARDEV | 0:010b908e2187 | 73 | else |
AVELARDEV | 0:010b908e2187 | 74 | return true; |
AVELARDEV | 0:010b908e2187 | 75 | else |
AVELARDEV | 0:010b908e2187 | 76 | return false; |
AVELARDEV | 0:010b908e2187 | 77 | } |
AVELARDEV | 0:010b908e2187 | 78 | |
AVELARDEV | 0:010b908e2187 | 79 | bool MAX30100::setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent) |
AVELARDEV | 0:010b908e2187 | 80 | { |
AVELARDEV | 0:010b908e2187 | 81 | if(!writeRegister(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent)) |
AVELARDEV | 0:010b908e2187 | 82 | return false; |
AVELARDEV | 0:010b908e2187 | 83 | else |
AVELARDEV | 0:010b908e2187 | 84 | return true; |
AVELARDEV | 0:010b908e2187 | 85 | } |
AVELARDEV | 0:010b908e2187 | 86 | |
AVELARDEV | 0:010b908e2187 | 87 | bool MAX30100::setHighresModeEnabled(bool enabled) |
AVELARDEV | 0:010b908e2187 | 88 | { |
AVELARDEV | 0:010b908e2187 | 89 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 90 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 91 | if (enabled) { |
AVELARDEV | 0:010b908e2187 | 92 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous | MAX30100_SPC_SPO2_HI_RES_EN)) |
AVELARDEV | 0:010b908e2187 | 93 | return false; |
AVELARDEV | 0:010b908e2187 | 94 | else |
AVELARDEV | 0:010b908e2187 | 95 | return true; |
AVELARDEV | 0:010b908e2187 | 96 | } else { |
AVELARDEV | 0:010b908e2187 | 97 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous & ~MAX30100_SPC_SPO2_HI_RES_EN)) |
AVELARDEV | 0:010b908e2187 | 98 | return false; |
AVELARDEV | 0:010b908e2187 | 99 | else |
AVELARDEV | 0:010b908e2187 | 100 | return true; |
AVELARDEV | 0:010b908e2187 | 101 | } |
AVELARDEV | 0:010b908e2187 | 102 | else |
AVELARDEV | 0:010b908e2187 | 103 | return false; |
AVELARDEV | 0:010b908e2187 | 104 | } |
AVELARDEV | 0:010b908e2187 | 105 | |
AVELARDEV | 0:010b908e2187 | 106 | |
AVELARDEV | 0:010b908e2187 | 107 | bool MAX30100::update() |
AVELARDEV | 0:010b908e2187 | 108 | { |
AVELARDEV | 0:010b908e2187 | 109 | if(!readFifoData()) |
AVELARDEV | 0:010b908e2187 | 110 | return false; |
AVELARDEV | 0:010b908e2187 | 111 | else |
AVELARDEV | 0:010b908e2187 | 112 | return true; |
AVELARDEV | 0:010b908e2187 | 113 | } |
AVELARDEV | 0:010b908e2187 | 114 | |
AVELARDEV | 0:010b908e2187 | 115 | |
AVELARDEV | 0:010b908e2187 | 116 | /* |
AVELARDEV | 0:010b908e2187 | 117 | uint8_t MAX30100::readRegister(uint8_t address) |
AVELARDEV | 0:010b908e2187 | 118 | { |
AVELARDEV | 0:010b908e2187 | 119 | Wire.beginTransmission(MAX30100_I2C_ADDRESS); |
AVELARDEV | 0:010b908e2187 | 120 | Wire.write(address); |
AVELARDEV | 0:010b908e2187 | 121 | Wire.endTransmission(false); |
AVELARDEV | 0:010b908e2187 | 122 | Wire.requestFrom(MAX30100_I2C_ADDRESS, 1); |
AVELARDEV | 0:010b908e2187 | 123 | |
AVELARDEV | 0:010b908e2187 | 124 | return Wire.read(); |
AVELARDEV | 0:010b908e2187 | 125 | } |
AVELARDEV | 0:010b908e2187 | 126 | */ |
AVELARDEV | 0:010b908e2187 | 127 | |
AVELARDEV | 0:010b908e2187 | 128 | bool MAX30100::readRegister(uint8_t uch_addr, uint8_t *puch_data) |
AVELARDEV | 0:010b908e2187 | 129 | /** |
AVELARDEV | 0:010b908e2187 | 130 | * \brief Read a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 131 | * \par Details |
AVELARDEV | 0:010b908e2187 | 132 | * This function reads a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 133 | * |
AVELARDEV | 0:010b908e2187 | 134 | * \param[in] uch_addr - register address |
AVELARDEV | 0:010b908e2187 | 135 | * \param[out] puch_data - pointer that stores the register data |
AVELARDEV | 0:010b908e2187 | 136 | * |
AVELARDEV | 0:010b908e2187 | 137 | * \retval true on success |
AVELARDEV | 0:010b908e2187 | 138 | */ |
AVELARDEV | 0:010b908e2187 | 139 | { |
AVELARDEV | 0:010b908e2187 | 140 | char ch_i2c_data; |
AVELARDEV | 0:010b908e2187 | 141 | ch_i2c_data=uch_addr; |
condato_mbed | 1:a9cc51956082 | 142 | if(i2c.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0) |
AVELARDEV | 0:010b908e2187 | 143 | return false; |
condato_mbed | 1:a9cc51956082 | 144 | if(i2c.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0) |
AVELARDEV | 0:010b908e2187 | 145 | { |
AVELARDEV | 0:010b908e2187 | 146 | *puch_data=(uint8_t) ch_i2c_data; |
AVELARDEV | 0:010b908e2187 | 147 | return true; |
AVELARDEV | 0:010b908e2187 | 148 | } |
AVELARDEV | 0:010b908e2187 | 149 | else |
AVELARDEV | 0:010b908e2187 | 150 | return false; |
AVELARDEV | 0:010b908e2187 | 151 | } |
AVELARDEV | 0:010b908e2187 | 152 | |
AVELARDEV | 0:010b908e2187 | 153 | /* |
AVELARDEV | 0:010b908e2187 | 154 | void MAX30100::writeRegister(uint8_t address, uint8_t data) |
AVELARDEV | 0:010b908e2187 | 155 | { |
AVELARDEV | 0:010b908e2187 | 156 | Wire.beginTransmission(MAX30100_I2C_ADDRESS); |
AVELARDEV | 0:010b908e2187 | 157 | Wire.write(address); |
AVELARDEV | 0:010b908e2187 | 158 | Wire.write(data); |
AVELARDEV | 0:010b908e2187 | 159 | Wire.endTransmission(); |
AVELARDEV | 0:010b908e2187 | 160 | } |
AVELARDEV | 0:010b908e2187 | 161 | */ |
AVELARDEV | 0:010b908e2187 | 162 | |
AVELARDEV | 0:010b908e2187 | 163 | bool MAX30100::writeRegister(uint8_t uch_addr, uint8_t uch_data) |
AVELARDEV | 0:010b908e2187 | 164 | /** |
AVELARDEV | 0:010b908e2187 | 165 | * \brief Write a value to a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 166 | * \par Details |
AVELARDEV | 0:010b908e2187 | 167 | * This function writes a value to a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 168 | * |
AVELARDEV | 0:010b908e2187 | 169 | * \param[in] uch_addr - register address |
AVELARDEV | 0:010b908e2187 | 170 | * \param[in] uch_data - register data |
AVELARDEV | 0:010b908e2187 | 171 | * |
AVELARDEV | 0:010b908e2187 | 172 | * \retval true on success |
AVELARDEV | 0:010b908e2187 | 173 | */ |
AVELARDEV | 0:010b908e2187 | 174 | { |
AVELARDEV | 0:010b908e2187 | 175 | char ach_i2c_data[2]; |
AVELARDEV | 0:010b908e2187 | 176 | ach_i2c_data[0]=uch_addr; |
AVELARDEV | 0:010b908e2187 | 177 | ach_i2c_data[1]=uch_data; |
AVELARDEV | 0:010b908e2187 | 178 | |
condato_mbed | 1:a9cc51956082 | 179 | if(i2c.write(I2C_WRITE_ADDR, ach_i2c_data, 2, false)==0) |
AVELARDEV | 0:010b908e2187 | 180 | return true; |
AVELARDEV | 0:010b908e2187 | 181 | else |
AVELARDEV | 0:010b908e2187 | 182 | return false; |
AVELARDEV | 0:010b908e2187 | 183 | } |
AVELARDEV | 0:010b908e2187 | 184 | |
AVELARDEV | 0:010b908e2187 | 185 | bool MAX30100::readFifoData() |
AVELARDEV | 0:010b908e2187 | 186 | { |
AVELARDEV | 0:010b908e2187 | 187 | char ach_i2c_data[4]; |
AVELARDEV | 0:010b908e2187 | 188 | |
AVELARDEV | 0:010b908e2187 | 189 | ach_i2c_data[0]=MAX30100_REG_FIFO_DATA; |
condato_mbed | 1:a9cc51956082 | 190 | if(i2c.write(I2C_WRITE_ADDR, ach_i2c_data, 1, true)!=0) |
AVELARDEV | 0:010b908e2187 | 191 | return false; |
condato_mbed | 1:a9cc51956082 | 192 | if(i2c.read(I2C_READ_ADDR, ach_i2c_data, 4, false)!=0) |
AVELARDEV | 0:010b908e2187 | 193 | return false; |
AVELARDEV | 0:010b908e2187 | 194 | |
AVELARDEV | 0:010b908e2187 | 195 | // Warning: the values are always left-aligned |
AVELARDEV | 0:010b908e2187 | 196 | rawIRValue = (ach_i2c_data[0] << 8) | ach_i2c_data[1]; |
AVELARDEV | 0:010b908e2187 | 197 | rawRedValue = (ach_i2c_data[2] << 8) | ach_i2c_data[3]; |
AVELARDEV | 0:010b908e2187 | 198 | |
AVELARDEV | 0:010b908e2187 | 199 | return true; |
AVELARDEV | 0:010b908e2187 | 200 | } |