Files
jdillenburg-esphome/components/adxl345/adxl345.cpp
2025-09-10 14:01:29 -05:00

102 lines
3.2 KiB
C++

#include "adxl345.h"
#include "esphome/core/log.h"
#include <cmath>
namespace esphome {
namespace adxl345 {
static const char *const TAG = "adxl345";
// Register map
static const uint8_t REG_DEVID = 0x00;
static const uint8_t REG_POWER_CTL = 0x2D;
static const uint8_t REG_DATA_FORMAT = 0x31;
static const uint8_t REG_DATAX0 = 0x32;
void ADXL345Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up ADXL345...");
// Check device ID
uint8_t devid;
if (this->read_register(REG_DEVID, &devid, 1) != i2c::ERROR_OK || devid != 0xE5) {
ESP_LOGE(TAG, "ADXL345 not found at 0x%02X (id=0x%02X)", this->address_, devid);
this->mark_failed();
return;
}
ESP_LOGI(TAG, "Found ADXL345 at 0x%02X", this->address_);
// Set range
uint8_t range_bits = 0;
switch (this->range_) {
case 0: range_bits = 0x00; break; // ±2g
case 1: range_bits = 0x01; break; // ±4g
case 2: range_bits = 0x02; break; // ±8g
case 3: range_bits = 0x03; break; // ±16g
}
this->write_register(REG_DATA_FORMAT, &range_bits, 1);
// Enable measurement mode
uint8_t power = 0x08;
this->write_register(REG_POWER_CTL, &power, 1);
ESP_LOGD(TAG, "ADXL345 setup complete");
}
void ADXL345Component::dump_config() {
ESP_LOGCONFIG(TAG, "ADXL345:");
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
const char* range_str;
switch (this->range_) {
case 0: range_str = "2G"; break;
case 1: range_str = "4G"; break;
case 2: range_str = "8G"; break;
case 3: range_str = "16G"; break;
default: range_str = "Unknown"; break;
}
ESP_LOGCONFIG(TAG, " Range: %s", range_str);
if (this->off_vertical_ != nullptr) LOG_SENSOR(" ", "Off Vertical", this->off_vertical_);
if (this->jitter_ != nullptr) LOG_SENSOR(" ", "Jitter", this->jitter_);
if (this->accel_x_ != nullptr) LOG_SENSOR(" ", "Acceleration X", this->accel_x_);
if (this->accel_y_ != nullptr) LOG_SENSOR(" ", "Acceleration Y", this->accel_y_);
if (this->accel_z_ != nullptr) LOG_SENSOR(" ", "Acceleration Z", this->accel_z_);
}
void ADXL345Component::update() {
uint8_t buffer[6];
if (this->read_register(REG_DATAX0, buffer, 6) != i2c::ERROR_OK) {
ESP_LOGW(TAG, "Failed to read data");
return;
}
int16_t raw_x = (int16_t)(buffer[1] << 8 | buffer[0]);
int16_t raw_y = (int16_t)(buffer[3] << 8 | buffer[2]);
int16_t raw_z = (int16_t)(buffer[5] << 8 | buffer[4]);
// Scale: 4 mg/LSB in full-res mode (0.004 g), convert to m/s²
float scale = 0.004f * 9.80665f;
float x = raw_x * scale;
float y = raw_y * scale;
float z = raw_z * scale;
if (this->accel_x_ != nullptr) this->accel_x_->publish_state(x);
if (this->accel_y_ != nullptr) this->accel_y_->publish_state(y);
if (this->accel_z_ != nullptr) this->accel_z_->publish_state(z);
if (this->off_vertical_ != nullptr) {
double pitch = atan(y / sqrt(pow(x, 2) + pow(z, 2))) * 180.0 / M_PI;
double roll = atan(-x / sqrt(pow(y, 2) + pow(z, 2))) * 180.0 / M_PI;
this->off_vertical_->publish_state(std::max(std::abs(pitch), std::abs(roll)));
}
if (this->jitter_ != nullptr) {
float jitter = fabs(x) + fabs(y) + fabs(z);
this->jitter_->publish_state(jitter);
}
}
} // namespace adxl345
} // namespace esphome