/* * H3LIS331DL.cpp * A library for 3-Axis Digital Accelerometer(±400g) * * Copyright (c) 2014 seeed technology inc. * Website : www.seeed.cc * Author : lawliet zou * Create Time: April 2014 * Change Log : * * The MIT License (MIT) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "H3LIS331DL.h" #include void H3LIS331DL::init(H3LIS331DL_ODR_t odr,H3LIS331DL_Mode_t mode,H3LIS331DL_Fullscale_t fullScale){ Wire.begin(); //set output data rate setODR(odr); //set PowerMode setMode( mode); //set Fullscale setFullScale( fullScale); //set axis Enable setAxis( H3LIS331DL_X_ENABLE | H3LIS331DL_Y_ENABLE | H3LIS331DL_Z_ENABLE); } void H3LIS331DL::importPara(int16_t val_x, int16_t val_y, int16_t val_z) { _adjVal[0] = val_x; _adjVal[1] = val_y; _adjVal[2] = val_z; } void H3LIS331DL::readXYZ(int16_t* x, int16_t* y, int16_t* z) { //get Acceleration Raw data AxesRaw_t data; status_t response = getAccAxesRaw(&data); if(MEMS_SUCCESS == response){ *x = (data.AXIS_X - _adjVal[0]); *y = (data.AXIS_Y - _adjVal[1]); *z = (data.AXIS_Z - _adjVal[2]); } } void H3LIS331DL::getAcceleration(double* xyz) { AxesRaw_t data; double gains = 0.003; getAccAxesRaw(&data); xyz[0] = (data.AXIS_X - _adjVal[0]) * gains; xyz[1] = (data.AXIS_Y - _adjVal[1]) * gains; xyz[2] = (data.AXIS_Z - _adjVal[2]) * gains; } /******************************************************************************* * Function Name : getWHO_AM_I * Description : Read identification code from H3LIS331DL::WHO_AM_I register * Input : char to be filled with the Device identification Value * Output : None * Return : Status [value of FSS] *******************************************************************************/ status_t H3LIS331DL::getWHO_AM_I(byte* val){ if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_WHO_AM_I, val) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : setODR * Description : Sets H3LIS331DL Accelerometer Output Data Rate * Input : Output Data Rate * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::setODR(H3LIS331DL_ODR_t dr){ byte value; if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, &value) ) return MEMS_ERROR; value &= 0xE7; value |= dr< 127) return MEMS_ERROR; if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_THS, ths) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : setInt1Duration * Description : Sets Interrupt 1 Duration * Input : Duration = [0,127] * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::setInt1Duration(byte id) { if (id > 127) return MEMS_ERROR; if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_DURATION, id) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : setInt2Threshold * Description : Sets Interrupt 2 Threshold * Input : Threshold = [0,127] * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::setInt2Threshold(byte ths) { if (ths > 127) return MEMS_ERROR; if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_THS, ths) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : setInt2Duration * Description : Sets Interrupt 2 Duration * Input : Duration = [0,127] * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::setInt2Duration(byte id) { if (id > 127) return MEMS_ERROR; if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_DURATION, id) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : getStatusReg * Description : Read the status register * Input : char to empty by Status Reg Value * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getStatusReg(byte* val) { if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_STATUS_REG, val) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : getStatusBIT * Description : Read the status register BIT * Input : H3LIS331DL_STATUS_REG_ZYXOR, H3LIS331DL_STATUS_REG_ZOR, H3LIS331DL_STATUS_REG_YOR, H3LIS331DL_STATUS_REG_XOR, H3LIS331DL_STATUS_REG_ZYXDA, H3LIS331DL_STATUS_REG_ZDA, H3LIS331DL_STATUS_REG_YDA, H3LIS331DL_STATUS_REG_XDA, H3LIS331DL_DATAREADY_BIT * Output : status register BIT * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getStatusBit(byte statusBIT, byte *val) { byte value; if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_STATUS_REG, &value) ) return MEMS_ERROR; switch (statusBIT){ case H3LIS331DL_STATUS_REG_ZYXOR: if(value &= H3LIS331DL_STATUS_REG_ZYXOR){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_ZOR: if(value &= H3LIS331DL_STATUS_REG_ZOR){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_YOR: if(value &= H3LIS331DL_STATUS_REG_YOR){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_XOR: if(value &= H3LIS331DL_STATUS_REG_XOR){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_ZYXDA: if(value &= H3LIS331DL_STATUS_REG_ZYXDA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_ZDA: if(value &= H3LIS331DL_STATUS_REG_ZDA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_YDA: if(value &= H3LIS331DL_STATUS_REG_YDA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } case H3LIS331DL_STATUS_REG_XDA: if(value &= H3LIS331DL_STATUS_REG_XDA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } return MEMS_ERROR; } /******************************************************************************* * Function Name : getAccAxesRaw * Description : Read the Acceleration Values Output Registers * Input : buffer to empty by AccAxesRaw_t Typedef * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getAccAxesRaw(AxesRaw_t* buff) { byte valueL = 0,valueH = 0; readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_X_L, &valueL); readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_X_H, &valueH); buff->AXIS_X = (valueH<<8)|valueL; readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Y_L, &valueL); readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Y_H, &valueH); buff->AXIS_Y = (valueH<<8)|valueL; readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Z_L, &valueL); readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Z_H, &valueH); buff->AXIS_Z = (valueH<<8)|valueL; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : getInt1Src * Description : Reset Interrupt 1 Latching function * Input : buffer to empty by Int1 Source Value * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getInt1Src(byte* val) { if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, val) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : getInt2Src * Description : Reset Interrupt 2 Latching function * Input : buffer to empty by Int2 Source Value * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getInt2Src(byte* val) { if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, val) ) return MEMS_ERROR; return MEMS_SUCCESS; } /******************************************************************************* * Function Name : getInt1SrcBit * Description : Reset Interrupt 1 Latching function * Input : H3LIS331DL_INT1_SRC_IA, H3LIS331DL_INT1_SRC_ZH, H3LIS331DL_INT1_SRC_ZL ..... * Output : None * Return : Status of BIT [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getInt1SrcBit(byte statusBIT, byte *val) { byte value; if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, &value) ) return MEMS_ERROR; if(statusBIT == H3LIS331DL_INT_SRC_IA){ if(value &= H3LIS331DL_INT_SRC_IA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_ZH){ if(value &= H3LIS331DL_INT_SRC_ZH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_ZL){ if(value &= H3LIS331DL_INT_SRC_ZL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_YH){ if(value &= H3LIS331DL_INT_SRC_YH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_YL){ if(value &= H3LIS331DL_INT_SRC_YL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_XH){ if(value &= H3LIS331DL_INT_SRC_XH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_XL){ if(value &= H3LIS331DL_INT_SRC_XL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } return MEMS_ERROR; } /******************************************************************************* * Function Name : getInt2SrcBit * Description : Reset Interrupt 2 Latching function * Input : H3LIS331DL_INT_SRC_IA, H3LIS331DL_INT_SRC_ZH, H3LIS331DL_INT_SRC_ZL ..... * Output : None * Return : Status of BIT [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ status_t H3LIS331DL::getInt2SrcBit(byte statusBIT, byte *val) { byte value; if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, &value) ) return MEMS_ERROR; if(statusBIT == H3LIS331DL_INT_SRC_IA){ if(value &= H3LIS331DL_INT_SRC_IA){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_ZH){ if(value &= H3LIS331DL_INT_SRC_ZH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_ZL){ if(value &= H3LIS331DL_INT_SRC_ZL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_YH){ if(value &= H3LIS331DL_INT_SRC_YH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_YL){ if(value &= H3LIS331DL_INT_SRC_YL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_XH){ if(value &= H3LIS331DL_INT_SRC_XH){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } if(statusBIT == H3LIS331DL_INT_SRC_XL){ if(value &= H3LIS331DL_INT_SRC_XL){ *val = MEMS_SET; return MEMS_SUCCESS; } else{ *val = MEMS_RESET; return MEMS_SUCCESS; } } return MEMS_ERROR; } /******************************************************************************* * Function Name : readReg * Description : Generic Reading function. It must be full filled with either * : I2C or SPI reading functions * Input : Register Address * Output : Data Read * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ uint8_t H3LIS331DL::readReg(byte deviceAddr, byte Reg, byte* Data) { //To be completed with either I2c or SPI reading function // i.e. *Data = SPI_Mems_Read_Reg( Reg ); // i.e. if(!I2C_BufferRead(Data, deviceAddr, Reg, 1)) // return MEMS_ERROR; // else // return MEMS_SUCCESS; // Reads num bytes starting from address register on device in to _buff array byte num = 1; Wire.beginTransmission(deviceAddr); // start transmission to device Wire.write(Reg); // sends address to read from Wire.endTransmission(); // end transmission Wire.beginTransmission(deviceAddr); // start transmission to device Wire.requestFrom(deviceAddr,num); // request 6 bytes from device if(Wire.available()){ *Data = Wire.read(); // receive a byte Wire.endTransmission(); // end transmission return MEMS_SUCCESS; }else{ Wire.endTransmission(); return MEMS_ERROR; } } /******************************************************************************* * Function Name : writeReg * Description : Generic Writing function. It must be full filled with either * : I2C or SPI writing function * Input : Register Address, Data to be written * Output : None * Return : Status [MEMS_ERROR, MEMS_SUCCESS] *******************************************************************************/ uint8_t H3LIS331DL::writeReg(byte deviceAddress, byte WriteAddr, byte Data) { //To be completed with either I2c or SPI writing function // i.e. SPI_Mems_Write_Reg(Reg, Data); // i.e. I2C_ByteWrite(&Data, deviceAddress, WriteAddr); // return MEMS_SUCCESS; // Writes val to address register on device Wire.beginTransmission(deviceAddress); // start transmission to device Wire.write(WriteAddr); // send register address Wire.write(Data); // send value to write Wire.endTransmission(); // end transmission return MEMS_SUCCESS; }