m
Fork of MAX30100 by
MAX30100.cpp@0:010b908e2187, 2016-11-25 (annotated)
- Committer:
- AVELARDEV
- Date:
- Fri Nov 25 00:52:54 2016 +0000
- Revision:
- 0:010b908e2187
- Child:
- 1:e3b9aff8f221
max30100 example
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 | |
AVELARDEV | 0:010b908e2187 | 18 | I2C Wire(I2C_SDA , I2C_SCL ); |
AVELARDEV | 0:010b908e2187 | 19 | |
AVELARDEV | 0:010b908e2187 | 20 | MAX30100::MAX30100() |
AVELARDEV | 0:010b908e2187 | 21 | { |
AVELARDEV | 0:010b908e2187 | 22 | |
AVELARDEV | 0:010b908e2187 | 23 | } |
AVELARDEV | 0:010b908e2187 | 24 | |
AVELARDEV | 0:010b908e2187 | 25 | bool MAX30100::begin() |
AVELARDEV | 0:010b908e2187 | 26 | { |
AVELARDEV | 0:010b908e2187 | 27 | // Wire.begin(); |
AVELARDEV | 0:010b908e2187 | 28 | // Wire.setClock(I2C_BUS_SPEED); |
AVELARDEV | 0:010b908e2187 | 29 | |
AVELARDEV | 0:010b908e2187 | 30 | Wire.frequency(I2C_BUS_SPEED); |
AVELARDEV | 0:010b908e2187 | 31 | |
AVELARDEV | 0:010b908e2187 | 32 | if(!setMode(DEFAULT_MODE)) |
AVELARDEV | 0:010b908e2187 | 33 | return false; |
AVELARDEV | 0:010b908e2187 | 34 | if(!setLedsPulseWidth(DEFAULT_PULSE_WIDTH)) |
AVELARDEV | 0:010b908e2187 | 35 | return false; |
AVELARDEV | 0:010b908e2187 | 36 | if(!setSamplingRate(DEFAULT_SAMPLING_RATE)) |
AVELARDEV | 0:010b908e2187 | 37 | return false; |
AVELARDEV | 0:010b908e2187 | 38 | if(!setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT)) |
AVELARDEV | 0:010b908e2187 | 39 | return false; |
AVELARDEV | 0:010b908e2187 | 40 | if(!setHighresModeEnabled(true)) |
AVELARDEV | 0:010b908e2187 | 41 | return false; |
AVELARDEV | 0:010b908e2187 | 42 | |
AVELARDEV | 0:010b908e2187 | 43 | return true; |
AVELARDEV | 0:010b908e2187 | 44 | } |
AVELARDEV | 0:010b908e2187 | 45 | |
AVELARDEV | 0:010b908e2187 | 46 | bool MAX30100::setMode(Mode mode) |
AVELARDEV | 0:010b908e2187 | 47 | { |
AVELARDEV | 0:010b908e2187 | 48 | if(!writeRegister(MAX30100_REG_MODE_CONFIGURATION, mode)) |
AVELARDEV | 0:010b908e2187 | 49 | return false; |
AVELARDEV | 0:010b908e2187 | 50 | else |
AVELARDEV | 0:010b908e2187 | 51 | return true; |
AVELARDEV | 0:010b908e2187 | 52 | } |
AVELARDEV | 0:010b908e2187 | 53 | |
AVELARDEV | 0:010b908e2187 | 54 | bool MAX30100::setLedsPulseWidth(LEDPulseWidth ledPulseWidth) |
AVELARDEV | 0:010b908e2187 | 55 | { |
AVELARDEV | 0:010b908e2187 | 56 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 57 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 58 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xfc) | ledPulseWidth)) |
AVELARDEV | 0:010b908e2187 | 59 | return false; |
AVELARDEV | 0:010b908e2187 | 60 | else |
AVELARDEV | 0:010b908e2187 | 61 | return true; |
AVELARDEV | 0:010b908e2187 | 62 | else |
AVELARDEV | 0:010b908e2187 | 63 | return false; |
AVELARDEV | 0:010b908e2187 | 64 | } |
AVELARDEV | 0:010b908e2187 | 65 | |
AVELARDEV | 0:010b908e2187 | 66 | bool MAX30100::setSamplingRate(SamplingRate samplingRate) |
AVELARDEV | 0:010b908e2187 | 67 | { |
AVELARDEV | 0:010b908e2187 | 68 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 69 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 70 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xe3) | (samplingRate << 2))) |
AVELARDEV | 0:010b908e2187 | 71 | return false; |
AVELARDEV | 0:010b908e2187 | 72 | else |
AVELARDEV | 0:010b908e2187 | 73 | return true; |
AVELARDEV | 0:010b908e2187 | 74 | else |
AVELARDEV | 0:010b908e2187 | 75 | return false; |
AVELARDEV | 0:010b908e2187 | 76 | } |
AVELARDEV | 0:010b908e2187 | 77 | |
AVELARDEV | 0:010b908e2187 | 78 | bool MAX30100::setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent) |
AVELARDEV | 0:010b908e2187 | 79 | { |
AVELARDEV | 0:010b908e2187 | 80 | if(!writeRegister(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent)) |
AVELARDEV | 0:010b908e2187 | 81 | return false; |
AVELARDEV | 0:010b908e2187 | 82 | else |
AVELARDEV | 0:010b908e2187 | 83 | return true; |
AVELARDEV | 0:010b908e2187 | 84 | } |
AVELARDEV | 0:010b908e2187 | 85 | |
AVELARDEV | 0:010b908e2187 | 86 | bool MAX30100::setHighresModeEnabled(bool enabled) |
AVELARDEV | 0:010b908e2187 | 87 | { |
AVELARDEV | 0:010b908e2187 | 88 | uint8_t previous; |
AVELARDEV | 0:010b908e2187 | 89 | if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous)) |
AVELARDEV | 0:010b908e2187 | 90 | if (enabled) { |
AVELARDEV | 0:010b908e2187 | 91 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous | MAX30100_SPC_SPO2_HI_RES_EN)) |
AVELARDEV | 0:010b908e2187 | 92 | return false; |
AVELARDEV | 0:010b908e2187 | 93 | else |
AVELARDEV | 0:010b908e2187 | 94 | return true; |
AVELARDEV | 0:010b908e2187 | 95 | } else { |
AVELARDEV | 0:010b908e2187 | 96 | if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous & ~MAX30100_SPC_SPO2_HI_RES_EN)) |
AVELARDEV | 0:010b908e2187 | 97 | return false; |
AVELARDEV | 0:010b908e2187 | 98 | else |
AVELARDEV | 0:010b908e2187 | 99 | return true; |
AVELARDEV | 0:010b908e2187 | 100 | } |
AVELARDEV | 0:010b908e2187 | 101 | else |
AVELARDEV | 0:010b908e2187 | 102 | return false; |
AVELARDEV | 0:010b908e2187 | 103 | } |
AVELARDEV | 0:010b908e2187 | 104 | |
AVELARDEV | 0:010b908e2187 | 105 | |
AVELARDEV | 0:010b908e2187 | 106 | bool MAX30100::update() |
AVELARDEV | 0:010b908e2187 | 107 | { |
AVELARDEV | 0:010b908e2187 | 108 | if(!readFifoData()) |
AVELARDEV | 0:010b908e2187 | 109 | return false; |
AVELARDEV | 0:010b908e2187 | 110 | else |
AVELARDEV | 0:010b908e2187 | 111 | return true; |
AVELARDEV | 0:010b908e2187 | 112 | } |
AVELARDEV | 0:010b908e2187 | 113 | |
AVELARDEV | 0:010b908e2187 | 114 | |
AVELARDEV | 0:010b908e2187 | 115 | /* |
AVELARDEV | 0:010b908e2187 | 116 | uint8_t MAX30100::readRegister(uint8_t address) |
AVELARDEV | 0:010b908e2187 | 117 | { |
AVELARDEV | 0:010b908e2187 | 118 | Wire.beginTransmission(MAX30100_I2C_ADDRESS); |
AVELARDEV | 0:010b908e2187 | 119 | Wire.write(address); |
AVELARDEV | 0:010b908e2187 | 120 | Wire.endTransmission(false); |
AVELARDEV | 0:010b908e2187 | 121 | Wire.requestFrom(MAX30100_I2C_ADDRESS, 1); |
AVELARDEV | 0:010b908e2187 | 122 | |
AVELARDEV | 0:010b908e2187 | 123 | return Wire.read(); |
AVELARDEV | 0:010b908e2187 | 124 | } |
AVELARDEV | 0:010b908e2187 | 125 | */ |
AVELARDEV | 0:010b908e2187 | 126 | |
AVELARDEV | 0:010b908e2187 | 127 | bool MAX30100::readRegister(uint8_t uch_addr, uint8_t *puch_data) |
AVELARDEV | 0:010b908e2187 | 128 | /** |
AVELARDEV | 0:010b908e2187 | 129 | * \brief Read a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 130 | * \par Details |
AVELARDEV | 0:010b908e2187 | 131 | * This function reads a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 132 | * |
AVELARDEV | 0:010b908e2187 | 133 | * \param[in] uch_addr - register address |
AVELARDEV | 0:010b908e2187 | 134 | * \param[out] puch_data - pointer that stores the register data |
AVELARDEV | 0:010b908e2187 | 135 | * |
AVELARDEV | 0:010b908e2187 | 136 | * \retval true on success |
AVELARDEV | 0:010b908e2187 | 137 | */ |
AVELARDEV | 0:010b908e2187 | 138 | { |
AVELARDEV | 0:010b908e2187 | 139 | char ch_i2c_data; |
AVELARDEV | 0:010b908e2187 | 140 | ch_i2c_data=uch_addr; |
AVELARDEV | 0:010b908e2187 | 141 | if(Wire.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0) |
AVELARDEV | 0:010b908e2187 | 142 | return false; |
AVELARDEV | 0:010b908e2187 | 143 | if(Wire.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0) |
AVELARDEV | 0:010b908e2187 | 144 | { |
AVELARDEV | 0:010b908e2187 | 145 | *puch_data=(uint8_t) ch_i2c_data; |
AVELARDEV | 0:010b908e2187 | 146 | return true; |
AVELARDEV | 0:010b908e2187 | 147 | } |
AVELARDEV | 0:010b908e2187 | 148 | else |
AVELARDEV | 0:010b908e2187 | 149 | return false; |
AVELARDEV | 0:010b908e2187 | 150 | } |
AVELARDEV | 0:010b908e2187 | 151 | |
AVELARDEV | 0:010b908e2187 | 152 | /* |
AVELARDEV | 0:010b908e2187 | 153 | void MAX30100::writeRegister(uint8_t address, uint8_t data) |
AVELARDEV | 0:010b908e2187 | 154 | { |
AVELARDEV | 0:010b908e2187 | 155 | Wire.beginTransmission(MAX30100_I2C_ADDRESS); |
AVELARDEV | 0:010b908e2187 | 156 | Wire.write(address); |
AVELARDEV | 0:010b908e2187 | 157 | Wire.write(data); |
AVELARDEV | 0:010b908e2187 | 158 | Wire.endTransmission(); |
AVELARDEV | 0:010b908e2187 | 159 | } |
AVELARDEV | 0:010b908e2187 | 160 | */ |
AVELARDEV | 0:010b908e2187 | 161 | |
AVELARDEV | 0:010b908e2187 | 162 | bool MAX30100::writeRegister(uint8_t uch_addr, uint8_t uch_data) |
AVELARDEV | 0:010b908e2187 | 163 | /** |
AVELARDEV | 0:010b908e2187 | 164 | * \brief Write a value to a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 165 | * \par Details |
AVELARDEV | 0:010b908e2187 | 166 | * This function writes a value to a MAX30102 register |
AVELARDEV | 0:010b908e2187 | 167 | * |
AVELARDEV | 0:010b908e2187 | 168 | * \param[in] uch_addr - register address |
AVELARDEV | 0:010b908e2187 | 169 | * \param[in] uch_data - register data |
AVELARDEV | 0:010b908e2187 | 170 | * |
AVELARDEV | 0:010b908e2187 | 171 | * \retval true on success |
AVELARDEV | 0:010b908e2187 | 172 | */ |
AVELARDEV | 0:010b908e2187 | 173 | { |
AVELARDEV | 0:010b908e2187 | 174 | char ach_i2c_data[2]; |
AVELARDEV | 0:010b908e2187 | 175 | ach_i2c_data[0]=uch_addr; |
AVELARDEV | 0:010b908e2187 | 176 | ach_i2c_data[1]=uch_data; |
AVELARDEV | 0:010b908e2187 | 177 | |
AVELARDEV | 0:010b908e2187 | 178 | if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 2, false)==0) |
AVELARDEV | 0:010b908e2187 | 179 | return true; |
AVELARDEV | 0:010b908e2187 | 180 | else |
AVELARDEV | 0:010b908e2187 | 181 | return false; |
AVELARDEV | 0:010b908e2187 | 182 | } |
AVELARDEV | 0:010b908e2187 | 183 | |
AVELARDEV | 0:010b908e2187 | 184 | bool MAX30100::readFifoData() |
AVELARDEV | 0:010b908e2187 | 185 | { |
AVELARDEV | 0:010b908e2187 | 186 | char ach_i2c_data[4]; |
AVELARDEV | 0:010b908e2187 | 187 | |
AVELARDEV | 0:010b908e2187 | 188 | ach_i2c_data[0]=MAX30100_REG_FIFO_DATA; |
AVELARDEV | 0:010b908e2187 | 189 | if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 1, true)!=0) |
AVELARDEV | 0:010b908e2187 | 190 | return false; |
AVELARDEV | 0:010b908e2187 | 191 | if(Wire.read(I2C_READ_ADDR, ach_i2c_data, 4, false)!=0) |
AVELARDEV | 0:010b908e2187 | 192 | return false; |
AVELARDEV | 0:010b908e2187 | 193 | |
AVELARDEV | 0:010b908e2187 | 194 | // Warning: the values are always left-aligned |
AVELARDEV | 0:010b908e2187 | 195 | rawIRValue = (ach_i2c_data[0] << 8) | ach_i2c_data[1]; |
AVELARDEV | 0:010b908e2187 | 196 | rawRedValue = (ach_i2c_data[2] << 8) | ach_i2c_data[3]; |
AVELARDEV | 0:010b908e2187 | 197 | |
AVELARDEV | 0:010b908e2187 | 198 | return true; |
AVELARDEV | 0:010b908e2187 | 199 | } |