Eduardo Avelar / MAX30100

Dependents:   MAX30100_oxullo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30100.cpp Source File

MAX30100.cpp

00001 /*
00002 Arduino-MAX30100 oximetry / heart rate integrated sensor library
00003 Copyright (C) 2016  OXullo Intersecans <x@brainrapers.org>
00004 This program is free software: you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation, either version 3 of the License, or
00007 (at your option) any later version.
00008 This program is distributed in the hope that it will be useful,
00009 but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 GNU General Public License for more details.
00012 You should have received a copy of the GNU General Public License
00013 along with this program.  If not, see <http://www.gnu.org/licenses/>.
00014 */
00015 
00016 #include "MAX30100.h"
00017 
00018 I2C Wire(I2C_SDA , I2C_SCL );
00019 
00020 MAX30100::MAX30100()
00021 {
00022 
00023 }
00024 
00025 bool MAX30100::begin()
00026 {
00027 //    Wire.begin();
00028 //    Wire.setClock(I2C_BUS_SPEED);
00029 
00030     Wire.frequency(I2C_BUS_SPEED);
00031 
00032     if(!setMode(DEFAULT_MODE))
00033         return false;
00034     if(!setLedsPulseWidth(DEFAULT_PULSE_WIDTH))
00035         return false;
00036     if(!setSamplingRate(DEFAULT_SAMPLING_RATE))
00037         return false;
00038     if(!setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT))
00039         return false;
00040     if(!setHighresModeEnabled(true))
00041         return false;
00042     
00043     return true;
00044 }
00045 
00046 bool MAX30100::setMode(Mode mode)
00047 {
00048     if(!writeRegister(MAX30100_REG_MODE_CONFIGURATION, mode))
00049         return false;
00050     else
00051         return true;
00052 }
00053 
00054 bool MAX30100::setLedsPulseWidth(LEDPulseWidth ledPulseWidth)
00055 {
00056     uint8_t previous;
00057     if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
00058         if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xfc) | ledPulseWidth))
00059             return false;
00060         else
00061             return true; 
00062     else
00063         return false;       
00064 }
00065 
00066 bool MAX30100::setSamplingRate(SamplingRate samplingRate)
00067 {
00068     uint8_t previous;
00069     if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
00070         if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xe3) | (samplingRate << 2)))
00071             return false;
00072         else
00073             return true; 
00074     else
00075         return false;  
00076 }
00077 
00078 bool MAX30100::setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent)
00079 {
00080     if(!writeRegister(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent))
00081         return false;
00082     else
00083         return true;     
00084 }
00085 
00086 bool MAX30100::setHighresModeEnabled(bool enabled)
00087 {
00088     uint8_t previous;
00089     if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
00090         if (enabled) {
00091             if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous | MAX30100_SPC_SPO2_HI_RES_EN))
00092                 return false;
00093             else
00094                 return true; 
00095         } else {
00096             if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous & ~MAX30100_SPC_SPO2_HI_RES_EN))
00097                 return false;
00098             else
00099                 return true;         
00100         }
00101     else
00102         return false;
00103 }
00104 
00105 
00106 bool MAX30100::update()
00107 {
00108     if(!readFifoData())
00109         return false;
00110     else
00111         return true;
00112 }
00113 
00114 
00115 /*
00116 uint8_t MAX30100::readRegister(uint8_t address)
00117 {
00118     Wire.beginTransmission(MAX30100_I2C_ADDRESS);
00119     Wire.write(address);
00120     Wire.endTransmission(false);
00121     Wire.requestFrom(MAX30100_I2C_ADDRESS, 1);
00122 
00123     return Wire.read();
00124 }
00125 */
00126 
00127 bool MAX30100::readRegister(uint8_t uch_addr, uint8_t *puch_data)
00128 /**
00129 * \brief        Read a MAX30102 register
00130 * \par          Details
00131 *               This function reads a MAX30102 register
00132 *
00133 * \param[in]    uch_addr    - register address
00134 * \param[out]   puch_data    - pointer that stores the register data
00135 *
00136 * \retval       true on success
00137 */
00138 {
00139   char ch_i2c_data;
00140   ch_i2c_data=uch_addr;
00141   if(Wire.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0)
00142     return false;
00143   if(Wire.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0)
00144   {
00145     *puch_data=(uint8_t) ch_i2c_data;
00146     return true;
00147   }
00148   else
00149     return false;   
00150 }
00151 
00152 /*
00153 void MAX30100::writeRegister(uint8_t address, uint8_t data)
00154 {
00155     Wire.beginTransmission(MAX30100_I2C_ADDRESS);
00156     Wire.write(address);
00157     Wire.write(data);
00158     Wire.endTransmission();
00159 }
00160 */
00161 
00162 bool MAX30100::writeRegister(uint8_t uch_addr, uint8_t uch_data)
00163 /**
00164 * \brief        Write a value to a MAX30102 register
00165 * \par          Details
00166 *               This function writes a value to a MAX30102 register
00167 *
00168 * \param[in]    uch_addr    - register address
00169 * \param[in]    uch_data    - register data
00170 *
00171 * \retval       true on success
00172 */
00173 {
00174   char ach_i2c_data[2];
00175   ach_i2c_data[0]=uch_addr;
00176   ach_i2c_data[1]=uch_data;
00177   
00178   if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 2, false)==0)
00179     return true;
00180   else
00181     return false;    
00182 }
00183 
00184 bool MAX30100::readFifoData()
00185 {
00186     char ach_i2c_data[4];
00187 
00188     ach_i2c_data[0]=MAX30100_REG_FIFO_DATA;
00189     if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 1, true)!=0)
00190         return false;
00191     if(Wire.read(I2C_READ_ADDR, ach_i2c_data, 4, false)!=0)
00192         return false;
00193 
00194     // Warning: the values are always left-aligned
00195     rawIRValue = (ach_i2c_data[0] << 8) | ach_i2c_data[1];
00196     rawRedValue = (ach_i2c_data[2] << 8) | ach_i2c_data[3];
00197     
00198     return true;
00199 }