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