![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
ADXL345 test on L476
adxl345.cpp
- Committer:
- tifo
- Date:
- 2017-11-30
- Revision:
- 0:a0f7c6807a3a
File content as of revision 0:a0f7c6807a3a:
#include "adxl345.h" I2C i2c(PB_9, PB_8); #define ADXL345_DEVICE (0xA6) // Device Address for ADXL345 #define ADXL345_TO_READ (6) // Number of chars Read - Two chars Per Axis ADXL345::ADXL345() { status = ADXL345_OK; error_code = ADXL345_NO_ERROR; gains[0] = 0.00376390; // Original gain 0.00376390 gains[1] = 0.00376009; // Original gain 0.00376009 gains[2] = 0.00349265; // Original gain 0.00349265 } void ADXL345::powerOn() { //ADXL345 TURN ON writeToI2C(ADXL345_POWER_CTL, 0); // Wakeup writeToI2C(ADXL345_POWER_CTL, 16); // Auto_Sleep writeToI2C(ADXL345_POWER_CTL, 8); // Measure } /*********************** READING ACCELERATION ***********************/ /* Reads Acceleration into Three Variables: x, y and z */ void ADXL345::readAccel(int *xyz){ readAccel(xyz, xyz + 1, xyz + 2); } void ADXL345::readAccel(int *x, int *y, int *z) { readFromI2C(ADXL345_DATAX0, ADXL345_TO_READ, _buff); // Read Accel Data from ADXL345 // Each Axis @ All g Ranges: 10 Bit Resolution (2 chars) *x = (int16_t)((((int)_buff[1]) << 8) | _buff[0]); *y = (int16_t)((((int)_buff[3]) << 8) | _buff[2]); *z = (int16_t)((((int)_buff[5]) << 8) | _buff[4]); } void ADXL345::get_Gxyz(double *xyz){ int i; int xyz_int[3]; readAccel(xyz_int); for(i=0; i<3; i++){ xyz[i] = xyz_int[i] * gains[i]; } } /*************************** WRITE TO I2C ***************************/ /* Start; Send Register Address; Send Value To Write; End */ void ADXL345::writeToI2C(char _address, char _val) { char data_write[2]; data_write[0] = _address; data_write[1] = _val; i2c.write(ADXL345_DEVICE, data_write, 2, 0); } /*************************** READ FROM I2C **************************/ /* Start; Send Address To Read; End */ void ADXL345::readFromI2C(char address, int num, char _buff[]) { char data_write[1]; data_write[0] = address; i2c.write(ADXL345_DEVICE, data_write, 1, 1); i2c.read(ADXL345_DEVICE, _buff, num, 0); } void ADXL345::setRangeSetting(int val) { char _s; char _b; switch (val) { case 2: _s = 00000000; break; case 4: _s = 00000001; break; case 8: _s = 00000010; break; case 16: _s = 00000011; break; default: _s = 00000000; } readFromI2C(ADXL345_DATA_FORMAT, 1, &_b); _s |= (_b & 11101100); writeToI2C(ADXL345_DATA_FORMAT, _s); } /*************************** SELF_TEST BIT **************************/ /* ~ GET & SET */ bool ADXL345::getSelfTestBit() { return getRegisterBit(ADXL345_DATA_FORMAT, 7); } // If Set (1) Self-Test Applied. Electrostatic Force exerted on the sensor // causing a shift in the output data. // If Set (0) Self-Test Disabled. void ADXL345::setSelfTestBit(bool selfTestBit) { setRegisterBit(ADXL345_DATA_FORMAT, 7, selfTestBit); } /*********************** INT_INVERT BIT STATE ***********************/ /* ~ GET & SET */ bool ADXL345::getInterruptLevelBit() { return getRegisterBit(ADXL345_DATA_FORMAT, 5); } // If Set (0) Sets the Interrupts to Active HIGH // If Set (1) Sets the Interrupts to Active LOW void ADXL345::setInterruptLevelBit(bool interruptLevelBit) { setRegisterBit(ADXL345_DATA_FORMAT, 5, interruptLevelBit); } /************************* FULL_RES BIT STATE ***********************/ /* ~ GET & SET */ bool ADXL345::getFullResBit() { return getRegisterBit(ADXL345_DATA_FORMAT, 3); } // If Set (1) Device is in Full Resolution Mode: Output Resolution Increase with G Range // Set by the Range Bits to Maintain a 4mg/LSB Scale Factor // If Set (0) Device is in 10-bit Mode: Range Bits Determine Maximum G Range // And Scale Factor void ADXL345::setFullResBit(bool fullResBit) { setRegisterBit(ADXL345_DATA_FORMAT, 3, fullResBit); } /*************************** JUSTIFY BIT STATE **************************/ /* ~ GET & SET */ bool ADXL345::getJustifyBit() { return getRegisterBit(ADXL345_DATA_FORMAT, 2); } // If Set (1) Selects the Left Justified Mode // If Set (0) Selects Right Justified Mode with Sign Extension void ADXL345::setJustifyBit(bool justifyBit) { setRegisterBit(ADXL345_DATA_FORMAT, 2, justifyBit); } /*********************** THRESH_TAP char VALUE **********************/ /* ~ SET & GET */ // Should Set Between 0 and 255 // Scale Factor is 62.5 mg/LSB // A Value of 0 May Result in Undesirable Behavior void ADXL345::setTapThreshold(int tapThreshold) { if(tapThreshold < 0) { tapThreshold = 0; } if(tapThreshold > 255) { tapThreshold = 255; } char _b = char (tapThreshold); writeToI2C(ADXL345_THRESH_TAP, _b); } // Return Value Between 0 and 255 // Scale Factor is 62.5 mg/LSB int ADXL345::getTapThreshold() { char _b; readFromI2C(ADXL345_THRESH_TAP, 1, &_b); return int (_b); } /****************** GAIN FOR EACH AXIS IN Gs / COUNT *****************/ /* ~ SET & GET */ void ADXL345::setAxisGains(double *_gains){ int i; for(i = 0; i < 3; i++){ gains[i] = _gains[i]; } } void ADXL345::getAxisGains(double *_gains){ int i; for(i = 0; i < 3; i++){ _gains[i] = gains[i]; } } /********************* OFSX, OFSY and OFSZ charS ********************/ /* ~ SET & GET */ // OFSX, OFSY and OFSZ: User Offset Adjustments in Twos Complement Format // Scale Factor of 15.6mg/LSB void ADXL345::setAxisOffset(int x, int y, int z) { writeToI2C(ADXL345_OFSX, char (x)); writeToI2C(ADXL345_OFSY, char (y)); writeToI2C(ADXL345_OFSZ, char (z)); } void ADXL345::getAxisOffset(int* x, int* y, int*z) { char _b; readFromI2C(ADXL345_OFSX, 1, &_b); *x = int (_b); readFromI2C(ADXL345_OFSY, 1, &_b); *y = int (_b); readFromI2C(ADXL345_OFSZ, 1, &_b); *z = int (_b); } /****************************** DUR char ****************************/ /* ~ SET & GET */ // DUR char: Contains an Unsigned Time Value Representing the Max Time // that an Event must be Above the THRESH_TAP Threshold to qualify // as a Tap Event // The scale factor is 625µs/LSB // Value of 0 Disables the Tap/Double Tap Funcitons. Max value is 255. void ADXL345::setTapDuration(int tapDuration) { if(tapDuration < 0) { tapDuration = 0; } if(tapDuration > 255) { tapDuration = 255; } char _b = char (tapDuration); writeToI2C(ADXL345_DUR, _b); } int ADXL345::getTapDuration() { char _b; readFromI2C(ADXL345_DUR, 1, &_b); return int (_b); } /************************** LATENT REGISTER *************************/ /* ~ SET & GET */ // Contains Unsigned Time Value Representing the Wait Time from the Detection // of a Tap Event to the Start of the Time Window (defined by the Window // Register) during which a possible Second Tap Even can be Detected. // Scale Factor is 1.25ms/LSB. // A Value of 0 Disables the Double Tap Function. // It Accepts a Maximum Value of 255. void ADXL345::setDoubleTapLatency(int doubleTapLatency) { char _b = char (doubleTapLatency); writeToI2C(ADXL345_LATENT, _b); } int ADXL345::getDoubleTapLatency() { char _b; readFromI2C(ADXL345_LATENT, 1, &_b); return int (_b); } /************************** WINDOW REGISTER *************************/ /* ~ SET & GET */ // Contains an Unsigned Time Value Representing the Amount of Time // After the Expiration of the Latency Time (determined by Latent register) // During which a Second Valid Tape can Begin. // Scale Factor is 1.25ms/LSB. // Value of 0 Disables the Double Tap Function. // It Accepts a Maximum Value of 255. void ADXL345::setDoubleTapWindow(int doubleTapWindow) { if(doubleTapWindow < 0) { doubleTapWindow = 0; } if(doubleTapWindow > 255) { doubleTapWindow = 255; } char _b = char (doubleTapWindow); writeToI2C(ADXL345_WINDOW, _b); } int ADXL345::getDoubleTapWindow() { char _b; readFromI2C(ADXL345_WINDOW, 1, &_b); return int (_b); } /*********************** THRESH_ACT REGISTER ************************/ /* ~ SET & GET */ // Holds the Threshold Value for Detecting Activity. // Data Format is Unsigned, so the Magnitude of the Activity Event is Compared // with the Value is Compared with the Value in the THRESH_ACT Register. // The Scale Factor is 62.5mg/LSB. // Value of 0 may Result in Undesirable Behavior if the Activity Interrupt Enabled. // It Accepts a Maximum Value of 255. void ADXL345::setActivityThreshold(int activityThreshold) { if(activityThreshold < 0) { activityThreshold = 0; } if(activityThreshold > 255) { activityThreshold = 255; } char _b = char (activityThreshold); writeToI2C(ADXL345_THRESH_ACT, _b); } // Gets the THRESH_ACT char int ADXL345::getActivityThreshold() { char _b; readFromI2C(ADXL345_THRESH_ACT, 1, &_b); return int (_b); } /********************** THRESH_INACT REGISTER ***********************/ /* ~ SET & GET */ // Holds the Threshold Value for Detecting Inactivity. // The Data Format is Unsigned, so the Magnitude of the INactivity Event is // Compared with the value in the THRESH_INACT Register. // Scale Factor is 62.5mg/LSB. // Value of 0 May Result in Undesirable Behavior if the Inactivity Interrupt Enabled. // It Accepts a Maximum Value of 255. void ADXL345::setInactivityThreshold(int inactivityThreshold) { if(inactivityThreshold < 0) { inactivityThreshold = 0; } if(inactivityThreshold > 255) { inactivityThreshold = 255; } char _b = char (inactivityThreshold); writeToI2C(ADXL345_THRESH_INACT, _b); } int ADXL345::getInactivityThreshold() { char _b; readFromI2C(ADXL345_THRESH_INACT, 1, &_b); return int (_b); } /*********************** TIME_INACT RESIGER *************************/ /* ~ SET & GET */ // Contains an Unsigned Time Value Representing the Amount of Time that // Acceleration must be Less Than the Value in the THRESH_INACT Register // for Inactivity to be Declared. // Uses Filtered Output Data* unlike other Interrupt Functions // Scale Factor is 1sec/LSB. // Value Must Be Between 0 and 255. void ADXL345::setTimeInactivity(int timeInactivity) { if(timeInactivity < 0) { timeInactivity = 0; } if(timeInactivity > 255) { timeInactivity = 255; } char _b = char (timeInactivity); writeToI2C(ADXL345_TIME_INACT, _b); } int ADXL345::getTimeInactivity() { char _b; readFromI2C(ADXL345_TIME_INACT, 1, &_b); return int (_b); } /*********************** THRESH_FF Register *************************/ /* ~ SET & GET */ // Holds the Threshold Value, in Unsigned Format, for Free-Fall Detection // The Acceleration on all Axes is Compared with the Value in THRES_FF to // Determine if a Free-Fall Event Occurred. // Scale Factor is 62.5mg/LSB. // Value of 0 May Result in Undesirable Behavior if the Free-Fall interrupt Enabled. // Accepts a Maximum Value of 255. void ADXL345::setFreeFallThreshold(int freeFallThreshold) { if(freeFallThreshold < 0) { freeFallThreshold = 0; } if(freeFallThreshold > 255) { freeFallThreshold = 255; } char _b = char (freeFallThreshold); writeToI2C(ADXL345_THRESH_FF, _b); } int ADXL345::getFreeFallThreshold() { char _b; readFromI2C(ADXL345_THRESH_FF, 1, &_b); return int (_b); } /************************ TIME_FF Register **************************/ /* ~ SET & GET */ // Stores an Unsigned Time Value Representing the Minimum Time that the Value // of all Axes must be Less Than THRES_FF to Generate a Free-Fall Interrupt. // Scale Factor is 5ms/LSB. // Value of 0 May Result in Undesirable Behavior if the Free-Fall Interrupt Enabled. // Accepts a Maximum Value of 255. void ADXL345::setFreeFallDuration(int freeFallDuration) { if(freeFallDuration < 0) { freeFallDuration = 0; } if(freeFallDuration > 255) { freeFallDuration = 255; } char _b = char (freeFallDuration); writeToI2C(ADXL345_TIME_FF, _b); } int ADXL345::getFreeFallDuration() { char _b; readFromI2C(ADXL345_TIME_FF, 1, &_b); return int (_b); } /************************** ACTIVITY BITS ***************************/ /* */ bool ADXL345::isActivityXEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 6); } bool ADXL345::isActivityYEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 5); } bool ADXL345::isActivityZEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 4); } bool ADXL345::isInactivityXEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 2); } bool ADXL345::isInactivityYEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 1); } bool ADXL345::isInactivityZEnabled() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 0); } void ADXL345::setActivityX(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 6, state); } void ADXL345::setActivityY(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 5, state); } void ADXL345::setActivityZ(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 4, state); } void ADXL345::setActivityXYZ(bool stateX, bool stateY, bool stateZ) { setActivityX(stateX); setActivityY(stateY); setActivityZ(stateZ); } void ADXL345::setInactivityX(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 2, state); } void ADXL345::setInactivityY(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 1, state); } void ADXL345::setInactivityZ(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 0, state); } void ADXL345::setInactivityXYZ(bool stateX, bool stateY, bool stateZ) { setInactivityX(stateX); setInactivityY(stateY); setInactivityZ(stateZ); } bool ADXL345::isActivityAc() { return getRegisterBit(ADXL345_ACT_INACT_CTL, 7); } bool ADXL345::isInactivityAc(){ return getRegisterBit(ADXL345_ACT_INACT_CTL, 3); } void ADXL345::setActivityAc(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 7, state); } void ADXL345::setInactivityAc(bool state) { setRegisterBit(ADXL345_ACT_INACT_CTL, 3, state); } /************************* SUPPRESS BITS ****************************/ /* */ bool ADXL345::getSuppressBit(){ return getRegisterBit(ADXL345_TAP_AXES, 3); } void ADXL345::setSuppressBit(bool state) { setRegisterBit(ADXL345_TAP_AXES, 3, state); } /**************************** TAP BITS ******************************/ /* */ bool ADXL345::isTapDetectionOnX(){ return getRegisterBit(ADXL345_TAP_AXES, 2); } void ADXL345::setTapDetectionOnX(bool state) { setRegisterBit(ADXL345_TAP_AXES, 2, state); } bool ADXL345::isTapDetectionOnY(){ return getRegisterBit(ADXL345_TAP_AXES, 1); } void ADXL345::setTapDetectionOnY(bool state) { setRegisterBit(ADXL345_TAP_AXES, 1, state); } bool ADXL345::isTapDetectionOnZ(){ return getRegisterBit(ADXL345_TAP_AXES, 0); } void ADXL345::setTapDetectionOnZ(bool state) { setRegisterBit(ADXL345_TAP_AXES, 0, state); } void ADXL345::setTapDetectionOnXYZ(bool stateX, bool stateY, bool stateZ) { setTapDetectionOnX(stateX); setTapDetectionOnY(stateY); setTapDetectionOnZ(stateZ); } bool ADXL345::isActivitySourceOnX(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 6); } bool ADXL345::isActivitySourceOnY(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 5); } bool ADXL345::isActivitySourceOnZ(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 4); } bool ADXL345::isTapSourceOnX(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 2); } bool ADXL345::isTapSourceOnY(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 1); } bool ADXL345::isTapSourceOnZ(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 0); } /*************************** ASLEEP BIT *****************************/ /* */ bool ADXL345::isAsleep(){ return getRegisterBit(ADXL345_ACT_TAP_STATUS, 3); } /************************** LOW POWER BIT ***************************/ /* */ bool ADXL345::isLowPower(){ return getRegisterBit(ADXL345_BW_RATE, 4); } void ADXL345::setLowPower(bool state) { setRegisterBit(ADXL345_BW_RATE, 4, state); } /************************* TRIGGER CHECK ***************************/ /* */ // Check if Action was Triggered in Interrupts // Example triggered(interrupts, ADXL345_SINGLE_TAP); bool ADXL345::triggered(char interrupts, int mask){ return ((interrupts >> mask) & 1); } /* ADXL345_DATA_READY ADXL345_SINGLE_TAP ADXL345_DOUBLE_TAP ADXL345_ACTIVITY ADXL345_INACTIVITY ADXL345_FREE_FALL ADXL345_WATERMARK ADXL345_OVERRUNY */ char ADXL345::getInterruptSource() { char _b; readFromI2C(ADXL345_INT_SOURCE, 1, &_b); return _b; } bool ADXL345::getInterruptSource(char interruptBit) { return getRegisterBit(ADXL345_INT_SOURCE,interruptBit); } bool ADXL345::getInterruptMapping(char interruptBit) { return getRegisterBit(ADXL345_INT_MAP,interruptBit); } /*********************** INTERRUPT MAPPING **************************/ /* Set the Mapping of an Interrupt to pin1 or pin2 */ // eg: setInterruptMapping(ADXL345_INT_DOUBLE_TAP_BIT,ADXL345_INT2_PIN); void ADXL345::setInterruptMapping(char interruptBit, bool interruptPin) { setRegisterBit(ADXL345_INT_MAP, interruptBit, interruptPin); } void ADXL345::setImportantInterruptMapping(int single_tap, int double_tap, int free_fall, int activity, int inactivity) { if(single_tap == 1) { setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN );} else if(single_tap == 2) { setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT2_PIN );} if(double_tap == 1) { setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN );} else if(double_tap == 2) { setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT2_PIN );} if(free_fall == 1) { setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN );} else if(free_fall == 2) { setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT2_PIN );} if(activity == 1) { setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN );} else if(activity == 2) { setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT2_PIN );} if(inactivity == 1) { setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN );} else if(inactivity == 2) { setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT2_PIN );} } bool ADXL345::isInterruptEnabled(char interruptBit) { return getRegisterBit(ADXL345_INT_ENABLE,interruptBit); } void ADXL345::setInterrupt(char interruptBit, bool state) { setRegisterBit(ADXL345_INT_ENABLE, interruptBit, state); } void ADXL345::singleTapINT(bool status) { if(status) { setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); } else { setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 0); } } void ADXL345::doubleTapINT(bool status) { if(status) { setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); } else { setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 0); } } void ADXL345::FreeFallINT(bool status) { if(status) { setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); } else { setInterrupt( ADXL345_INT_FREE_FALL_BIT, 0); } } void ADXL345::ActivityINT(bool status) { if(status) { setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); } else { setInterrupt( ADXL345_INT_ACTIVITY_BIT, 0); } } void ADXL345::InactivityINT(bool status) { if(status) { setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); } else { setInterrupt( ADXL345_INT_INACTIVITY_BIT, 0); } } void ADXL345::setRegisterBit(char regAdress, int bitPos, bool state) { char _b; readFromI2C(regAdress, 1, &_b); if (state) { _b |= (1 << bitPos); // Forces nth Bit of _b to 1. Other Bits Unchanged. } else { _b &= ~(1 << bitPos); // Forces nth Bit of _b to 0. Other Bits Unchanged. } writeToI2C(regAdress, _b); } bool ADXL345::getRegisterBit(char regAdress, int bitPos) { char _b; readFromI2C(regAdress, 1, &_b); return ((_b >> bitPos) & 1); }