203 lines
7.2 KiB
C++
203 lines
7.2 KiB
C++
|
// I2Cdev library collection - ADXL345 I2C device class
|
||
|
// Based on Analog Devices ADXL345 datasheet rev. C, 5/2011
|
||
|
// 7/31/2011 by Jeff Rowberg <jeff@rowberg.net>
|
||
|
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
|
||
|
//
|
||
|
// Changelog:
|
||
|
// 2011-07-31 - initial release
|
||
|
|
||
|
/* ============================================
|
||
|
I2Cdev device library code is placed under the MIT license
|
||
|
Copyright (c) 2011 Jeff Rowberg
|
||
|
|
||
|
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 "ADXL345.h"
|
||
|
#include "board.h"
|
||
|
|
||
|
/** Default constructor, uses default I2C address.
|
||
|
* @see ADXL345_DEFAULT_ADDRESS
|
||
|
*/
|
||
|
ADXL345::ADXL345() {
|
||
|
devAddr = ADXL345_DEFAULT_ADDRESS;
|
||
|
}
|
||
|
|
||
|
/** Specific address constructor.
|
||
|
* @param address I2C address
|
||
|
* @see ADXL345_DEFAULT_ADDRESS
|
||
|
* @see ADXL345_ADDRESS_ALT_LOW
|
||
|
* @see ADXL345_ADDRESS_ALT_HIGH
|
||
|
*/
|
||
|
ADXL345::ADXL345(unsigned char address) {
|
||
|
devAddr = address;
|
||
|
}
|
||
|
|
||
|
/** Power on and prepare for general usage.
|
||
|
* This will activate the accelerometer, so be sure to adjust the power settings
|
||
|
* after you call this method if you want it to enter standby mode, or another
|
||
|
* less demanding mode of operation.
|
||
|
*/
|
||
|
void ADXL345::initialize() {
|
||
|
Board::get()->i2c_write_byte(devAddr, ADXL345_RA_POWER_CTL, 0); // reset all power settings
|
||
|
setAutoSleepEnabled(true);
|
||
|
setMeasureEnabled(true);
|
||
|
}
|
||
|
|
||
|
/** Verify the I2C connection.
|
||
|
* Make sure the device is connected and responds as expected.
|
||
|
* @return True if connection is valid, false otherwise
|
||
|
*/
|
||
|
bool ADXL345::testConnection() {
|
||
|
return getDeviceID() == 0xE5;
|
||
|
}
|
||
|
|
||
|
// DEVID register
|
||
|
|
||
|
/** Get Device ID.
|
||
|
* The DEVID register holds a fixed device ID code of 0xE5 (345 octal).
|
||
|
* @return Device ID (should be 0xE5, 229 dec, 345 oct)
|
||
|
* @see ADXL345_RA_DEVID
|
||
|
*/
|
||
|
unsigned char ADXL345::getDeviceID() {
|
||
|
Board::get()->i2c_read_buf(devAddr, ADXL345_RA_DEVID, buffer, 1);
|
||
|
return buffer[0];
|
||
|
}
|
||
|
|
||
|
// BW_RATE register
|
||
|
|
||
|
/** Set low power enabled status.
|
||
|
* @see getLowPowerEnabled()
|
||
|
* @param enabled Low power enable setting
|
||
|
* @see ADXL345_RA_BW_RATE
|
||
|
* @see ADXL345_BW_LOWPOWER_BIT
|
||
|
*/
|
||
|
void ADXL345::setLowPowerEnabled(bool enabled) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_BW_RATE, ADXL345_BW_LOWPOWER_BIT, enabled);
|
||
|
}
|
||
|
|
||
|
/** Set measurement data rate.
|
||
|
* 0x7 = 12.5Hz
|
||
|
* 0x8 = 25Hz, increasing or decreasing by factors of 2, so:
|
||
|
* 0x9 = 50Hz
|
||
|
* 0xA = 100Hz
|
||
|
* @param rate New data rate (0x0 - 0xF)
|
||
|
* @see ADXL345_RATE_100
|
||
|
* @see ADXL345_RA_BW_RATE
|
||
|
* @see ADXL345_BW_RATE_BIT
|
||
|
* @see ADXL345_BW_RATE_LENGTH
|
||
|
*/
|
||
|
void ADXL345::setRate(unsigned char rate) {
|
||
|
Board::get()->i2c_write_bits(devAddr, ADXL345_RA_BW_RATE, ADXL345_BW_RATE_BIT, ADXL345_BW_RATE_LENGTH, rate);
|
||
|
}
|
||
|
|
||
|
// POWER_CTL register
|
||
|
/** Set auto-sleep enabled status.
|
||
|
* @param enabled New auto-sleep status
|
||
|
* @see getAutoSleepEnabled()
|
||
|
* @see ADXL345_RA_POWER_CTL
|
||
|
* @see ADXL345_PCTL_AUTOSLEEP_BIT
|
||
|
*/
|
||
|
void ADXL345::setAutoSleepEnabled(bool enabled) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_POWER_CTL, ADXL345_PCTL_AUTOSLEEP_BIT, enabled);
|
||
|
}
|
||
|
|
||
|
/** Set measurement enabled status.
|
||
|
* @param enabled Measurement enabled status
|
||
|
* @see getMeasureEnabled()
|
||
|
* @see ADXL345_RA_POWER_CTL
|
||
|
* @see ADXL345_PCTL_MEASURE_BIT
|
||
|
*/
|
||
|
void ADXL345::setMeasureEnabled(bool enabled) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_POWER_CTL, ADXL345_PCTL_MEASURE_BIT, enabled);
|
||
|
}
|
||
|
|
||
|
// DATA_FORMAT register
|
||
|
|
||
|
/** Set self-test force enabled.
|
||
|
* @param enabled New self-test force enabled setting
|
||
|
* @see getSelfTestEnabled()
|
||
|
* @see ADXL345_RA_DATA_FORMAT
|
||
|
* @see ADXL345_FORMAT_SELFTEST_BIT
|
||
|
*/
|
||
|
void ADXL345::setSelfTestEnabled(unsigned char enabled) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_DATA_FORMAT, ADXL345_FORMAT_SELFTEST_BIT, enabled);
|
||
|
}
|
||
|
|
||
|
/** Set interrupt mode setting.
|
||
|
* @param mode New interrupt mode setting
|
||
|
* @see getInterruptMode()
|
||
|
* @see ADXL345_RA_DATA_FORMAT
|
||
|
* @see ADXL345_FORMAT_INTMODE_BIT
|
||
|
*/
|
||
|
void ADXL345::setInterruptMode(unsigned char mode) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_DATA_FORMAT, ADXL345_FORMAT_INTMODE_BIT, mode);
|
||
|
}
|
||
|
|
||
|
/** Set full resolution mode setting.
|
||
|
* @param resolution New full resolution enabled setting
|
||
|
* @see getFullResolution()
|
||
|
* @see ADXL345_RA_DATA_FORMAT
|
||
|
* @see ADXL345_FORMAT_FULL_RES_BIT
|
||
|
*/
|
||
|
void ADXL345::setFullResolution(unsigned char resolution) {
|
||
|
Board::get()->i2c_write_bit(devAddr, ADXL345_RA_DATA_FORMAT, ADXL345_FORMAT_FULL_RES_BIT, resolution);
|
||
|
}
|
||
|
|
||
|
/** Set data range setting.
|
||
|
* @param range Range value (0x0 - 0x3 for 2g/4g/8g/16g)
|
||
|
* @see getRange()
|
||
|
* @see ADXL345_RA_DATA_FORMAT
|
||
|
* @see ADXL345_FORMAT_RANGE_BIT
|
||
|
* @see ADXL345_FORMAT_RANGE_LENGTH
|
||
|
*/
|
||
|
void ADXL345::setRange(unsigned char range) {
|
||
|
Board::get()->i2c_write_bits(devAddr, ADXL345_RA_DATA_FORMAT, ADXL345_FORMAT_RANGE_BIT, ADXL345_FORMAT_RANGE_LENGTH, range);
|
||
|
}
|
||
|
|
||
|
// DATA* registers
|
||
|
|
||
|
/** Get 3-axis accleration measurements.
|
||
|
* These six bytes (Register 0x32 to Register 0x37) are eight bits each and hold
|
||
|
* the output data for each axis. Register 0x32 and Register 0x33 hold the
|
||
|
* output data for the x-axis, Register 0x34 and Register 0x35 hold the output
|
||
|
* data for the y-axis, and Register 0x36 and Register 0x37 hold the output data
|
||
|
* for the z-axis. The output data is twos complement, with DATAx0 as the least
|
||
|
* significant byte and DATAx1 as the most significant byte, where x represent
|
||
|
* X, Y, or Z. The DATA_FORMAT register (Address 0x31) controls the format of
|
||
|
* the data. It is recommended that a multiple-byte read of all registers be
|
||
|
* performed to prevent a change in data between reads of sequential registers.
|
||
|
*
|
||
|
* The DATA_FORMAT register controls the presentation of data to Register 0x32
|
||
|
* through Register 0x37. All data, except that for the +/-16 g range, must be
|
||
|
* clipped to avoid rollover.
|
||
|
*
|
||
|
* @param x 16-bit signed integer container for X-axis acceleration
|
||
|
* @param y 16-bit signed integer container for Y-axis acceleration
|
||
|
* @param z 16-bit signed integer container for Z-axis acceleration
|
||
|
* @see ADXL345_RA_DATAX0
|
||
|
*/
|
||
|
void ADXL345::getAcceleration(short* x, short* y, short* z) {
|
||
|
Board::get()->i2c_read_buf(devAddr, ADXL345_RA_DATAX0, buffer, 6);
|
||
|
*x = (((short)buffer[1]) << 8) | buffer[0];
|
||
|
*y = (((short)buffer[3]) << 8) | buffer[2];
|
||
|
*z = (((short)buffer[5]) << 8) | buffer[4];
|
||
|
}
|