Add the LSM6DSO and use the LSM6DS3's own temperature sensitivity

This commit is contained in:
J. Nick Koston committed 2026-10-13 22:05:41 -10:00
1 parent 79e0ae448b
commit e1b6e5dc6e
2 files changed
+22 -13

No files matched your search

+8 -4
View File
@@ -29,10 +29,12 @@ static const LogString *gyro_range_to_str(LSM6DSGyroRange range) {
static const LogString *chip_name_from_who_am_i(uint8_t who_am_i) {
switch (who_am_i) {
case 0x69:
case LSM6DS_WHO_AM_I_LSM6DS3:
return LOG_STR("LSM6DS3");
case 0x6A:
case LSM6DS_WHO_AM_I_LSM6DS3TR_C:
return LOG_STR("LSM6DS3TR-C");
case LSM6DS_WHO_AM_I_LSM6DSO:
return LOG_STR("LSM6DSO");
default:
return nullptr;
}
@@ -54,6 +56,8 @@ void LSM6DSComponent::setup() {
}
ESP_LOGD(TAG, "Found %s (WHO_AM_I = 0x%02X)", LOG_STR_ARG(chip_name), who_am_i);
this->chip_name_ = chip_name;
if (who_am_i == LSM6DS_WHO_AM_I_LSM6DS3)
this->temperature_sensitivity_ = 16;
// 2. Software reset — clears all registers to defaults
if (this->write_register(LSM6DS_REG_CTRL3_C, &CTRL3_C_SW_RESET, 1) != i2c::ERROR_OK) {
@@ -185,12 +189,12 @@ bool LSM6DSComponent::update_data(motion::MotionData &data) {
// 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)
// Formula: T(°C) = raw / sensitivity + 25.0, sensitivity in LSB/°C per chip (0 LSB at 25 °C)
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;
float temperature = temp_raw / static_cast<float>(this->temperature_sensitivity_) + 25.0f;
this->temperature_callback_.call(temperature);
}
}
+14 -9
View File
@@ -9,15 +9,19 @@ 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
// WHO_AM_I values; the LSM6DS3 (DocID026899) and LSM6DSO (DS12140) use the same registers as the TR-C here
static const uint8_t LSM6DS_WHO_AM_I_LSM6DS3 = 0x69;
static const uint8_t LSM6DS_WHO_AM_I_LSM6DS3TR_C = 0x6A;
static const uint8_t LSM6DS_WHO_AM_I_LSM6DSO = 0x6C; // also the LSM6DSO32, whose accel ranges differ (unsupported)
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;
@@ -105,6 +109,7 @@ class LSM6DSComponent final : public motion::MotionComponent, public i2c::I2CDev
LSM6DSAccelODR accel_odr_{LSM6DS_ACCEL_ODR_104};
LSM6DSGyroRange gyro_range_{LSM6DS_GYRO_RANGE_2000};
LSM6DSGyroODR gyro_odr_{LSM6DS_GYRO_ODR_208};
uint16_t temperature_sensitivity_{256}; // LSB/°C: 16 on the LSM6DS3, 256 on the others
LazyCallbackManager<void(float)> temperature_callback_{};
};