first commit
This commit is contained in:
508
libraries/Adafruit_ADXL343/Adafruit_ADXL343.cpp
Normal file
508
libraries/Adafruit_ADXL343/Adafruit_ADXL343.cpp
Normal file
@@ -0,0 +1,508 @@
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_ADXL343.cpp
|
||||
@author Bryan Siepert and K.Townsend (Adafruit Industries)
|
||||
|
||||
BSD License (see license.txt)
|
||||
|
||||
The ADXL343 is a digital accelerometer with 13-bit resolution, capable
|
||||
of measuring up to +/-16g. This driver communicates using I2C.
|
||||
|
||||
This is a library for the Adafruit ADXL343 breakout
|
||||
----> https://www.adafruit.com/product/4097
|
||||
or the Adafruit ADXL343 + ADT7410 FeatherWing
|
||||
----> https://www.adafruit.com/product/4147
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
v1.0 - First release
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <Wire.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "Adafruit_ADXL343.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Writes 8-bits to the specified destination register
|
||||
|
||||
@param reg The register to write to
|
||||
@param value The value to write to the register
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
void Adafruit_ADXL343::writeRegister(uint8_t reg, uint8_t value) {
|
||||
Adafruit_BusIO_Register reg_obj = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, reg, 1);
|
||||
reg_obj.write(value);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads 8-bits from the specified register
|
||||
|
||||
@param reg register to read
|
||||
|
||||
@return The results of the register read request
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_ADXL343::readRegister(uint8_t reg) {
|
||||
Adafruit_BusIO_Register reg_obj = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, reg, 1);
|
||||
return ((uint8_t)reg_obj.read());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads 16-bits from the specified register
|
||||
|
||||
@param reg The register to read two bytes from
|
||||
|
||||
@return The 16-bit value read from the reg starting address
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
int16_t Adafruit_ADXL343::read16(uint8_t reg) {
|
||||
Adafruit_BusIO_Register reg_obj = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, reg, 2);
|
||||
return ((uint16_t)reg_obj.read());
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Read the device ID (can be used to check connection)
|
||||
|
||||
@return The 8-bit device ID
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_ADXL343::getDeviceID(void) {
|
||||
// Check device ID register
|
||||
return readRegister(ADXL3XX_REG_DEVID);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Enables (1) or disables (0) the interrupts on the specified
|
||||
interrupt pin.
|
||||
|
||||
@param cfg The bitfield of the interrupts to enable or disable.
|
||||
|
||||
@return True if the operation was successful, otherwise false.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_ADXL343::enableInterrupts(int_config cfg) {
|
||||
/* Update the INT_ENABLE register with 'config'. */
|
||||
writeRegister(ADXL3XX_REG_INT_ENABLE, cfg.value);
|
||||
|
||||
/* ToDo: Add proper error checking! */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief 'Maps' the specific interrupt to either pin INT1 (bit=0),
|
||||
of pin INT2 (bit=1).
|
||||
|
||||
@param cfg The bitfield of the interrupts to enable or disable.
|
||||
|
||||
@return True if the operation was successful, otherwise false.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_ADXL343::mapInterrupts(int_config cfg) {
|
||||
/* Update the INT_MAP register with 'config'. */
|
||||
writeRegister(ADXL3XX_REG_INT_MAP, cfg.value);
|
||||
|
||||
/* ToDo: Add proper error checking! */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads the status of the interrupt pins. Reading this register
|
||||
also clears or deasserts any currently active interrupt.
|
||||
|
||||
@return The 8-bit content of the INT_SOURCE register.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_ADXL343::checkInterrupts(void) {
|
||||
return readRegister(ADXL3XX_REG_INT_SOURCE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent X axis value
|
||||
|
||||
@return The 16-bit signed value for the X axis
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t Adafruit_ADXL343::getX(void) { return read16(ADXL3XX_REG_DATAX0); }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent Y axis value
|
||||
|
||||
@return The 16-bit signed value for the Y axis
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t Adafruit_ADXL343::getY(void) { return read16(ADXL3XX_REG_DATAY0); }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent Z axis value
|
||||
|
||||
@return The 16-bit signed value for the Z axis
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int16_t Adafruit_ADXL343::getZ(void) { return read16(ADXL3XX_REG_DATAZ0); }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads 3x16-bits from the x, y, and z data register
|
||||
@param x reference to return x acceleration data
|
||||
@param y reference to return y acceleration data
|
||||
@param z reference to return z acceleration data
|
||||
@return True if the operation was successful, otherwise false.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_ADXL343::getXYZ(int16_t &x, int16_t &y, int16_t &z) {
|
||||
int16_t buffer[] = {0, 0, 0};
|
||||
Adafruit_BusIO_Register reg_obj = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_DATAX0, 6);
|
||||
if (!reg_obj.read((uint8_t *)&buffer, 6))
|
||||
return false;
|
||||
x = buffer[0];
|
||||
y = buffer[1];
|
||||
z = buffer[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
* @brief Instantiates a new ADXL343 class
|
||||
*
|
||||
* @param sensorID An optional ID # so you can track this sensor, it will
|
||||
* tag sensorEvents you create.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_ADXL343::Adafruit_ADXL343(int32_t sensorID) {
|
||||
_sensorID = sensorID;
|
||||
_wire = &Wire;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
* @brief Instantiates a new ADXL343 class
|
||||
*
|
||||
* @param sensorID An optional ID # so you can track this sensor, it will
|
||||
* tag sensorEvents you create.
|
||||
* @param wireBus TwoWire instance to use for I2C communication.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_ADXL343::Adafruit_ADXL343(int32_t sensorID, TwoWire *wireBus) {
|
||||
_sensorID = sensorID;
|
||||
_wire = wireBus;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new ADXL343 class in software SPI mode
|
||||
|
||||
@param clock The SCK pin
|
||||
@param miso The MISO pin
|
||||
@param mosi The MOSI pin
|
||||
@param cs The CS/SSEL pin
|
||||
@param sensorID An optional ID # so you can track this sensor, it will tag
|
||||
sensorEvents you create.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_ADXL343::Adafruit_ADXL343(uint8_t clock, uint8_t miso, uint8_t mosi,
|
||||
uint8_t cs, int32_t sensorID) {
|
||||
_sensorID = sensorID;
|
||||
_cs = cs;
|
||||
_clk = clock;
|
||||
_do = mosi;
|
||||
_di = miso;
|
||||
_wire = NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new ADXL343 class in hardware SPI mode
|
||||
|
||||
@param cs The CS/SSEL pin
|
||||
@param theSPI SPIClass instance to use for SPI communication.
|
||||
@param sensorID An optional ID # so you can track this sensor, it will tag
|
||||
sensorEvents you create.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_ADXL343::Adafruit_ADXL343(uint8_t cs, SPIClass *theSPI,
|
||||
int32_t sensorID) {
|
||||
_sensorID = sensorID;
|
||||
_cs = cs;
|
||||
_spi = theSPI;
|
||||
_wire = NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Setups the HW (reads coefficients values, etc.)
|
||||
@param i2caddr The 7-bit I2C address to find the ADXL on
|
||||
@return True if the sensor was successfully initialised.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_ADXL343::begin(uint8_t i2caddr) {
|
||||
|
||||
if (_wire) {
|
||||
//-- I2C --------------
|
||||
if (i2c_dev) {
|
||||
delete i2c_dev; // remove old interface
|
||||
}
|
||||
i2c_dev = new Adafruit_I2CDevice(i2caddr, _wire);
|
||||
|
||||
if (!i2c_dev->begin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
//-- SPI --------------
|
||||
i2c_dev = NULL;
|
||||
|
||||
if (spi_dev) {
|
||||
delete spi_dev; // remove old interface
|
||||
}
|
||||
if (_spi) {
|
||||
// hardware spi
|
||||
spi_dev = new Adafruit_SPIDevice(_cs,
|
||||
1000000, // frequency
|
||||
SPI_BITORDER_MSBFIRST, // bit order
|
||||
SPI_MODE3, // data mode
|
||||
_spi); // hardware SPI
|
||||
} else {
|
||||
// software spi
|
||||
spi_dev = new Adafruit_SPIDevice(_cs, _clk, _di, _do,
|
||||
1000000, // frequency
|
||||
SPI_BITORDER_MSBFIRST, // bit order
|
||||
SPI_MODE3); // data mode
|
||||
}
|
||||
|
||||
if (!spi_dev->begin()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check connection */
|
||||
uint8_t deviceid = getDeviceID();
|
||||
if (deviceid != 0xE5) {
|
||||
/* No ADXL343 detected ... return false */
|
||||
return false;
|
||||
}
|
||||
|
||||
_range = ADXL343_RANGE_2_G;
|
||||
// Default tap detection level (2G, 31.25ms duration, single tap only)
|
||||
// If only the single tap function is in use, the single tap interrupt
|
||||
// is triggered when the acceleration goes below the threshold, as
|
||||
// long as DUR has not been exceeded.
|
||||
writeRegister(ADXL3XX_REG_INT_ENABLE, 0); // Disable interrupts to start
|
||||
writeRegister(ADXL3XX_REG_THRESH_TAP, 20); // 62.5 mg/LSB (so 0xFF = 16 g)
|
||||
writeRegister(ADXL3XX_REG_DUR, 50); // Max tap duration, 625 µs/LSB
|
||||
writeRegister(ADXL3XX_REG_LATENT,
|
||||
0); // Tap latency, 1.25 ms/LSB, 0=no double tap
|
||||
writeRegister(ADXL3XX_REG_WINDOW,
|
||||
0); // Waiting period, 1.25 ms/LSB, 0=no double tap
|
||||
writeRegister(ADXL3XX_REG_TAP_AXES, 0x7); // Enable the XYZ axis for tap
|
||||
|
||||
// Enable measurements
|
||||
writeRegister(ADXL3XX_REG_POWER_CTL, 0x08);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the g range for the accelerometer
|
||||
|
||||
@param range The range to set, based on adxl34x_range_t
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ADXL343::setRange(adxl34x_range_t range) {
|
||||
Adafruit_BusIO_Register data_format_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC,
|
||||
ADXL3XX_REG_DATA_FORMAT, 1);
|
||||
|
||||
Adafruit_BusIO_RegisterBits range_bits =
|
||||
Adafruit_BusIO_RegisterBits(&data_format_reg, 2, 0);
|
||||
|
||||
Adafruit_BusIO_RegisterBits full_range_bit =
|
||||
Adafruit_BusIO_RegisterBits(&data_format_reg, 1, 3);
|
||||
|
||||
/* Update the data rate */
|
||||
range_bits.write(range);
|
||||
/* Make sure that the FULL-RES bit is enabled for range scaling */
|
||||
full_range_bit.write(true);
|
||||
|
||||
/* Keep track of the current range (to avoid readbacks) */
|
||||
_range = range;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the g range for the accelerometer
|
||||
|
||||
@return The adxl34x_range_t value corresponding to the sensors range
|
||||
*/
|
||||
/**************************************************************************/
|
||||
adxl34x_range_t Adafruit_ADXL343::getRange(void) {
|
||||
Adafruit_BusIO_Register data_format_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC,
|
||||
ADXL3XX_REG_DATA_FORMAT, 1);
|
||||
|
||||
Adafruit_BusIO_RegisterBits range_bits =
|
||||
Adafruit_BusIO_RegisterBits(&data_format_reg, 2, 0);
|
||||
return (adxl34x_range_t)range_bits.read();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the data rate for the ADXL343 (controls power consumption)
|
||||
|
||||
@param dataRate The data rate to set, based on adxl3xx_dataRate_t
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ADXL343::setDataRate(adxl3xx_dataRate_t dataRate) {
|
||||
/* Note: The LOW_POWER bits are currently ignored and we always keep
|
||||
the device in 'normal' mode */
|
||||
writeRegister(ADXL3XX_REG_BW_RATE, dataRate);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the data rate for the ADXL343 (controls power consumption)
|
||||
|
||||
@return The current data rate, based on adxl3xx_dataRate_t
|
||||
*/
|
||||
/**************************************************************************/
|
||||
adxl3xx_dataRate_t Adafruit_ADXL343::getDataRate(void) {
|
||||
Adafruit_BusIO_Register bw_rate_reg = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_BW_RATE, 1);
|
||||
|
||||
Adafruit_BusIO_RegisterBits rate_bits =
|
||||
Adafruit_BusIO_RegisterBits(&bw_rate_reg, 4, 0);
|
||||
|
||||
return (adxl3xx_dataRate_t)rate_bits.read();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Retrieves the X Y Z trim offsets, note that they are 4 bits signed
|
||||
but we use int8_t to store and 'extend' the sign bit!
|
||||
@param x Pointer to the x offset, from -5 to 4 (internally multiplied by 8
|
||||
lsb)
|
||||
@param y Pointer to the y offset, from -5 to 4 (internally multiplied by 8
|
||||
lsb)
|
||||
@param z Pointer to the z offset, from -5 to 4 (internally multiplied by 8
|
||||
lsb)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ADXL343::getTrimOffsets(int8_t *x, int8_t *y, int8_t *z) {
|
||||
Adafruit_BusIO_Register x_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSX, 1);
|
||||
if (x != NULL)
|
||||
*x = x_off.read();
|
||||
Adafruit_BusIO_Register y_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSY, 1);
|
||||
if (y != NULL)
|
||||
*y = y_off.read();
|
||||
Adafruit_BusIO_Register z_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSZ, 1);
|
||||
if (z != NULL)
|
||||
*z = z_off.read();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the X Y Z trim offsets, note that they are 4 bits signed
|
||||
but we use int8_t to store and 'extend' the sign bit!
|
||||
@param x The x offset, from -5 to 4 (internally multiplied by 8 lsb)
|
||||
@param y The y offset, from -5 to 4 (internally multiplied by 8 lsb)
|
||||
@param z The z offset, from -5 to 4 (internally multiplied by 8 lsb)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ADXL343::setTrimOffsets(int8_t x, int8_t y, int8_t z) {
|
||||
Adafruit_BusIO_Register x_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSX, 1);
|
||||
x_off.write(x);
|
||||
|
||||
Adafruit_BusIO_Register y_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSY, 1);
|
||||
y_off.write(y);
|
||||
|
||||
Adafruit_BusIO_Register z_off = Adafruit_BusIO_Register(
|
||||
i2c_dev, spi_dev, AD8_HIGH_TOREAD_AD7_HIGH_TOINC, ADXL3XX_REG_OFSZ, 1);
|
||||
z_off.write(z);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent sensor event
|
||||
|
||||
@param event Pointer to the sensors_event_t placeholder
|
||||
|
||||
@return True of the read request was successful.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_ADXL343::getEvent(sensors_event_t *event) {
|
||||
int16_t x, y, z;
|
||||
/* Clear the event */
|
||||
memset(event, 0, sizeof(sensors_event_t));
|
||||
|
||||
event->version = sizeof(sensors_event_t);
|
||||
event->sensor_id = _sensorID;
|
||||
event->type = SENSOR_TYPE_ACCELEROMETER;
|
||||
event->timestamp = millis();
|
||||
if (!getXYZ(x, y, z))
|
||||
return false;
|
||||
event->acceleration.x =
|
||||
x * ADXL343_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
|
||||
event->acceleration.y =
|
||||
y * ADXL343_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
|
||||
event->acceleration.z =
|
||||
z * ADXL343_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor_t data
|
||||
|
||||
@param sensor Pointer to the sensor_t placeholder.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ADXL343::getSensor(sensor_t *sensor) {
|
||||
/* Clear the sensor_t object */
|
||||
memset(sensor, 0, sizeof(sensor_t));
|
||||
|
||||
/* Insert the sensor name in the fixed length char array */
|
||||
strncpy(sensor->name, "ADXL343", sizeof(sensor->name) - 1);
|
||||
sensor->name[sizeof(sensor->name) - 1] = 0;
|
||||
sensor->version = 1;
|
||||
sensor->sensor_id = _sensorID;
|
||||
sensor->type = SENSOR_TYPE_ACCELEROMETER;
|
||||
sensor->min_delay = 0;
|
||||
sensor->min_value = -156.9064F; /* -16g = 156.9064 m/s^2 */
|
||||
sensor->max_value = 156.9064F; /* 16g = 156.9064 m/s^2 */
|
||||
sensor->resolution = 0.03923F; /* 4mg = 0.0392266 m/s^2 */
|
||||
}
|
||||
Reference in New Issue
Block a user