[lsm6ds] Add LSM6DS component (LSM6DSOX/LSM6DS3TR-C)
This commit is contained in:
1 parent
4a18ef87d7
commit
b5dfd3b31f
5 files changed
+466
No files matched your search
@@ -0,0 +1,93 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c, spi
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
lsm6ds_ns,
|
||||||
|
LSM6DSComponent,
|
||||||
|
CONF_ACCEL_RANGE,
|
||||||
|
CONF_GYRO_RANGE,
|
||||||
|
CONF_ACCEL_ODR,
|
||||||
|
CONF_GYRO_ODR,
|
||||||
|
LSM6DS_ACCEL_RANGE_2G,
|
||||||
|
LSM6DS_ACCEL_RANGE_4G,
|
||||||
|
LSM6DS_ACCEL_RANGE_8G,
|
||||||
|
LSM6DS_ACCEL_RANGE_16G,
|
||||||
|
LSM6DS_GYRO_RANGE_125DPS,
|
||||||
|
LSM6DS_GYRO_RANGE_250DPS,
|
||||||
|
LSM6DS_GYRO_RANGE_500DPS,
|
||||||
|
LSM6DS_GYRO_RANGE_1000DPS,
|
||||||
|
LSM6DS_GYRO_RANGE_2000DPS,
|
||||||
|
LSM6DS_ACCEL_ODR_OFF,
|
||||||
|
LSM6DS_ACCEL_ODR_12_5HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_26HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_52HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_104HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_208HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_416HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_833HZ,
|
||||||
|
LSM6DS_ACCEL_ODR_1_66KHZ,
|
||||||
|
LSM6DS_ACCEL_ODR_3_33KHZ,
|
||||||
|
LSM6DS_ACCEL_ODR_6_66KHZ,
|
||||||
|
)
|
||||||
|
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
AUTO_LOAD = ["sensor"]
|
||||||
|
|
||||||
|
LSM6DSI2CDevice = lsm6ds_ns.class_("LSM6DSI2CDevice", LSM6DSComponent, i2c.I2CDevice)
|
||||||
|
|
||||||
|
ACCEL_RANGES = {
|
||||||
|
"2G": LSM6DS_ACCEL_RANGE_2G,
|
||||||
|
"4G": LSM6DS_ACCEL_RANGE_4G,
|
||||||
|
"8G": LSM6DS_ACCEL_RANGE_8G,
|
||||||
|
"16G": LSM6DS_ACCEL_RANGE_16G,
|
||||||
|
}
|
||||||
|
|
||||||
|
GYRO_RANGES = {
|
||||||
|
"125DPS": LSM6DS_GYRO_RANGE_125DPS,
|
||||||
|
"250DPS": LSM6DS_GYRO_RANGE_250DPS,
|
||||||
|
"500DPS": LSM6DS_GYRO_RANGE_500DPS,
|
||||||
|
"1000DPS": LSM6DS_GYRO_RANGE_1000DPS,
|
||||||
|
"2000DPS": LSM6DS_GYRO_RANGE_2000DPS,
|
||||||
|
}
|
||||||
|
|
||||||
|
ODRS = {
|
||||||
|
"0HZ": LSM6DS_ACCEL_ODR_OFF,
|
||||||
|
"12.5HZ": LSM6DS_ACCEL_ODR_12_5HZ,
|
||||||
|
"26HZ": LSM6DS_ACCEL_ODR_26HZ,
|
||||||
|
"52HZ": LSM6DS_ACCEL_ODR_52HZ,
|
||||||
|
"104HZ": LSM6DS_ACCEL_ODR_104HZ,
|
||||||
|
"208HZ": LSM6DS_ACCEL_ODR_208HZ,
|
||||||
|
"416HZ": LSM6DS_ACCEL_ODR_416HZ,
|
||||||
|
"833HZ": LSM6DS_ACCEL_ODR_833HZ,
|
||||||
|
"1.66KHZ": LSM6DS_ACCEL_ODR_1_66KHZ,
|
||||||
|
"3.33KHZ": LSM6DS_ACCEL_ODR_3_33KHZ,
|
||||||
|
"6.66KHZ": LSM6DS_ACCEL_ODR_6_66KHZ,
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_SCHEMA = cv.Schema({
|
||||||
|
cv.Optional(CONF_ACCEL_RANGE, default="2G"): cv.enum(ACCEL_RANGES, upper=True),
|
||||||
|
cv.Optional(CONF_GYRO_RANGE, default="250DPS"): cv.enum(GYRO_RANGES, upper=True),
|
||||||
|
cv.Optional(CONF_ACCEL_ODR, default="104HZ"): cv.enum(ODRS, upper=True),
|
||||||
|
cv.Optional(CONF_GYRO_ODR, default="104HZ"): cv.enum(ODRS, upper=True),
|
||||||
|
}).extend(cv.polling_component_schema("60s"))
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
|
cv.GenerateID(): cv.declare_id(LSM6DSI2CDevice),
|
||||||
|
}).extend(BASE_SCHEMA).extend(i2c.i2c_device_schema(None))
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
|
accel_range = ACCEL_RANGES[config[CONF_ACCEL_RANGE]]
|
||||||
|
gyro_range = GYRO_RANGES[config[CONF_GYRO_RANGE]]
|
||||||
|
accel_odr = ODRS[config[CONF_ACCEL_ODR]]
|
||||||
|
gyro_odr = ODRS[config[CONF_GYRO_ODR]]
|
||||||
|
|
||||||
|
cg.add(var.set_accel_range(accel_range))
|
||||||
|
cg.add(var.set_gyro_range(gyro_range))
|
||||||
|
cg.add(var.set_accel_odr(accel_odr))
|
||||||
|
cg.add(var.set_gyro_odr(gyro_odr))
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
# Registers
|
||||||
|
LSM6DS_WHO_AM_I = 0x0F
|
||||||
|
LSM6DS_CTRL1_XL = 0x10
|
||||||
|
LSM6DS_CTRL2_G = 0x11
|
||||||
|
LSM6DS_CTRL3_C = 0x12
|
||||||
|
LSM6DS_STATUS_REG = 0x1E
|
||||||
|
LSM6DS_OUT_TEMP_L = 0x20
|
||||||
|
LSM6DS_OUTX_L_G = 0x22
|
||||||
|
LSM6DS_OUTX_L_A = 0x28
|
||||||
|
|
||||||
|
# WHO_AM_I Values for different variants
|
||||||
|
LSM6DSOX_WHO_AM_I_VALUE = 0x6C
|
||||||
|
LSM6DS3TR_WHO_AM_I_VALUE = 0x6A
|
||||||
|
|
||||||
|
lsm6ds_ns = cg.esphome_ns.namespace("lsm6ds")
|
||||||
|
LSM6DSComponent = lsm6ds_ns.class_("LSM6DSComponent", cg.PollingComponent)
|
||||||
|
|
||||||
|
LSM6DSAccelRange = lsm6ds_ns.enum("LSM6DSAccelRange")
|
||||||
|
LSM6DS_ACCEL_RANGE_2G = LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_2G
|
||||||
|
LSM6DS_ACCEL_RANGE_16G = LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_16G
|
||||||
|
LSM6DS_ACCEL_RANGE_4G = LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_4G
|
||||||
|
LSM6DS_ACCEL_RANGE_8G = LSM6DSAccelRange.LSM6DS_ACCEL_RANGE_8G
|
||||||
|
|
||||||
|
LSM6DSGyroRange = lsm6ds_ns.enum("LSM6DSGyroRange")
|
||||||
|
LSM6DS_GYRO_RANGE_250DPS = LSM6DSGyroRange.LSM6DS_GYRO_RANGE_250DPS
|
||||||
|
LSM6DS_GYRO_RANGE_500DPS = LSM6DSGyroRange.LSM6DS_GYRO_RANGE_500DPS
|
||||||
|
LSM6DS_GYRO_RANGE_1000DPS = LSM6DSGyroRange.LSM6DS_GYRO_RANGE_1000DPS
|
||||||
|
LSM6DS_GYRO_RANGE_2000DPS = LSM6DSGyroRange.LSM6DS_GYRO_RANGE_2000DPS
|
||||||
|
LSM6DS_GYRO_RANGE_125DPS = LSM6DSGyroRange.LSM6DS_GYRO_RANGE_125DPS
|
||||||
|
|
||||||
|
LSM6DSODR = lsm6ds_ns.enum("LSM6DSODR")
|
||||||
|
LSM6DS_ACCEL_ODR_OFF = LSM6DSODR.LSM6DS_ODR_OFF
|
||||||
|
LSM6DS_ACCEL_ODR_12_5HZ = LSM6DSODR.LSM6DS_ODR_12_5HZ
|
||||||
|
LSM6DS_ACCEL_ODR_26HZ = LSM6DSODR.LSM6DS_ODR_26HZ
|
||||||
|
LSM6DS_ACCEL_ODR_52HZ = LSM6DSODR.LSM6DS_ODR_52HZ
|
||||||
|
LSM6DS_ACCEL_ODR_104HZ = LSM6DSODR.LSM6DS_ODR_104HZ
|
||||||
|
LSM6DS_ACCEL_ODR_208HZ = LSM6DSODR.LSM6DS_ODR_208HZ
|
||||||
|
LSM6DS_ACCEL_ODR_416HZ = LSM6DSODR.LSM6DS_ODR_416HZ
|
||||||
|
LSM6DS_ACCEL_ODR_833HZ = LSM6DSODR.LSM6DS_ODR_833HZ
|
||||||
|
LSM6DS_ACCEL_ODR_1_66KHZ = LSM6DSODR.LSM6DS_ODR_1_66KHZ
|
||||||
|
LSM6DS_ACCEL_ODR_3_33KHZ = LSM6DSODR.LSM6DS_ODR_3_33KHZ
|
||||||
|
LSM6DS_ACCEL_ODR_6_66KHZ = LSM6DSODR.LSM6DS_ODR_6_66KHZ
|
||||||
|
|
||||||
|
CONF_ACCEL_X = "accel_x"
|
||||||
|
CONF_ACCEL_Y = "accel_y"
|
||||||
|
CONF_ACCEL_Z = "accel_z"
|
||||||
|
CONF_GYRO_X = "gyro_x"
|
||||||
|
CONF_GYRO_Y = "gyro_y"
|
||||||
|
CONF_GYRO_Z = "gyro_z"
|
||||||
|
CONF_ACCEL_RANGE = "accel_range"
|
||||||
|
CONF_GYRO_RANGE = "gyro_range"
|
||||||
|
CONF_ACCEL_ODR = "accel_odr"
|
||||||
|
CONF_GYRO_ODR = "gyro_odr"
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
#include "lsm6ds.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace lsm6ds {
|
||||||
|
|
||||||
|
static const char *const TAG = "lsm6ds";
|
||||||
|
|
||||||
|
void LSM6DSComponent::setup() {
|
||||||
|
uint8_t who_am_i;
|
||||||
|
if (!this->read_register(0x0F, &who_am_i, 1)) {
|
||||||
|
this->mark_failed();
|
||||||
|
ESP_LOGE(TAG, "Communication failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (who_am_i == 0x6C) {
|
||||||
|
ESP_LOGI(TAG, "Detected LSM6DSOX");
|
||||||
|
} else if (who_am_i == 0x6A) {
|
||||||
|
ESP_LOGI(TAG, "Detected LSM6DS3TR-C");
|
||||||
|
} else {
|
||||||
|
this->mark_failed();
|
||||||
|
ESP_LOGE(TAG, "Unknown chip ID: 0x%02X", who_am_i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SW Reset
|
||||||
|
this->write_register(0x12, 0x01);
|
||||||
|
uint8_t ctrl3;
|
||||||
|
uint32_t start = millis();
|
||||||
|
do {
|
||||||
|
delay(10);
|
||||||
|
this->read_register(0x12, &ctrl3, 1);
|
||||||
|
} while ((ctrl3 & 0x01) && (millis() - start < 100));
|
||||||
|
|
||||||
|
if (ctrl3 & 0x01) {
|
||||||
|
ESP_LOGW(TAG, "SW Reset timed out");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable BDU (Block Data Update)
|
||||||
|
this->write_register(0x12, 0x40 | 0x04); // BDU=1, IF_INC=1
|
||||||
|
|
||||||
|
// Configure Accel
|
||||||
|
uint8_t ctrl1_xl = (this->accel_odr_ << 4) | (this->accel_range_ << 2);
|
||||||
|
this->write_register(0x10, ctrl1_xl);
|
||||||
|
|
||||||
|
switch (this->accel_range_) {
|
||||||
|
case LSM6DS_ACCEL_RANGE_2G: accel_sensitivity_ = 0.061e-3f; break;
|
||||||
|
case LSM6DS_ACCEL_RANGE_4G: accel_sensitivity_ = 0.122e-3f; break;
|
||||||
|
case LSM6DS_ACCEL_RANGE_8G: accel_sensitivity_ = 0.244e-3f; break;
|
||||||
|
case LSM6DS_ACCEL_RANGE_16G: accel_sensitivity_ = 0.488e-3f; break;
|
||||||
|
default: accel_sensitivity_ = 0; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure Gyro
|
||||||
|
uint8_t ctrl2_g = (this->gyro_odr_ << 4);
|
||||||
|
if (this->gyro_range_ == LSM6DS_GYRO_RANGE_125DPS) {
|
||||||
|
ctrl2_g |= 0x02; // FS_125 = 1
|
||||||
|
gyro_sensitivity_ = 4.375e-3f;
|
||||||
|
} else {
|
||||||
|
ctrl2_g |= (this->gyro_range_ << 2);
|
||||||
|
switch (this->gyro_range_) {
|
||||||
|
case LSM6DS_GYRO_RANGE_250DPS: gyro_sensitivity_ = 8.75e-3f; break;
|
||||||
|
case LSM6DS_GYRO_RANGE_500DPS: gyro_sensitivity_ = 17.50e-3f; break;
|
||||||
|
case LSM6DS_GYRO_RANGE_1000DPS: gyro_sensitivity_ = 35.0e-3f; break;
|
||||||
|
case LSM6DS_GYRO_RANGE_2000DPS: gyro_sensitivity_ = 70.0e-3f; break;
|
||||||
|
default: gyro_sensitivity_ = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->write_register(0x11, ctrl2_g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM6DSComponent::update() {
|
||||||
|
uint8_t status;
|
||||||
|
if (!this->read_register(0x1E, &status, 1)) return;
|
||||||
|
|
||||||
|
if (status & 0x01) { // GDA - Gyroscope data available
|
||||||
|
uint8_t data[6];
|
||||||
|
if (this->read_register(0x22, data, 6)) {
|
||||||
|
int16_t gx = encode_uint16(data[1], data[0]);
|
||||||
|
int16_t gy = encode_uint16(data[3], data[2]);
|
||||||
|
int16_t gz = encode_uint16(data[5], data[4]);
|
||||||
|
if (this->gyro_x_sensor_) this->gyro_x_sensor_->publish_state(gx * gyro_sensitivity_);
|
||||||
|
if (this->gyro_y_sensor_) this->gyro_y_sensor_->publish_state(gy * gyro_sensitivity_);
|
||||||
|
if (this->gyro_z_sensor_) this->gyro_z_sensor_->publish_state(gz * gyro_sensitivity_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & 0x02) { // XLDA - Accelerometer data available
|
||||||
|
uint8_t data[6];
|
||||||
|
if (this->read_register(0x28, data, 6)) {
|
||||||
|
int16_t ax = encode_uint16(data[1], data[0]);
|
||||||
|
int16_t ay = encode_uint16(data[3], data[2]);
|
||||||
|
int16_t az = encode_uint16(data[5], data[4]);
|
||||||
|
float grav = 9.80665f;
|
||||||
|
if (this->accel_x_sensor_) this->accel_x_sensor_->publish_state(ax * accel_sensitivity_ * grav);
|
||||||
|
if (this->accel_y_sensor_) this->accel_y_sensor_->publish_state(ay * accel_sensitivity_ * grav);
|
||||||
|
if (this->accel_z_sensor_) this->accel_z_sensor_->publish_state(az * accel_sensitivity_ * grav);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & 0x04) { // TDA - Temperature data available
|
||||||
|
uint8_t data[2];
|
||||||
|
if (this->read_register(0x20, data, 2)) {
|
||||||
|
int16_t temp = encode_uint16(data[1], data[0]);
|
||||||
|
if (this->temperature_sensor_) this->temperature_sensor_->publish_state(25.0f + (temp / 256.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LSM6DSComponent::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "LSM6DS (LSM6DSOX/LSM6DS3TR-C):");
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Connection failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_SENSOR(" ", "Accel X", this->accel_x_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Accel Y", this->accel_y_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Accel Z", this->accel_z_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Gyro X", this->gyro_x_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Gyro Y", this->gyro_y_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Gyro Z", this->gyro_z_sensor_);
|
||||||
|
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lsm6ds
|
||||||
|
} // namespace esphome
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
#ifdef USE_SPI
|
||||||
|
#include "esphome/components/spi/spi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace lsm6ds {
|
||||||
|
|
||||||
|
enum LSM6DSAccelRange {
|
||||||
|
LSM6DS_ACCEL_RANGE_2G = 0x00,
|
||||||
|
LSM6DS_ACCEL_RANGE_16G = 0x01,
|
||||||
|
LSM6DS_ACCEL_RANGE_4G = 0x02,
|
||||||
|
LSM6DS_ACCEL_RANGE_8G = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LSM6DSGyroRange {
|
||||||
|
LSM6DS_GYRO_RANGE_250DPS = 0x00,
|
||||||
|
LSM6DS_GYRO_RANGE_500DPS = 0x01,
|
||||||
|
LSM6DS_GYRO_RANGE_1000DPS = 0x02,
|
||||||
|
LSM6DS_GYRO_RANGE_2000DPS = 0x03,
|
||||||
|
LSM6DS_GYRO_RANGE_125DPS = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LSM6DSODR {
|
||||||
|
LSM6DS_ODR_OFF = 0x00,
|
||||||
|
LSM6DS_ODR_12_5HZ = 0x01,
|
||||||
|
LSM6DS_ODR_26HZ = 0x02,
|
||||||
|
LSM6DS_ODR_52HZ = 0x03,
|
||||||
|
LSM6DS_ODR_104HZ = 0x04,
|
||||||
|
LSM6DS_ODR_208HZ = 0x05,
|
||||||
|
LSM6DS_ODR_416HZ = 0x06,
|
||||||
|
LSM6DS_ODR_833HZ = 0x07,
|
||||||
|
LSM6DS_ODR_1_66KHZ = 0x08,
|
||||||
|
LSM6DS_ODR_3_33KHZ = 0x09,
|
||||||
|
LSM6DS_ODR_6_66KHZ = 0x0A,
|
||||||
|
};
|
||||||
|
|
||||||
|
class LSM6DSComponent : public PollingComponent {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
void update() override;
|
||||||
|
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||||
|
|
||||||
|
void set_accel_x_sensor(sensor::Sensor *accel_x) { accel_x_sensor_ = accel_x; }
|
||||||
|
void set_accel_y_sensor(sensor::Sensor *accel_y) { accel_y_sensor_ = accel_y; }
|
||||||
|
void set_accel_z_sensor(sensor::Sensor *accel_z) { accel_z_sensor_ = accel_z; }
|
||||||
|
void set_gyro_x_sensor(sensor::Sensor *gyro_x) { gyro_x_sensor_ = gyro_x; }
|
||||||
|
void set_gyro_y_sensor(sensor::Sensor *gyro_y) { gyro_y_sensor_ = gyro_y; }
|
||||||
|
void set_gyro_z_sensor(sensor::Sensor *gyro_z) { gyro_z_sensor_ = gyro_z; }
|
||||||
|
void set_temperature_sensor(sensor::Sensor *temp) { temperature_sensor_ = temp; }
|
||||||
|
|
||||||
|
void set_accel_range(LSM6DSAccelRange range) { accel_range_ = range; }
|
||||||
|
void set_gyro_range(LSM6DSGyroRange range) { gyro_range_ = range; }
|
||||||
|
void set_accel_odr(LSM6DSODR odr) { accel_odr_ = odr; }
|
||||||
|
void set_gyro_odr(LSM6DSODR odr) { gyro_odr_ = odr; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool read_register(uint8_t reg, uint8_t *data, size_t len) = 0;
|
||||||
|
virtual bool write_register(uint8_t reg, uint8_t data) = 0;
|
||||||
|
|
||||||
|
sensor::Sensor *accel_x_sensor_{nullptr};
|
||||||
|
sensor::Sensor *accel_y_sensor_{nullptr};
|
||||||
|
sensor::Sensor *accel_z_sensor_{nullptr};
|
||||||
|
sensor::Sensor *gyro_x_sensor_{nullptr};
|
||||||
|
sensor::Sensor *gyro_y_sensor_{nullptr};
|
||||||
|
sensor::Sensor *gyro_z_sensor_{nullptr};
|
||||||
|
sensor::Sensor *temperature_sensor_{nullptr};
|
||||||
|
|
||||||
|
LSM6DSAccelRange accel_range_;
|
||||||
|
LSM6DSGyroRange gyro_range_;
|
||||||
|
LSM6DSODR accel_odr_;
|
||||||
|
LSM6DSODR gyro_odr_;
|
||||||
|
|
||||||
|
float accel_sensitivity_;
|
||||||
|
float gyro_sensitivity_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LSM6DSI2CDevice : public LSM6DSComponent, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
bool read_register(uint8_t reg, uint8_t *data, size_t len) override {
|
||||||
|
return this->read_bytes(reg, data, len);
|
||||||
|
}
|
||||||
|
bool write_register(uint8_t reg, uint8_t data) override {
|
||||||
|
return this->write_byte(reg, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_SPI
|
||||||
|
class LSM6DSSPIDevice : public LSM6DSComponent, public spi::SPIDevice {
|
||||||
|
public:
|
||||||
|
bool read_register(uint8_t reg, uint8_t *data, size_t len) override {
|
||||||
|
this->enable();
|
||||||
|
this->transfer_byte(reg | 0x80);
|
||||||
|
this->transfer_bytes(nullptr, data, len);
|
||||||
|
this->disable();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool write_register(uint8_t reg, uint8_t data) override {
|
||||||
|
this->enable();
|
||||||
|
this->transfer_byte(reg & 0x7F);
|
||||||
|
this->transfer_byte(data);
|
||||||
|
this->disable();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace lsm6ds
|
||||||
|
} // namespace esphome
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import sensor
|
||||||
|
from esphome.const import (
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_METER_PER_SECOND_SQUARED,
|
||||||
|
UNIT_DEGREE_PER_SECOND,
|
||||||
|
UNIT_CELSIUS,
|
||||||
|
ICON_ACCELERATION,
|
||||||
|
ICON_THERMOMETER,
|
||||||
|
ICON_SCREEN_ROTATION,
|
||||||
|
CONF_ID,
|
||||||
|
)
|
||||||
|
from .const import (
|
||||||
|
CONF_ACCEL_X, CONF_ACCEL_Y, CONF_ACCEL_Z,
|
||||||
|
CONF_GYRO_X, CONF_GYRO_Y, CONF_GYRO_Z,
|
||||||
|
LSM6DSComponent,
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
|
cv.GenerateID(CONF_ID): cv.use_id(LSM6DSComponent),
|
||||||
|
cv.Optional(CONF_ACCEL_X): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_METER_PER_SECOND_SQUARED,
|
||||||
|
icon=ICON_ACCELERATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ACCEL_Y): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_METER_PER_SECOND_SQUARED,
|
||||||
|
icon=ICON_ACCELERATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ACCEL_Z): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_METER_PER_SECOND_SQUARED,
|
||||||
|
icon=ICON_ACCELERATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_GYRO_X): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_DEGREE_PER_SECOND,
|
||||||
|
icon=ICON_SCREEN_ROTATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_GYRO_Y): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_DEGREE_PER_SECOND,
|
||||||
|
icon=ICON_SCREEN_ROTATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_GYRO_Z): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_DEGREE_PER_SECOND,
|
||||||
|
icon=ICON_SCREEN_ROTATION,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional("temperature"): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_CELSIUS,
|
||||||
|
icon=ICON_THERMOMETER,
|
||||||
|
accuracy_decimals=1,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_ID])
|
||||||
|
|
||||||
|
for key in [CONF_ACCEL_X, CONF_ACCEL_Y, CONF_ACCEL_Z,
|
||||||
|
CONF_GYRO_X, CONF_GYRO_Y, CONF_GYRO_Z,
|
||||||
|
"temperature"]:
|
||||||
|
if key in config:
|
||||||
|
sens = await sensor.new_sensor(config[key])
|
||||||
|
cg.add(getattr(hub, f"set_{key}_sensor")(sens))
|
||||||
Reference in new issue
Block a user