ADXL345 3-Axis Accelerometer
The Adxl345 component provides an interface to the ADXL345 accelerometer, which is a small, thin, low-power, 3-axis accelerometer with high resolution (13-bit) measurement at up to ±16 g. It can be used in various applications such as motion detection, orientation sensing, and gesture recognition.
API Reference
Header File
Classes
-
class Adxl345 : public espp::BasePeripheral<>
Class for the ADXL345 I2C 3-axis accelerometer.
The ADXL345 is a 3-axis accelerometer with 10-bit to 13-bit resolution measurement at up to ±16g. Digital output data is formatted as 16-bit twos complement and is accessible through either a SPI (3- or 4-wire) or I2C digital interface.
The ADXL345 can support SPI up to 5 MHz and I2C up to 400 kHz. It has a programmable interrupt system that can be used to signal events such as data ready, free-fall, activity, inactivity, and tap detection.
The datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl345.pdf
ADXL345 Example
// I2C configuration espp::I2c i2c({ .port = I2C_NUM_0, .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO, .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO, }); std::error_code ec; // Create the ADXL345 instance // NOTE: auto_init defaults to true, so we don't have to call initialize ourselves. espp::Adxl345 accel(espp::Adxl345::Config{ .device_address = espp::Adxl345::DEFAULT_ADDRESS, .range = espp::Adxl345::RANGE_2G, .data_rate = espp::Adxl345::RATE_100_HZ, .write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .read = std::bind(&espp::I2c::read, &i2c, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .log_level = espp::Logger::Verbosity::WARN, }); // Disable measurement mode initially, so we can configure interrupts and such accel.set_measurement_mode(false, ec); // Configure the ADXL345 accel.set_fifo_mode(espp::Adxl345::FifoMode::STREAM, ec); // discard old data when FIFO is full accel.set_fifo_num_samples(1, ec); // set FIFO to trigger watermark interrupt on every sample accel.set_low_power(false, ec); // disable low power mode accel.set_sleep_mode(false, ec); // disable sleep mode accel.set_auto_sleep(false, ec); // disable auto sleep mode bool active_high = false; accel.set_interrupt_polarity(active_high, ec); // set interrupt polarity to active high // configure the interrupt to trigger on watermark on INT1 pin accel.set_interrupt_mapping(espp::Adxl345::InterruptType::WATERMARK, espp::Adxl345::InterruptPin::INT1, ec); // enable the watermark interrupt accel.configure_interrupt(espp::Adxl345::InterruptType::WATERMARK, true, ec); static auto start = std::chrono::high_resolution_clock::now(); auto callback = [&](const espp::Interrupt::Event &event) { std::error_code ec; // clear the interrupt source [[maybe_unused]] auto interrupt_status = accel.get_interrupt_source(ec); if (ec) { logger.error("Error getting interrupt source: {}", ec.message()); } auto now = std::chrono::high_resolution_clock::now(); // we got a data ready interrupt, read the data and print it auto data_vec = accel.read_all(ec); if (ec) { fmt::print("Error reading ADXL345: {}\n", ec.message()); return; } for (int i = 0; i < data_vec.size(); ++i) { auto &data = data_vec[i]; // get the offset in time from now that hte sample was taken auto sample_time = now - 10ms * (data_vec.size() - i - 1); // convert to seconds auto elapsed = std::chrono::duration<float>(sample_time - start).count(); // Print the data in g's fmt::print("{:.3f}, {:.4f}, {:.4f}, {:.4f}\n", elapsed, data.x, data.y, data.z); } }; espp::Interrupt::PinConfig accel_int = { .gpio_num = (gpio_num_t)CONFIG_EXAMPLE_ALERT_GPIO, .callback = callback, .active_level = espp::Interrupt::ActiveLevel::LOW, .interrupt_type = espp::Interrupt::Type::FALLING_EDGE, .pullup_enabled = true, .pulldown_enabled = false, .filter_type = espp::Interrupt::FilterType::PIN_GLITCH_FILTER, }; espp::Interrupt interrupt({ .isr_core_id = 1, .interrupts = {accel_int}, .task_config = { .name = "Interrupt task", .stack_size_bytes = 6192, .priority = 5, }, .log_level = espp::Logger::Verbosity::WARN, }); // Print CSV header fmt::print("%time (s), x (g), y (g), z (g)\n"); // Enable measurement mode accel.set_measurement_mode(true, ec); // Keep the main function running to allow the example to run while (true) { auto start_time = std::chrono::high_resolution_clock::now(); auto active_states = interrupt.get_active_states(); logger.info("Instantaneous state of pins: {}", active_states); auto interrupt_status = accel.get_interrupt_source(ec); if (ec) { logger.error("Error getting interrupt source: {}", ec.message()); } else { logger.info("Interrupt source: 0x{:02X}", interrupt_status); } auto data_vec = accel.read_all(ec); if (ec) { logger.error("Error reading all data: {}", ec.message()); } else { logger.info("Read {} samples from ADXL345: {}", data_vec.size(), data_vec); } interrupt_status = accel.get_interrupt_source(ec); if (ec) { logger.error("Error getting interrupt source: {}", ec.message()); } else { logger.info("Interrupt source: 0x{:02X}", interrupt_status); } std::this_thread::sleep_until(start_time + 100ms); }
Public Types
-
enum Range
Range of the accelerometer.
Values:
-
enumerator RANGE_2G
±2g
-
enumerator RANGE_4G
±4g
-
enumerator RANGE_8G
±8g
-
enumerator RANGE_16G
±16g
-
enumerator RANGE_2G
-
enum DataRate
Output data rate.
Values:
-
enumerator RATE_0_10_HZ
0.10 Hz
-
enumerator RATE_0_20_HZ
0.20 Hz
-
enumerator RATE_0_39_HZ
0.39 Hz
-
enumerator RATE_0_78_HZ
0.78 Hz
-
enumerator RATE_1_56_HZ
1.56 Hz
-
enumerator RATE_3_13_HZ
3.13 Hz
-
enumerator RATE_6_25_HZ
6.25 Hz
-
enumerator RATE_12_5_HZ
12.5 Hz
-
enumerator RATE_25_HZ
25 Hz
-
enumerator RATE_50_HZ
50 Hz
-
enumerator RATE_100_HZ
100 Hz
-
enumerator RATE_200_HZ
200 Hz
-
enumerator RATE_400_HZ
400 Hz
-
enumerator RATE_800_HZ
800 Hz
-
enumerator RATE_1600_HZ
1600 Hz
-
enumerator RATE_3200_HZ
3200 Hz
-
enumerator RATE_0_10_HZ
-
enum InterruptType
Interrupt type.
Values:
-
enumerator OVERRUN
FIFO overrun interrupt.
-
enumerator WATERMARK
FIFO watermark interrupt.
-
enumerator FREE_FALL
Free fall interrupt.
-
enumerator INACTIVITY
Inactivity interrupt.
-
enumerator ACTIVITY
Activity interrupt.
-
enumerator DOUBLE_TAP
Double tap interrupt.
-
enumerator SINGLE_TAP
Single tap interrupt.
-
enumerator OVERRUN
-
enum class FifoMode
FIFO Mode.
Values:
-
enumerator BYPASS
Bypass mode.
-
enumerator FIFO
FIFO mode.
-
enumerator STREAM
Stream mode.
-
enumerator TRIGGER
Trigger mode.
-
enumerator BYPASS
-
typedef std::function<bool(uint8_t)> probe_fn
Function to probe the peripheral
- Param address:
The address to probe
- Return:
True if the peripheral is found at the given address
Public Functions
-
inline explicit Adxl345(const Config &config)
Constructor.
- Parameters:
config – Configuration for the ADXL345
-
inline bool initialize(std::error_code &ec)
Initialize the ADXL345.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
True if initialization was successful, false otherwise
-
inline bool set_range(Range range, std::error_code &ec)
Set the range of the accelerometer.
- Parameters:
range – New range
ec – Error code to set if an error occurs
- Returns:
True if setting range was successful, false otherwise
-
inline bool set_data_rate(DataRate rate, std::error_code &ec)
Set the output data rate.
- Parameters:
rate – New data rate
ec – Error code to set if an error occurs
- Returns:
True if setting data rate was successful, false otherwise
-
inline bool set_low_power(bool enable, std::error_code &ec)
Enable/Disable low power mode.
- Parameters:
enable – Whether to enable or disable low power mode
ec – Error code to set if an error occurs
- Returns:
True if setting low power mode was successful, false otherwise
-
inline bool set_auto_sleep(bool enable, std::error_code &ec)
Enable/Disable the auto-sleep mode.
- Parameters:
enable – Whether to enable or disable auto-sleep
ec – Error code to set if an error occurs
- Returns:
True if setting auto-sleep was successful, false otherwise
-
inline bool set_measurement_mode(bool enable, std::error_code &ec)
Enable/Disable the measurement mode.
- Parameters:
enable – Whether to enable or disable measurement mode
ec – Error code to set if an error occurs
- Returns:
True if setting measurement mode was successful, false otherwise
-
inline bool set_sleep_mode(bool enable, std::error_code &ec)
Enable/Disable the Sleep mode.
- Parameters:
enable – Whether to enable or disable sleep mode
ec – Error code to set if an error occurs
- Returns:
True if setting sleep mode was successful, false otherwise
-
inline bool set_fifo_mode(FifoMode mode, std::error_code &ec)
Set the FIFO mode.
- Parameters:
mode – New FIFO mode
ec – Error code to set if an error occurs
- Returns:
True if setting FIFO mode was successful, false otherwise
-
inline FifoMode get_fifo_mode(std::error_code &ec)
Get the current FIFO mode.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Current FIFO mode
-
inline bool set_fifo_num_samples(std::uint8_t num_samples, std::error_code &ec)
Set the FIFO Num Samples.
Note
Num Samples is meaningless for FifoMode::BYPASS.
Note
The FIFO can store up to 32 samples.
Note
Num Samples specifies how many FIFO entries are needed to trigger a InterruptType::WATERMARK interrupt in FifoMode::FIFO, and FifoMode::STREAM.
Note
Num Samples specifies how many FIFO entries are retained in the FIFO before an InterruptType::TRIGGER interrupt is triggered.
- Parameters:
num_samples – Number of samples to store in FIFO
ec – Error code to set if an error occurs
- Returns:
True if setting FIFO num samples was successful, false otherwise
-
inline std::uint8_t get_fifo_num_samples_available(std::error_code &ec)
Get the number of samples available in the FIFO.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Number of samples available in the FIFO (0-32)
-
inline std::uint8_t get_fifo_status(std::error_code &ec)
Get the current FIFO status.
Note
The FIFO status byte contains the following bits:
Bit 7: FIFO trigger
Bit 6: unused (always 0)
Bits 5-0: Number of entries in FIFO (0-32)
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Current FIFO status as a byte
-
inline Data read(std::error_code &ec)
Read the accelerometer data.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Accelerometer data in g
-
inline std::vector<Data> read_all(std::error_code &ec)
Read all accelerometer data from the FIFO.
Note
This function reads all available data from the FIFO. The data is returned as a vector of Data structures.
Note
If the FIFO is empty, an empty vector is returned.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Vector of accelerometer data in g
-
inline bool set_interrupt_polarity(bool active_high, std::error_code &ec)
Set the interrupt polarity.
- Parameters:
active_high – Whether the interrupt should be active high (true) or active low (false)
ec – Error code to set if an error occurs
- Returns:
True if setting interrupt polarity was successful, false otherwise
-
inline bool disable_all_interrupts(std::error_code &ec)
Disable all interrupts.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
True if disabling all interrupts was successful, false otherwise
-
inline bool configure_interrupt(InterruptType type, bool enable, std::error_code &ec)
Configure an interrupt.
- Parameters:
type – Type of interrupt to configure
enable – Whether to enable or disable the interrupt
ec – Error code to set if an error occurs
- Returns:
True if configuring interrupt was successful, false otherwise
-
inline std::uint8_t get_interrupt_source(std::error_code &ec)
Get the interrupt source.
- Parameters:
ec – Error code to set if an error occurs
- Returns:
Bitmap of active interrupts
-
inline bool set_interrupt_mapping(InterruptType type, InterruptPin pin, std::error_code &ec)
Set the interrupt mapping.
- Parameters:
type – Type of interrupt to map
pin – Interrupt pin to map to
ec – Error code to set if an error occurs
- Returns:
True if setting interrupt mapping was successful, false otherwise
-
inline bool probe(std::error_code &ec)
Probe the peripheral
Note
This function is thread safe
Note
If the probe function is not set, this function will return false and set the error code to operation_not_supported
Note
This function is only available if UseAddress is true
- Parameters:
ec – The error code to set if there is an error
- Returns:
True if the peripheral is found
-
inline void set_address(uint8_t address)
Set the address of the peripheral
Note
This function is thread safe
Note
This function is only available if UseAddress is true
- Parameters:
address – The address of the peripheral
-
inline void set_probe(const probe_fn &probe)
Set the probe function
Note
This function is thread safe
Note
This should rarely be used, as the probe function is usually set in the constructor. If you need to change the probe function, consider using the set_config function instead.
Note
This function is only available if UseAddress is true
- Parameters:
probe – The probe function
-
inline void set_write(const write_fn &write)
Set the write function
Note
This function is thread safe
Note
This should rarely be used, as the write function is usually set in the constructor. If you need to change the write function, consider using the set_config function instead.
- Parameters:
write – The write function
-
inline void set_read(const read_fn &read)
Set the read function
Note
This function is thread safe
Note
This should rarely be used, as the read function is usually set in the constructor. If you need to change the read function, consider using the set_config function instead.
- Parameters:
read – The read function
-
inline void set_read_register(const read_register_fn &read_register)
Set the read register function
Note
This function is thread safe
Note
This should rarely be used, as the read register function is usually set in the constructor. If you need to change the read register function, consider using the set_config function instead.
- Parameters:
read_register – The read register function
-
inline void set_write_then_read(const write_then_read_fn &write_then_read)
Set the write then read function
Note
This function is thread safe
Note
This should rarely be used, as the write then read function is usually set in the constructor. If you need to change the write then
- Parameters:
write_then_read – The write then read function
-
inline void set_separate_write_then_read_delay(const std::chrono::milliseconds &delay)
Set the delay between the write and read operations in write_then_read
Note
This function is thread safe
Note
This should rarely be used, as the delay is usually set in the constructor. If you need to change the delay, consider using the set_config function instead.
Note
This delay is only used if the write_then_read function is not set to a custom function and the write and read functions are separate functions.
- Parameters:
delay – The delay between the write and read operations in write_then_read
-
inline void set_config(const Config &config)
Set the configuration for the peripheral
Note
This function is thread safe
Note
The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.
- Parameters:
config – The configuration for the peripheral
-
inline void set_config(Config &&config)
Set the configuration for the peripheral
Note
This function is thread safe
Note
The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.
- Parameters:
config – The configuration for the peripheral
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
Public Static Attributes
-
static constexpr std::uint8_t DEFAULT_ADDRESS = 0x53
Default I2C address of the ADXL345.
-
struct Config
Configuration for the ADXL345.
Public Members
-
std::uint8_t device_address = DEFAULT_ADDRESS
I2C address of the device.
-
DataRate data_rate = RATE_100_HZ
Output data rate.
-
bool auto_init = true
Automatically initialize the device on construction.
-
BasePeripheral<std::uint8_t, true>::write_fn write
Function to write to the device.
-
BasePeripheral<std::uint8_t, true>::read_fn read
Function to read from the device.
-
std::uint8_t device_address = DEFAULT_ADDRESS
-
enum Range