mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 17:27:59 +01:00
tests and calib/transform options
This commit is contained in:
parent
78aef0a348
commit
d7e0ca6eed
11 changed files with 244 additions and 71 deletions
|
@ -3,11 +3,16 @@ import esphome.config_validation as cv
|
|||
from esphome.components import i2c
|
||||
from esphome import automation
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_ADDRESS,
|
||||
CONF_CALIBRATION,
|
||||
CONF_ID,
|
||||
CONF_MIRROR_X,
|
||||
CONF_MIRROR_Y,
|
||||
CONF_MODEL,
|
||||
CONF_RANGE,
|
||||
CONF_RESOLUTION,
|
||||
CONF_SWAP_XY,
|
||||
CONF_TRANSFORM,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
@ -15,13 +20,15 @@ AUTO_LOAD = ["sensor", "binary_sensor", "text_sensor"]
|
|||
|
||||
CONF_MSA3XX_ID = "msa3xx_id"
|
||||
|
||||
CONF_MIRROR_Z = "mirror_z"
|
||||
CONF_OFFSET_X = "offset_x"
|
||||
CONF_OFFSET_Y = "offset_y"
|
||||
CONF_OFFSET_Z = "offset_z"
|
||||
CONF_ON_TAP = "on_tap"
|
||||
CONF_ON_ACTIVE = "on_active"
|
||||
CONF_ON_DOUBLE_TAP = "on_double_tap"
|
||||
CONF_ON_FREEFALL = "on_freefall"
|
||||
CONF_ON_ORIENTATION = "on_orientation"
|
||||
CONF_ON_TAP = "on_tap"
|
||||
|
||||
|
||||
msa3xx_ns = cg.esphome_ns.namespace("msa3xx")
|
||||
|
@ -72,9 +79,28 @@ CONFIG_SCHEMA = cv.Schema(
|
|||
cv.Optional(CONF_RANGE, default="2G"): cv.enum(MSA_RANGES, upper=True),
|
||||
# cv.Optional(CONF_BANDWIDTH, default="250HZ"): cv.enum(MSA_BANDWIDTHS, upper=True),
|
||||
cv.Optional(CONF_RESOLUTION): cv.enum(MSA_RESOLUTIONS),
|
||||
cv.Optional(CONF_OFFSET_X, default=0): cv.float_range(min=-4.5, max=4.5),
|
||||
cv.Optional(CONF_OFFSET_Y, default=0): cv.float_range(min=-4.5, max=4.5),
|
||||
cv.Optional(CONF_OFFSET_Z, default=0): cv.float_range(min=-4.5, max=4.5),
|
||||
cv.Optional(CONF_CALIBRATION): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_OFFSET_X, default=0): cv.float_range(
|
||||
min=-4.5, max=4.5
|
||||
),
|
||||
cv.Optional(CONF_OFFSET_Y, default=0): cv.float_range(
|
||||
min=-4.5, max=4.5
|
||||
),
|
||||
cv.Optional(CONF_OFFSET_Z, default=0): cv.float_range(
|
||||
min=-4.5, max=4.5
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_TRANSFORM): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_MIRROR_X, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MIRROR_Z, default=False): cv.boolean,
|
||||
cv.Optional(CONF_SWAP_XY, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_ACTIVE): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_ON_TAP): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_ON_DOUBLE_TAP): automation.validate_automation(
|
||||
single=True
|
||||
|
@ -136,16 +162,31 @@ async def to_code(config):
|
|||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_model(config[CONF_MODEL]))
|
||||
cg.add(
|
||||
var.set_offset(
|
||||
config[CONF_OFFSET_X], config[CONF_OFFSET_Y], config[CONF_OFFSET_Z]
|
||||
)
|
||||
)
|
||||
cg.add(var.set_range(MSA_RANGES[config[CONF_RANGE]]))
|
||||
cg.add(var.set_resolution(MSA_RESOLUTIONS[config[CONF_RESOLUTION]]))
|
||||
|
||||
irq_set_0 = 0
|
||||
irq_set_1 = 0
|
||||
if CONF_TRANSFORM in config:
|
||||
transform = config[CONF_TRANSFORM]
|
||||
cg.add(
|
||||
var.set_transform(
|
||||
transform[CONF_MIRROR_X],
|
||||
transform[CONF_MIRROR_Y],
|
||||
transform[CONF_MIRROR_Z],
|
||||
transform[CONF_SWAP_XY],
|
||||
)
|
||||
)
|
||||
|
||||
if CONF_CALIBRATION in config:
|
||||
calibration_config = config[CONF_CALIBRATION]
|
||||
cg.add(
|
||||
var.set_offset(
|
||||
calibration_config[CONF_OFFSET_X],
|
||||
calibration_config[CONF_OFFSET_Y],
|
||||
calibration_config[CONF_OFFSET_Z],
|
||||
)
|
||||
)
|
||||
|
||||
# Triggers secton
|
||||
|
||||
if CONF_ON_ORIENTATION in config:
|
||||
await automation.build_automation(
|
||||
|
@ -153,7 +194,6 @@ async def to_code(config):
|
|||
[],
|
||||
config[CONF_ON_ORIENTATION],
|
||||
)
|
||||
irq_set_0 |= 1 << 6
|
||||
|
||||
if CONF_ON_TAP in config:
|
||||
await automation.build_automation(
|
||||
|
@ -161,7 +201,6 @@ async def to_code(config):
|
|||
[],
|
||||
config[CONF_ON_TAP],
|
||||
)
|
||||
irq_set_0 |= 1 << 5
|
||||
|
||||
if CONF_ON_DOUBLE_TAP in config:
|
||||
await automation.build_automation(
|
||||
|
@ -169,7 +208,13 @@ async def to_code(config):
|
|||
[],
|
||||
config[CONF_ON_DOUBLE_TAP],
|
||||
)
|
||||
irq_set_0 |= 1 << 4
|
||||
|
||||
if CONF_ON_ACTIVE in config:
|
||||
await automation.build_automation(
|
||||
var.get_active_trigger(),
|
||||
[],
|
||||
config[CONF_ON_ACTIVE],
|
||||
)
|
||||
|
||||
if CONF_ON_FREEFALL in config:
|
||||
await automation.build_automation(
|
||||
|
@ -177,6 +222,3 @@ async def to_code(config):
|
|||
[],
|
||||
config[CONF_ON_FREEFALL],
|
||||
)
|
||||
irq_set_1 |= 1 << 3
|
||||
|
||||
cg.add(var.set_interrupts(irq_set_0, irq_set_1))
|
||||
|
|
|
@ -7,8 +7,12 @@ namespace msa3xx {
|
|||
|
||||
static const char *const TAG = "msa3xx";
|
||||
|
||||
const uint8_t MSA3xx_PART_ID = 0x13;
|
||||
const uint8_t MSA_3XX_PART_ID = 0x13;
|
||||
|
||||
const float GRAVITY_EARTH = 9.80665f;
|
||||
const float LSB_COEFF = 1000.0f / (GRAVITY_EARTH * 3.9); // LSB to 1 LSB = 3.9mg = 0.0039g
|
||||
const float G_OFFSET_MIN = -4.5f; // -127...127 LSB = +- 0.4953g = +- 4.857 m/s^2 => +- 4.5 for the safe
|
||||
const float G_OFFSET_MAX = 4.5f; // -127...127 LSB = +- 0.4953g = +- 4.857 m/s^2 => +- 4.5 for the safe
|
||||
|
||||
const uint8_t RESOLUTION[] = {14, 12, 10, 8};
|
||||
|
||||
|
@ -36,8 +40,8 @@ const char *power_mode_to_string(PowerMode power_mode) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *res_to_string(Resolution Resolution) {
|
||||
switch (Resolution) {
|
||||
const char *res_to_string(Resolution resolution) {
|
||||
switch (resolution) {
|
||||
case Resolution::RES_14BIT:
|
||||
return "14-bit";
|
||||
case Resolution::RES_12BIT:
|
||||
|
@ -91,11 +95,28 @@ const char *bandwidth_to_string(Bandwidth bandwidth) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *orientation_xy_to_string(OrientationXY orientation) {
|
||||
switch (orientation) {
|
||||
case OrientationXY::PORTRAIT_UPRIGHT:
|
||||
return "Portrait Upright";
|
||||
case OrientationXY::PORTRAIT_UPSIDE_DOWN:
|
||||
return "Portrait Upside Down";
|
||||
case OrientationXY::LANDSCAPE_LEFT:
|
||||
return "Landscape Left";
|
||||
case OrientationXY::LANDSCAPE_RIGHT:
|
||||
return "Landscape Right";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *orientation_z_to_string(bool orientation) { return orientation ? "Downwards looking" : "Upwards looking"; }
|
||||
|
||||
void MSA3xxComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up MSA3xx...");
|
||||
|
||||
uint8_t part_id{0xff};
|
||||
if (!this->read_byte(static_cast<uint8_t>(RegisterMap::PART_ID), &part_id) || (part_id != MSA3xx_PART_ID)) {
|
||||
if (!this->read_byte(static_cast<uint8_t>(RegisterMap::PART_ID), &part_id) || (part_id != MSA_3XX_PART_ID)) {
|
||||
ESP_LOGE(TAG, "Part ID is wrong or missing. Got 0x%02X", part_id);
|
||||
this->mark_failed();
|
||||
return;
|
||||
|
@ -113,7 +134,6 @@ void MSA3xxComponent::setup() {
|
|||
} else if (this->model_ == Model::MSA311) {
|
||||
this->device_params_.accel_data_width = 12;
|
||||
this->device_params_.scale_factor_exp = static_cast<uint8_t>(this->range_) - 10;
|
||||
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unknown model");
|
||||
this->mark_failed();
|
||||
|
@ -122,11 +142,12 @@ void MSA3xxComponent::setup() {
|
|||
|
||||
this->setup_odr_(this->data_rate_);
|
||||
this->setup_power_mode_bandwidth_(this->power_mode_, this->bandwidth_);
|
||||
this->setup_range_resolution_(this->range_, this->resolution_);
|
||||
this->setup_offset_(this->offset_x_, this->offset_y_, this->offset_z_);
|
||||
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::INT_SET_0), this->int_set_0_);
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::INT_SET_1), this->int_set_1_);
|
||||
this->setup_range_resolution_(this->range_, this->resolution_); // 2g...16g, 14...8 bit
|
||||
this->setup_offset_(this->offset_x_, this->offset_y_, this->offset_z_); // calibration offsets
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::TAP_DURATION), 0b11000100); // set tap duration 250ms
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::SWAP_POLARITY), this->swap_.raw); // set axes polarity
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::INT_SET_0), 0b01110111); // enable all interrupts
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::INT_SET_1), 0b00011000); // including orientation
|
||||
}
|
||||
|
||||
void MSA3xxComponent::dump_config() {
|
||||
|
@ -140,13 +161,15 @@ void MSA3xxComponent::dump_config() {
|
|||
ESP_LOGCONFIG(TAG, " Bandwidth: %s", bandwidth_to_string(this->bandwidth_));
|
||||
ESP_LOGCONFIG(TAG, " Range: %s", range_to_string(this->range_));
|
||||
ESP_LOGCONFIG(TAG, " Resolution: %s", res_to_string(this->resolution_));
|
||||
ESP_LOGCONFIG(TAG, " Offsets: (%.3f m/s², %.3f m/s², %.3f m/s²)", this->offset_x_, this->offset_y_, this->offset_z_);
|
||||
ESP_LOGCONFIG(TAG, " Offsets: {%.3f m/s², %.3f m/s², %.3f m/s²}", this->offset_x_, this->offset_y_, this->offset_z_);
|
||||
ESP_LOGCONFIG(TAG, " Transform: {mirror_x=%s, mirror_y=%s, mirror_z=%s, swap_xy=%s}", YESNO(this->swap_.x_polarity),
|
||||
YESNO(this->swap_.y_polarity), YESNO(this->swap_.z_polarity), YESNO(this->swap_.x_y_swap));
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
LOG_SENSOR(" ", "Acceleration X", this->accel_x_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Y", this->accel_y_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Z", this->accel_z_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration X", this->acceleration_x_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Y", this->acceleration_y_sensor_);
|
||||
LOG_SENSOR(" ", "Acceleration Z", this->acceleration_z_sensor_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -165,22 +188,19 @@ bool MSA3xxComponent::read_data_() {
|
|||
};
|
||||
|
||||
this->data_.lsb_x =
|
||||
this->two_complement_to_normal_(raw_to_x_bit(accel_data[0], accel_data[1], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
this->twos_complement_(raw_to_x_bit(accel_data[0], accel_data[1], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
this->data_.lsb_y =
|
||||
this->two_complement_to_normal_(raw_to_x_bit(accel_data[2], accel_data[3], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
this->twos_complement_(raw_to_x_bit(accel_data[2], accel_data[3], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
this->data_.lsb_z =
|
||||
this->two_complement_to_normal_(raw_to_x_bit(accel_data[4], accel_data[5], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
this->twos_complement_(raw_to_x_bit(accel_data[4], accel_data[5], this->device_params_.accel_data_width),
|
||||
this->device_params_.accel_data_width);
|
||||
|
||||
this->data_.x = lpf(ldexp(this->data_.lsb_x, this->device_params_.scale_factor_exp) * GRAVITY_EARTH, this->data_.x);
|
||||
this->data_.y = lpf(ldexp(this->data_.lsb_y, this->device_params_.scale_factor_exp) * GRAVITY_EARTH, this->data_.y);
|
||||
this->data_.z = lpf(ldexp(this->data_.lsb_z, this->device_params_.scale_factor_exp) * GRAVITY_EARTH, this->data_.z);
|
||||
|
||||
// ESP_LOGVV(TAG, "Got raw data {x=%5d, y=%5d, z=%5d}, accel={x=%+1.3f m/s², y=%+1.3f m/s², z=%+1.3f m/s²}",
|
||||
// this->data_.lsb_x, this->data_.lsb_y, this->data_.lsb_z, this->data_.x, this->data_.y, this->data_.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -206,6 +226,11 @@ void MSA3xxComponent::loop() {
|
|||
return;
|
||||
}
|
||||
|
||||
// ESP_LOGVV(TAG, "Got raw data {x=%5d, y=%5d, z=%5d}, accel={x=%+1.3f m/s², y=%+1.3f m/s², z=%+1.3f m/s²}",
|
||||
// this->data_.lsb_x, this->data_.lsb_y, this->data_.lsb_z, this->data_.x, this->data_.y, this->data_.z);
|
||||
// ESP_LOGV(TAG, "Orientation XY(%s), Z(%s)", orientation_xy_to_string(this->status_.orientation.orient_xy),
|
||||
// orientation_z_to_string(this->status_.orientation.orient_z));
|
||||
|
||||
this->process_interrupts_();
|
||||
}
|
||||
|
||||
|
@ -216,16 +241,19 @@ void MSA3xxComponent::update() {
|
|||
ESP_LOGV(TAG, "Component MSA3xx not ready for update");
|
||||
return;
|
||||
}
|
||||
ESP_LOGV(TAG, "Acceleration: {x = %+1.3f m/s², y = %+1.3f m/s², z = %+1.3f m/s²}", this->data_.x, this->data_.y,
|
||||
ESP_LOGV(TAG, "Acceleration: {x = %+1.3f m/s², y = %+1.3f m/s², z = %+1.3f m/s²}; ", this->data_.x, this->data_.y,
|
||||
this->data_.z);
|
||||
|
||||
ESP_LOGV(TAG, "Orientation: {XY = %s, Z = %s}", orientation_xy_to_string(this->status_.orientation.orient_xy),
|
||||
orientation_z_to_string(this->status_.orientation.orient_z));
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
if (this->accel_x_sensor_ != nullptr)
|
||||
this->accel_x_sensor_->publish_state(this->data_.x);
|
||||
if (this->accel_y_sensor_ != nullptr)
|
||||
this->accel_y_sensor_->publish_state(this->data_.y);
|
||||
if (this->accel_z_sensor_ != nullptr)
|
||||
this->accel_z_sensor_->publish_state(this->data_.z);
|
||||
if (this->acceleration_x_sensor_ != nullptr)
|
||||
this->acceleration_x_sensor_->publish_state(this->data_.x);
|
||||
if (this->acceleration_y_sensor_ != nullptr)
|
||||
this->acceleration_y_sensor_->publish_state(this->data_.y);
|
||||
if (this->acceleration_z_sensor_ != nullptr)
|
||||
this->acceleration_z_sensor_->publish_state(this->data_.z);
|
||||
#endif
|
||||
|
||||
this->status_clear_warning();
|
||||
|
@ -238,6 +266,13 @@ void MSA3xxComponent::set_offset(float offset_x, float offset_y, float offset_z)
|
|||
this->offset_z_ = offset_z;
|
||||
}
|
||||
|
||||
void MSA3xxComponent::set_transform(bool mirror_x, bool mirror_y, bool mirror_z, bool swap_xy) {
|
||||
this->swap_.x_polarity = mirror_x;
|
||||
this->swap_.y_polarity = mirror_y;
|
||||
this->swap_.z_polarity = mirror_z;
|
||||
this->swap_.x_y_swap = swap_xy;
|
||||
}
|
||||
|
||||
void MSA3xxComponent::setup_odr_(DataRate rate) {
|
||||
RegOutputDataRate reg_odr;
|
||||
auto reg = this->read_byte(static_cast<uint8_t>(RegisterMap::ODR));
|
||||
|
@ -247,9 +282,9 @@ void MSA3xxComponent::setup_odr_(DataRate rate) {
|
|||
reg_odr.raw = 0x0F; // defaut from datasheet
|
||||
}
|
||||
|
||||
reg_odr.x_axis_disable = 0;
|
||||
reg_odr.y_axis_disable = 0;
|
||||
reg_odr.z_axis_disable = 0;
|
||||
reg_odr.x_axis_disable = false;
|
||||
reg_odr.y_axis_disable = false;
|
||||
reg_odr.z_axis_disable = false;
|
||||
reg_odr.odr = rate;
|
||||
|
||||
this->write_byte(static_cast<uint8_t>(RegisterMap::ODR), reg_odr.raw);
|
||||
|
@ -284,10 +319,8 @@ void MSA3xxComponent::setup_offset_(float offset_x, float offset_y, float offset
|
|||
uint8_t offset[3];
|
||||
|
||||
auto offset_g_to_lsb = [](float accel) -> int8_t {
|
||||
// 1 LSB = 3.9mg = 0.0039g
|
||||
// -127...127 LSB = +- 0.4953g = +- 4.857 m/s^2 => +- 4.5 for the safe
|
||||
float acccel_clamped = clamp(accel, -4.5f, 4.5f);
|
||||
return static_cast<int8_t>(accel * 1000 / (GRAVITY_EARTH * 3.9));
|
||||
float acccel_clamped = clamp(accel, G_OFFSET_MIN, G_OFFSET_MAX);
|
||||
return static_cast<int8_t>(accel * LSB_COEFF);
|
||||
};
|
||||
offset[0] = offset_g_to_lsb(offset_x);
|
||||
offset[1] = offset_g_to_lsb(offset_y);
|
||||
|
@ -299,7 +332,7 @@ void MSA3xxComponent::setup_offset_(float offset_x, float offset_y, float offset
|
|||
this->write_bytes(static_cast<uint8_t>(RegisterMap::OFFSET_COMP_X), (uint8_t *) &offset, 3);
|
||||
}
|
||||
|
||||
int64_t MSA3xxComponent::two_complement_to_normal_(uint64_t value, uint8_t bits) {
|
||||
int64_t MSA3xxComponent::twos_complement_(uint64_t value, uint8_t bits) {
|
||||
if (value > (1ULL << (bits - 1))) {
|
||||
return (int64_t) (value - (1ULL << bits));
|
||||
} else {
|
||||
|
@ -326,6 +359,11 @@ void MSA3xxComponent::process_interrupts_() {
|
|||
ESP_LOGW(TAG, "Orientation changed");
|
||||
this->orientation_trigger_.trigger();
|
||||
}
|
||||
|
||||
if (this->status_.motion_int.active_interrupt) {
|
||||
ESP_LOGW(TAG, "Activity detected");
|
||||
this->active_trigger_.trigger();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace msa3xx
|
||||
|
|
|
@ -105,6 +105,22 @@ enum class DataRate : uint8_t {
|
|||
ODR_1000HZ = 0b1010, // not available in low power mode
|
||||
};
|
||||
|
||||
enum class OrientationXY : uint8_t {
|
||||
PORTRAIT_UPRIGHT = 0b00,
|
||||
PORTRAIT_UPSIDE_DOWN = 0b01,
|
||||
LANDSCAPE_LEFT = 0b10,
|
||||
LANDSCAPE_RIGHT = 0b11,
|
||||
};
|
||||
|
||||
union Orientation {
|
||||
struct {
|
||||
OrientationXY xy : 2;
|
||||
bool z : 1;
|
||||
uint8_t reserved : 5;
|
||||
};
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
// 0x09
|
||||
union RegMotionInterrupt {
|
||||
struct {
|
||||
|
@ -124,7 +140,8 @@ union RegMotionInterrupt {
|
|||
union RegOrientationStatus {
|
||||
struct {
|
||||
uint8_t reserved_0_3 : 4;
|
||||
uint8_t orient : 3;
|
||||
OrientationXY orient_xy : 2;
|
||||
bool orient_z : 1;
|
||||
uint8_t reserved_7 : 1;
|
||||
};
|
||||
uint8_t raw{0x00};
|
||||
|
@ -163,6 +180,18 @@ union RegPowerModeBandwidth {
|
|||
uint8_t raw{0xde};
|
||||
};
|
||||
|
||||
// 0x12
|
||||
union RegSwapPolarity {
|
||||
struct {
|
||||
bool x_y_swap : 1;
|
||||
bool z_polarity : 1;
|
||||
bool y_polarity : 1;
|
||||
bool x_polarity : 1;
|
||||
uint8_t reserved : 4;
|
||||
};
|
||||
uint8_t raw{0};
|
||||
};
|
||||
|
||||
// 0x2a
|
||||
union RegTapDuration {
|
||||
struct {
|
||||
|
@ -189,21 +218,19 @@ class MSA3xxComponent : public PollingComponent, public i2c::I2CDevice {
|
|||
void set_range(Range range) { this->range_ = range; }
|
||||
void set_bandwidth(Bandwidth bandwidth) { this->bandwidth_ = bandwidth; }
|
||||
void set_resolution(Resolution resolution) { this->resolution_ = resolution; }
|
||||
void set_interrupts(uint8_t set0, uint8_t set1) {
|
||||
this->int_set_0_ = set0;
|
||||
this->int_set_1_ = set1;
|
||||
};
|
||||
void set_transform(bool mirror_x, bool mirror_y, bool mirror_z, bool swap_xy);
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
SUB_SENSOR(accel_x)
|
||||
SUB_SENSOR(accel_y)
|
||||
SUB_SENSOR(accel_z)
|
||||
SUB_SENSOR(acceleration_x)
|
||||
SUB_SENSOR(acceleration_y)
|
||||
SUB_SENSOR(acceleration_z)
|
||||
#endif
|
||||
|
||||
Trigger<> *get_tap_trigger() { return &this->tap_trigger_; }
|
||||
Trigger<> *get_double_tap_trigger() { return &this->double_tap_trigger_; }
|
||||
Trigger<> *get_orientation_trigger() { return &this->orientation_trigger_; }
|
||||
Trigger<> *get_freefall_trigger() { return &this->freefall_trigger_; }
|
||||
Trigger<> *get_active_trigger() { return &this->active_trigger_; }
|
||||
|
||||
protected:
|
||||
Model model_{Model::MSA311};
|
||||
|
@ -213,11 +240,8 @@ class MSA3xxComponent : public PollingComponent, public i2c::I2CDevice {
|
|||
Bandwidth bandwidth_{Bandwidth::BW_250HZ};
|
||||
Range range_{Range::RANGE_2G};
|
||||
Resolution resolution_{Resolution::RES_14BIT};
|
||||
|
||||
float offset_x_, offset_y_, offset_z_; // in m/s²
|
||||
|
||||
uint8_t int_set_0_{0x00};
|
||||
uint8_t int_set_1_{0x00};
|
||||
RegSwapPolarity swap_;
|
||||
|
||||
struct {
|
||||
int scale_factor_exp;
|
||||
|
@ -242,7 +266,7 @@ class MSA3xxComponent : public PollingComponent, public i2c::I2CDevice {
|
|||
bool read_data_();
|
||||
bool read_motion_status_();
|
||||
|
||||
int64_t two_complement_to_normal_(uint64_t value, uint8_t bits);
|
||||
int64_t twos_complement_(uint64_t value, uint8_t bits);
|
||||
|
||||
//
|
||||
// Actons / Triggers
|
||||
|
@ -251,10 +275,10 @@ class MSA3xxComponent : public PollingComponent, public i2c::I2CDevice {
|
|||
Trigger<> double_tap_trigger_;
|
||||
Trigger<> orientation_trigger_;
|
||||
Trigger<> freefall_trigger_;
|
||||
Trigger<> active_trigger_;
|
||||
|
||||
void process_interrupts_();
|
||||
};
|
||||
;
|
||||
|
||||
} // namespace msa3xx
|
||||
} // namespace esphome
|
||||
|
|
|
@ -45,4 +45,4 @@ async def to_code(config):
|
|||
accel_key = f"acceleration_{d}"
|
||||
if accel_key in config:
|
||||
sens = await sensor.new_sensor(config[accel_key])
|
||||
cg.add(getattr(hub, f"set_accel_{d}_sensor")(sens))
|
||||
cg.add(getattr(hub, f"set_acceleration_{d}_sensor")(sens))
|
||||
|
|
33
tests/components/msa3xx/common.yaml
Normal file
33
tests/components/msa3xx/common.yaml
Normal file
|
@ -0,0 +1,33 @@
|
|||
msa3xx:
|
||||
i2c_id: i2c_msa3xx
|
||||
model: msa301
|
||||
range: 4G
|
||||
resolution: 14
|
||||
update_interval: 10s
|
||||
calibration:
|
||||
offset_x: -0.250
|
||||
offset_y: -0.400
|
||||
offset_z: -0.800
|
||||
transform:
|
||||
mirror_x: false
|
||||
mirror_y: true
|
||||
mirror_z: true
|
||||
swap_xy: false
|
||||
on_tap:
|
||||
- then:
|
||||
- logger.log: "Tapped"
|
||||
on_double_tap:
|
||||
- then:
|
||||
- logger.log: "Double tapped"
|
||||
on_active:
|
||||
- then:
|
||||
- logger.log: "Activity detected"
|
||||
on_orientation:
|
||||
- then:
|
||||
- logger.log: "Orientation changed"
|
||||
|
||||
sensor:
|
||||
- platform: msa3xx
|
||||
acceleration_x: Accel X
|
||||
acceleration_y: Accel Y
|
||||
acceleration_z: Accel Z
|
6
tests/components/msa3xx/test.esp32-c3-idf.yaml
Normal file
6
tests/components/msa3xx/test.esp32-c3-idf.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO5
|
||||
sda: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
6
tests/components/msa3xx/test.esp32-c3.yaml
Normal file
6
tests/components/msa3xx/test.esp32-c3.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO5
|
||||
sda: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
6
tests/components/msa3xx/test.esp32-idf.yaml
Normal file
6
tests/components/msa3xx/test.esp32-idf.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO16
|
||||
sda: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
6
tests/components/msa3xx/test.esp32.yaml
Normal file
6
tests/components/msa3xx/test.esp32.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO16
|
||||
sda: GPIO17
|
||||
|
||||
<<: !include common.yaml
|
6
tests/components/msa3xx/test.esp8266.yaml
Normal file
6
tests/components/msa3xx/test.esp8266.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO5
|
||||
sda: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
6
tests/components/msa3xx/test.rp2040.yaml
Normal file
6
tests/components/msa3xx/test.rp2040.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
i2c:
|
||||
- id: i2c_msa3xx
|
||||
scl: GPIO5
|
||||
sda: GPIO4
|
||||
|
||||
<<: !include common.yaml
|
Loading…
Reference in a new issue