[lsm6ds] Add motion platform for STMicro LSM6DS IMU (#16232)

Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Clyde Stubbs
2026-06-10 11:22:44 +10:00
committed by GitHub
parent 6809af3de0
commit a25ac28ae5
8 changed files with 542 additions and 0 deletions

View File

@@ -291,6 +291,7 @@ esphome/components/lock/* @esphome/core
esphome/components/logger/* @esphome/core
esphome/components/logger/select/* @clydebarrow
esphome/components/lps22/* @nagisa
esphome/components/lsm6ds/* @clydebarrow
esphome/components/ltr390/* @latonita @sjtrny
esphome/components/ltr501/* @latonita
esphome/components/ltr_als_ps/* @latonita

View File

@@ -0,0 +1,15 @@
import esphome.codegen as cg
from esphome.components import i2c
from esphome.components.motion import MotionComponent
CODEOWNERS = ["@clydebarrow"]
CONF_LSM6DS_ID = "lsm6ds_id"
# C++ namespace / class
lsm6ds_ns = cg.esphome_ns.namespace("lsm6ds")
LSM6DSComponent = lsm6ds_ns.class_(
"LSM6DSComponent",
MotionComponent,
i2c.I2CDevice,
)

View File

@@ -0,0 +1,203 @@
#include "lsm6ds.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
namespace esphome::lsm6ds {
static const char *const TAG = "lsm6ds";
static const struct {
uint8_t who_am_i;
const char *const name;
} CHIP_IDS[] = {{0x69, "LSMDSO"}, {0x6A, "LSM6DS3"}};
void LSM6DSComponent::setup() {
MotionComponent::setup();
uint8_t who_am_i = 0;
if (this->read_register(LSM6DS_REG_WHO_AM_I, &who_am_i, 1) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Failed to read WHO_AM_I — check wiring and I2C address");
this->mark_failed();
return;
}
const char *chip_name = nullptr;
for (const auto &chip : CHIP_IDS) {
if (chip.who_am_i == who_am_i) {
chip_name = chip.name;
break;
}
}
if (chip_name == nullptr) {
ESP_LOGE(TAG, "Unknown WHO_AM_I: 0x%02X", who_am_i);
this->mark_failed(LOG_STR("Unknown WHO_AM_I value"));
return;
}
ESP_LOGD(TAG, "Found %s (WHO_AM_I = 0x%02X)", chip_name, who_am_i);
this->chip_name_ = chip_name;
// 2. Software reset — clears all registers to defaults
if (this->write_register(LSM6DS_REG_CTRL3_C, &CTRL3_C_SW_RESET, 1) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Software reset failed"));
return;
}
// Datasheet: reset bit self-clears after boot (typ. 50 µs);
delay(2);
// 3. Enable auto-increment and block data update (BDU).
// BDU prevents reading a high-byte from one sample and a low-byte from the next.
// IF_INC is set by default after reset but we set it explicitly for clarity.
uint8_t ctrl3 = CTRL3_C_IF_INC | CTRL3_C_BDU;
if (this->write_register(LSM6DS_REG_CTRL3_C, &ctrl3, 1) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Config failed"));
return;
}
// 4. Configure accelerometer: ODR in bits[7:4], FS in bits[3:2]
// Anti-aliasing filter bandwidth is left at power-on default (bits[1:0] = 00 = ODR/2).
uint8_t ctrl1_xl = (uint8_t) (this->accel_odr_ << 4) | (uint8_t) (this->accel_range_ << 2);
if (this->write_register(LSM6DS_REG_CTRL1_XL, &ctrl1_xl, 1) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Failed to configure accelerometer"));
return;
}
// 5. Configure gyroscope: ODR in bits[7:4], FS_G + FS_125 in bits[3:0]
// For ±125 dps: FS_G[2:1]=00 and FS_125(bit1)=1, so gyro_range_ encodes the full nibble.
uint8_t ctrl2_g = (uint8_t) (this->gyro_odr_ << 4) | (uint8_t) (this->gyro_range_);
if (this->write_register(LSM6DS_REG_CTRL2_G, &ctrl2_g, 1) != i2c::ERROR_OK) {
this->mark_failed(LOG_STR("Failed to configure gyroscope"));
return;
}
// 6. Ensure accelerometer is in high-performance mode (CTRL6_C bit 4 = XL_HM_MODE = 0)
// and gyroscope is in high-performance mode (CTRL7_G bit 7 = G_HM_MODE = 0).
// Both default to 0 (high-performance) after reset, but write explicitly.
uint8_t zero = 0x00;
if (this->write_register(LSM6DS_REG_CTRL6_C, &zero, 1) != i2c::ERROR_OK) {
this->mark_failed();
return;
}
if (this->write_register(LSM6DS_REG_CTRL7_G, &zero, 1) != i2c::ERROR_OK) {
this->mark_failed();
return;
}
}
void LSM6DSComponent::dump_config() {
ESP_LOGCONFIG(TAG,
"LSM6DS IMU:\n"
" Chip type: %s\n",
this->chip_name_);
LOG_I2C_DEVICE(this);
LOG_UPDATE_INTERVAL(this);
// Accel range — index into the sensitivity table (datasheet Table 3)
static const char *const ACCEL_RANGE_STR[] = {"±2g", "±16g", "±4g", "±8g"};
const char *gyro_str;
switch (this->gyro_range_) {
case LSM6DS_GYRO_RANGE_125:
gyro_str = "±125dps";
break;
case LSM6DS_GYRO_RANGE_250:
gyro_str = "±250dps";
break;
case LSM6DS_GYRO_RANGE_500:
gyro_str = "±500dps";
break;
case LSM6DS_GYRO_RANGE_1000:
gyro_str = "±1000dps";
break;
case LSM6DS_GYRO_RANGE_2000:
gyro_str = "±2000dps";
break;
default:
gyro_str = "unknown";
break;
}
auto accel_odr = this->accel_odr_ == 0 ? 0 : 13 * (1 << (this->accel_odr_ - 1));
auto gyro_odr = this->gyro_odr_ == 0 ? 0 : 13 * (1 << (this->gyro_odr_ - 1));
ESP_LOGCONFIG(TAG,
" Accel range : %s\n"
" Accel data rate : %dHz\n"
" Gyro range : %s\n"
" Gyro data rate : %dHz",
ACCEL_RANGE_STR[this->accel_range_], accel_odr, gyro_str, gyro_odr);
}
// update_data()
// Called by MotionComponent::update() on each polling interval.
// Reads gyro XYZ and accel XYZ in a single 12-byte burst (registers 0x220x2D).
// Values are in g (accel) and °/s (gyro) — MotionComponent handles axis mapping
// and sensor publishing.
bool LSM6DSComponent::update_data(motion::MotionData &data) {
if (this->is_failed())
return false;
// Single burst: gyro X/Y/Z (0x220x27) then accel X/Y/Z (0x280x2D)
uint8_t raw[LSM6DS_BURST_LEN];
if (!this->read_bytes(LSM6DS_REG_OUTX_L_G, raw, LSM6DS_BURST_LEN)) {
this->status_set_error(LOG_STR("Failed to read IMU data"));
return false;
}
this->status_clear_error();
// Gyroscope
// Sensitivity (mdps/LSB) from datasheet Table 3.
// Multiply by 1e-3 to convert mdps → dps (°/s).
static constexpr float GYRO_SCALE[] = {
8.75e-3f, // 0x00 — ±250 dps
8.75e-3f, // 0x01 — unused (maps to 250 as fallback)
4.375e-3f, // 0x02 — ±125 dps (FS_125 bit set)
8.75e-3f, // 0x03 — unused
17.50e-3f, // 0x04 — ±500 dps
17.50e-3f, // 0x05 — unused
8.75e-3f, // 0x06 — unused
8.75e-3f, // 0x07 — unused
35.0e-3f, // 0x08 — ±1000 dps
35.0e-3f, // 0x09 — unused
17.50e-3f, // 0x0A — unused
17.50e-3f, // 0x0B — unused
70.0e-3f, // 0x0C — ±2000 dps
};
float gyro_scale = GYRO_SCALE[this->gyro_range_];
data.angular_rate[motion::X_AXIS] = (int16_t) ((raw[1] << 8) | raw[0]) * gyro_scale;
data.angular_rate[motion::Y_AXIS] = (int16_t) ((raw[3] << 8) | raw[2]) * gyro_scale;
data.angular_rate[motion::Z_AXIS] = (int16_t) ((raw[5] << 8) | raw[4]) * gyro_scale;
// Accelerometer
// Sensitivity (mg/LSB) from datasheet Table 3.
// Multiply by 1e-3 to convert mg → g.
// Note: FS_XL register values are non-monotonic (0=2g, 1=16g, 2=4g, 3=8g).
static constexpr float ACCEL_SCALE[] = {
0.061e-3f, // 0x00 — ±2g
0.488e-3f, // 0x01 — ±16g
0.122e-3f, // 0x02 — ±4g
0.244e-3f, // 0x03 — ±8g
};
float accel_scale = ACCEL_SCALE[this->accel_range_];
data.acceleration[motion::X_AXIS] =
(int16_t) ((raw[LSM6DS_ACCEL_OFFSET + 1] << 8) | raw[LSM6DS_ACCEL_OFFSET + 0]) * accel_scale;
data.acceleration[motion::Y_AXIS] =
(int16_t) ((raw[LSM6DS_ACCEL_OFFSET + 3] << 8) | raw[LSM6DS_ACCEL_OFFSET + 2]) * accel_scale;
data.acceleration[motion::Z_AXIS] =
(int16_t) ((raw[LSM6DS_ACCEL_OFFSET + 5] << 8) | raw[LSM6DS_ACCEL_OFFSET + 4]) * accel_scale;
// Temperature (lazy — only read if a listener is registered)
// Kept as a separate 2-byte read to avoid extending the burst to 14 bytes when
// temperature is not needed.
// Formula: T(°C) = (raw / 256.0) + 25.0 (datasheet Table 90, OUT_TEMP register)
if (!this->temperature_callback_.empty()) {
uint8_t raw_t[2];
if (this->read_bytes(LSM6DS_REG_OUT_TEMP_L, raw_t, 2)) {
int16_t temp_raw = (int16_t) ((raw_t[1] << 8) | raw_t[0]);
float temperature = (temp_raw / 256.0f) + 25.0f;
this->temperature_callback_.call(temperature);
}
}
return true;
}
} // namespace esphome::lsm6ds

View File

@@ -0,0 +1,111 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/motion/motion_component.h"
namespace esphome::lsm6ds {
// ── Register map (datasheet DocID030071 Rev 3, Table 19) ────────────────────
static const uint8_t LSM6DS_REG_WHO_AM_I = 0x0F;
static const uint8_t LSM6DS_REG_CTRL1_XL = 0x10; // Accel ODR + FS
static const uint8_t LSM6DS_REG_CTRL2_G = 0x11; // Gyro ODR + FS
static const uint8_t LSM6DS_REG_CTRL3_C = 0x12; // SW_RESET, BDU, IF_INC
static const uint8_t LSM6DS_REG_CTRL6_C = 0x15; // Accel HP disable, Gyro LPF1
static const uint8_t LSM6DS_REG_CTRL7_G = 0x16; // Gyro HP disable
static const uint8_t LSM6DS_REG_STATUS = 0x1E; // XLDA, GDA, TDA
static const uint8_t LSM6DS_REG_OUT_TEMP_L = 0x20; // Temperature LSB
static const uint8_t LSM6DS_REG_OUTX_L_G = 0x22; // Gyro X LSB (burst start)
static const uint8_t LSM6DS_REG_OUTX_L_XL = 0x28; // Accel X LSB
// Burst read from 0x22 to 0x2D inclusive: gyro XYZ (6 bytes) + accel XYZ (6 bytes)
static const uint8_t LSM6DS_BURST_LEN = 12;
static const uint8_t LSM6DS_ACCEL_OFFSET = 6; // 0x28 - 0x22
// ── CTRL3_C bit fields ───────────────────────────────────────────────────────
static const uint8_t CTRL3_C_SW_RESET = (1 << 0);
static const uint8_t CTRL3_C_IF_INC = (1 << 2); // auto-increment address on burst (default 1)
static const uint8_t CTRL3_C_BDU = (1 << 6); // block data update
// ── Accelerometer full-scale range ──────────────────────────────────────────
// CTRL1_XL bits [3:2] — FS_XL[1:0]
// Note: 0x01 = ±16g is intentional per Table 52 — the mapping is non-monotonic
enum LSM6DSAccelRange : uint8_t {
LSM6DS_ACCEL_RANGE_2G = 0x00, // ±2 g, 0.061 mg/LSB
LSM6DS_ACCEL_RANGE_16G = 0x01, // ±16 g, 0.488 mg/LSB
LSM6DS_ACCEL_RANGE_4G = 0x02, // ±4 g, 0.122 mg/LSB
LSM6DS_ACCEL_RANGE_8G = 0x03, // ±8 g, 0.244 mg/LSB
};
// ── Accelerometer output data rate ──────────────────────────────────────────
// CTRL1_XL bits [7:4] — ODR_XL[3:0]
enum LSM6DSAccelODR : uint8_t {
LSM6DS_ACCEL_ODR_OFF = 0x00,
LSM6DS_ACCEL_ODR_12_5 = 0x01, // 12.5 Hz
LSM6DS_ACCEL_ODR_26 = 0x02, // 26 Hz
LSM6DS_ACCEL_ODR_52 = 0x03, // 52 Hz
LSM6DS_ACCEL_ODR_104 = 0x04, // 104 Hz
LSM6DS_ACCEL_ODR_208 = 0x05, // 208 Hz
LSM6DS_ACCEL_ODR_416 = 0x06, // 416 Hz
LSM6DS_ACCEL_ODR_833 = 0x07, // 833 Hz
LSM6DS_ACCEL_ODR_1666 = 0x08, // 1666 Hz
LSM6DS_ACCEL_ODR_3332 = 0x09, // 3332 Hz
LSM6DS_ACCEL_ODR_6664 = 0x0A, // 6664 Hz
};
// ── Gyroscope full-scale range ───────────────────────────────────────────────
// CTRL2_G bits [3:0] — FS_G[2:1] and FS_125 (bit 1)
// The FS_125 bit (bit 1) enables the ±125 dps range independently of FS_G.
// For all other ranges, bits [3:2] select the range and bit 1 = 0.
enum LSM6DSGyroRange : uint8_t {
LSM6DS_GYRO_RANGE_125 = 0x02, // ±125 dps, 4.375 mdps/LSB (FS_125=1)
LSM6DS_GYRO_RANGE_250 = 0x00, // ±250 dps, 8.75 mdps/LSB
LSM6DS_GYRO_RANGE_500 = 0x04, // ±500 dps, 17.50 mdps/LSB
LSM6DS_GYRO_RANGE_1000 = 0x08, // ±1000 dps, 35 mdps/LSB
LSM6DS_GYRO_RANGE_2000 = 0x0C, // ±2000 dps, 70 mdps/LSB
};
// ── Gyroscope output data rate ───────────────────────────────────────────────
// CTRL2_G bits [7:4] — ODR_G[3:0]
enum LSM6DSGyroODR : uint8_t {
LSM6DS_GYRO_ODR_OFF = 0x00,
LSM6DS_GYRO_ODR_12_5 = 0x01, // 12.5 Hz
LSM6DS_GYRO_ODR_26 = 0x02, // 26 Hz
LSM6DS_GYRO_ODR_52 = 0x03, // 52 Hz
LSM6DS_GYRO_ODR_104 = 0x04, // 104 Hz
LSM6DS_GYRO_ODR_208 = 0x05, // 208 Hz
LSM6DS_GYRO_ODR_416 = 0x06, // 416 Hz
LSM6DS_GYRO_ODR_833 = 0x07, // 833 Hz
LSM6DS_GYRO_ODR_1666 = 0x08, // 1666 Hz
LSM6DS_GYRO_ODR_3332 = 0x09, // 3332 Hz
LSM6DS_GYRO_ODR_6664 = 0x0A, // 6664 Hz
};
// ── Main component class ─────────────────────────────────────────────────────
class LSM6DSComponent : public motion::MotionComponent, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::DATA; }
// Configuration setters (called from Python codegen)
void set_accel_range(LSM6DSAccelRange r) { this->accel_range_ = r; }
void set_accel_odr(LSM6DSAccelODR o) { this->accel_odr_ = o; }
void set_gyro_range(LSM6DSGyroRange r) { this->gyro_range_ = r; }
void set_gyro_odr(LSM6DSGyroODR o) { this->gyro_odr_ = o; }
template<typename F> void add_temperature_listener(F &&cb) { this->temperature_callback_.add(std::forward<F>(cb)); }
protected:
const char *chip_name_{"Unknown"};
bool update_data(motion::MotionData &data) override;
LSM6DSAccelRange accel_range_{LSM6DS_ACCEL_RANGE_4G};
LSM6DSAccelODR accel_odr_{LSM6DS_ACCEL_ODR_104};
LSM6DSGyroRange gyro_range_{LSM6DS_GYRO_RANGE_2000};
LSM6DSGyroODR gyro_odr_{LSM6DS_GYRO_ODR_208};
LazyCallbackManager<void(float)> temperature_callback_{};
};
} // namespace esphome::lsm6ds

View File

@@ -0,0 +1,106 @@
import esphome.codegen as cg
from esphome.components import i2c
from esphome.components.const import (
CONF_ACCELEROMETER_ODR,
CONF_ACCELEROMETER_RANGE,
CONF_GYROSCOPE_ODR,
CONF_GYROSCOPE_RANGE,
)
from esphome.components.motion import motion_schema, new_motion_component
import esphome.config_validation as cv
from . import LSM6DSComponent, lsm6ds_ns
# ── Dependency declarations ──────────────────────────────────────────────────
DEPENDENCIES = ["i2c"]
DOMAIN = "lsm6ds"
# ── C++ namespace / class ────────────────────────────────────────────────────
# ── Enum proxies ─────────────────────────────────────────────────────────────
LSM6DSAccelRange = lsm6ds_ns.enum("LSM6DSAccelRange")
ACCEL_RANGE_OPTIONS = {
"2G": LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_2G,
"4G": LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_4G,
"8G": LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_8G,
"16G": LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_16G,
}
LSM6DSAccelODR = lsm6ds_ns.enum("LSM6DSAccelODR")
ACCEL_ODR_OPTIONS = {
"OFF": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_OFF,
"12_5HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_12_5,
"26HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_26,
"52HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_52,
"104HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_104,
"208HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_208,
"416HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_416,
"833HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_833,
"1666HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_1666,
"3332HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_3332,
"6664HZ": LSM6DSAccelODR.LSM6DS_ACCEL_ODR_6664,
}
LSM6DSGyroRange = lsm6ds_ns.enum("LSM6DSGyroRange")
GYRO_RANGE_OPTIONS = {
"125DPS": LSM6DSGyroRange.LSM6DS_GYRO_RANGE_125,
"250DPS": LSM6DSGyroRange.LSM6DS_GYRO_RANGE_250,
"500DPS": LSM6DSGyroRange.LSM6DS_GYRO_RANGE_500,
"1000DPS": LSM6DSGyroRange.LSM6DS_GYRO_RANGE_1000,
"2000DPS": LSM6DSGyroRange.LSM6DS_GYRO_RANGE_2000,
}
LSM6DSGyroODR = lsm6ds_ns.enum("LSM6DSGyroODR")
GYRO_ODR_OPTIONS = {
"OFF": LSM6DSGyroODR.LSM6DS_GYRO_ODR_OFF,
"12_5HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_12_5,
"26HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_26,
"52HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_52,
"104HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_104,
"208HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_208,
"416HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_416,
"833HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_833,
"1666HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_1666,
"3332HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_3332,
"6664HZ": LSM6DSGyroODR.LSM6DS_GYRO_ODR_6664,
}
# ── CONFIG_SCHEMA ─────────────────────────────────────────────────────────────
# Extend the motion platform schema which provides:
# - accel_x/y/z sensor schemas
# - gyro_x/y/z sensor schemas
# - axis_mapping schema + validation
# - update_interval / polling
CONFIG_SCHEMA = (
motion_schema(LSM6DSComponent, has_accel=True, has_gyro=True)
.extend(
{
cv.Optional(CONF_ACCELEROMETER_RANGE, default="4G"): cv.enum(
ACCEL_RANGE_OPTIONS, upper=True
),
cv.Optional(CONF_ACCELEROMETER_ODR, default="104HZ"): cv.enum(
ACCEL_ODR_OPTIONS, upper=True
),
cv.Optional(CONF_GYROSCOPE_RANGE, default="2000DPS"): cv.enum(
GYRO_RANGE_OPTIONS, upper=True
),
cv.Optional(CONF_GYROSCOPE_ODR, default="208HZ"): cv.enum(
GYRO_ODR_OPTIONS, upper=True
),
}
)
.extend(i2c.i2c_device_schema(0x6A))
)
# ── Code generation ──────────────────────────────────────────────────────────
async def to_code(config):
var = await new_motion_component(config)
# Let the motion platform handle sensor wiring, axis mapping, and polling
await i2c.register_i2c_device(var, config)
# Chip-specific hardware configuration
cg.add(var.set_accel_range(config[CONF_ACCELEROMETER_RANGE]))
cg.add(var.set_accel_odr(config[CONF_ACCELEROMETER_ODR]))
cg.add(var.set_gyro_range(config[CONF_GYROSCOPE_RANGE]))
cg.add(var.set_gyro_odr(config[CONF_GYROSCOPE_ODR]))

View File

@@ -0,0 +1,39 @@
# YAML config keys
import esphome.codegen as cg
from esphome.components import sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_TEMPERATURE,
CONF_TYPE,
DEVICE_CLASS_TEMPERATURE,
ICON_THERMOMETER,
STATE_CLASS_MEASUREMENT,
UNIT_CELSIUS,
)
from esphome.cpp_generator import MockObj
from . import CONF_LSM6DS_ID, LSM6DSComponent
CONFIG_SCHEMA = sensor.sensor_schema(
unit_of_measurement=UNIT_CELSIUS,
icon=ICON_THERMOMETER,
accuracy_decimals=2,
state_class=STATE_CLASS_MEASUREMENT,
device_class=DEVICE_CLASS_TEMPERATURE,
).extend(
{
cv.Optional(CONF_TYPE): CONF_TEMPERATURE,
cv.GenerateID(CONF_LSM6DS_ID): cv.use_id(LSM6DSComponent),
}
)
async def to_code(config):
var = await sensor.new_sensor(config)
parent = await cg.get_variable(config[CONF_LSM6DS_ID])
data = MockObj("data")
value_lambda = await cg.process_lambda(
var.publish_state(data),
[(cg.float_, str(data))],
)
cg.add(parent.add_temperature_listener(value_lambda))

View File

@@ -0,0 +1,63 @@
sensor:
- platform: lsm6ds
name: "lsm6ds Temperature"
- platform: motion
type: acceleration_x
name: "Accel X"
accuracy_decimals: 4
filters:
- sliding_window_moving_average:
window_size: 4
send_every: 1
- platform: motion
type: acceleration_y
name: "Accel Y"
accuracy_decimals: 4
- platform: motion
type: acceleration_z
name: "Accel Z"
accuracy_decimals: 4
# Gyroscope axes (unit: °/s)
- platform: motion
type: gyroscope_x
name: "Gyro X"
- platform: motion
type: gyroscope_y
name: "Gyro Y"
- platform: motion
type: gyroscope_z
name: "Gyro Z"
- platform: motion
type: angular_rate_x
name: "Angular Rate X"
- platform: motion
type: angular_rate_y
name: "Angular Rate Y"
- platform: motion
type: angular_rate_z
name: "Angular Rate Z"
- platform: motion
type: pitch
name: "Pitch"
- platform: motion
type: roll
name: "Roll"
motion:
- platform: lsm6ds
# Accelerometer full-scale range: 2G | 4G | 8G | 16G
accelerometer_range: 4G
accelerometer_odr: 104HZ
gyroscope_range: 2000DPS
gyroscope_odr: 208HZ
axis_map:
x: y
y: x
z: -z

View File

@@ -0,0 +1,4 @@
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
<<: !include common.yaml