diff --git a/esphome/components/mlx90393/sensor.py b/esphome/components/mlx90393/sensor.py index fe01d8ebfc..a455b32113 100644 --- a/esphome/components/mlx90393/sensor.py +++ b/esphome/components/mlx90393/sensor.py @@ -1,20 +1,20 @@ +from esphome import pins import esphome.codegen as cg -import esphome.config_validation as cv from esphome.components import i2c, sensor +import esphome.config_validation as cv from esphome.const import ( + CONF_FILTER, + CONF_GAIN, CONF_ID, - UNIT_MICROTESLA, - UNIT_CELSIUS, - STATE_CLASS_MEASUREMENT, + CONF_OVERSAMPLING, + CONF_RESOLUTION, + CONF_TEMPERATURE, ICON_MAGNET, ICON_THERMOMETER, - CONF_GAIN, - CONF_RESOLUTION, - CONF_OVERSAMPLING, - CONF_FILTER, - CONF_TEMPERATURE, + STATE_CLASS_MEASUREMENT, + UNIT_CELSIUS, + UNIT_MICROTESLA, ) -from esphome import pins CODEOWNERS = ["@functionpointer"] DEPENDENCIES = ["i2c"] @@ -26,30 +26,47 @@ MLX90393Component = mlx90393_ns.class_( ) GAIN = { - "1X": 7, - "1_33X": 6, - "1_67X": 5, - "2X": 4, - "2_5X": 3, - "3X": 2, - "4X": 1, - "5X": 0, + "1X": 0, + "1_25X": 1, + "1_67X": 2, + "2X": 3, + "2_5X": 4, + "3X": 5, + "3_75X": 6, + "5X": 7, } RESOLUTION = { - "16BIT": 0, - "17BIT": 1, - "18BIT": 2, - "19BIT": 3, + "DIV_8": 3, + "DIV_4": 2, + "DIV_2": 1, + "DIV_1": 0, } CONF_X_AXIS = "x_axis" CONF_Y_AXIS = "y_axis" CONF_Z_AXIS = "z_axis" CONF_DRDY_PIN = "drdy_pin" +CONF_TEMPERATURE_COMPENSATION = "temperature_compensation" +CONF_HALLCONF = "hallconf" -def mlx90393_axis_schema(default_resolution: str): +def _validate(config): + if config[CONF_TEMPERATURE_COMPENSATION]: + for axis in [CONF_X_AXIS, CONF_Y_AXIS, CONF_Z_AXIS]: + if axis not in config: + continue + if (res := config[axis][CONF_RESOLUTION]) in [ + "DIV_8", + "DIV_4", + ]: + raise cv.Invalid( + f"{axis}: {CONF_RESOLUTION} cannot be {res} with {CONF_TEMPERATURE_COMPENSATION} enabled" + ) + return config + + +def mlx90393_axis_schema(): return sensor.sensor_schema( unit_of_measurement=UNIT_MICROTESLA, accuracy_decimals=0, @@ -58,7 +75,7 @@ def mlx90393_axis_schema(default_resolution: str): ).extend( cv.Schema( { - cv.Optional(CONF_RESOLUTION, default=default_resolution): cv.enum( + cv.Optional(CONF_RESOLUTION, default="DIV_8"): cv.enum( RESOLUTION, upper=True, space="_" ) } @@ -66,19 +83,19 @@ def mlx90393_axis_schema(default_resolution: str): ) -CONFIG_SCHEMA = ( +CONFIG_SCHEMA = cv.All( cv.Schema( { cv.GenerateID(): cv.declare_id(MLX90393Component), - cv.Optional(CONF_GAIN, default="2_5X"): cv.enum( - GAIN, upper=True, space="_" - ), + cv.Optional(CONF_GAIN, default="1X"): cv.enum(GAIN, upper=True, space="_"), cv.Optional(CONF_DRDY_PIN): pins.gpio_input_pin_schema, - cv.Optional(CONF_OVERSAMPLING, default=2): cv.int_range(min=0, max=3), + cv.Optional(CONF_OVERSAMPLING, default=0): cv.int_range(min=0, max=3), cv.Optional(CONF_FILTER, default=6): cv.int_range(min=0, max=7), - cv.Optional(CONF_X_AXIS): mlx90393_axis_schema("19BIT"), - cv.Optional(CONF_Y_AXIS): mlx90393_axis_schema("19BIT"), - cv.Optional(CONF_Z_AXIS): mlx90393_axis_schema("16BIT"), + cv.Optional(CONF_X_AXIS): mlx90393_axis_schema(), + cv.Optional(CONF_Y_AXIS): mlx90393_axis_schema(), + cv.Optional(CONF_Z_AXIS): mlx90393_axis_schema(), + cv.Optional(CONF_TEMPERATURE_COMPENSATION, default=False): bool, + cv.Optional(CONF_HALLCONF, default=0xC): cv.one_of(0xC, 0x0), cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( unit_of_measurement=UNIT_CELSIUS, accuracy_decimals=1, @@ -96,7 +113,8 @@ CONFIG_SCHEMA = ( }, ) .extend(cv.polling_component_schema("60s")) - .extend(i2c.i2c_device_schema(0x0C)) + .extend(i2c.i2c_device_schema(0x0C)), + _validate, ) diff --git a/esphome/components/mlx90393/sensor_mlx90393.cpp b/esphome/components/mlx90393/sensor_mlx90393.cpp index d4431a7334..e86080fe9c 100644 --- a/esphome/components/mlx90393/sensor_mlx90393.cpp +++ b/esphome/components/mlx90393/sensor_mlx90393.cpp @@ -43,6 +43,10 @@ void MLX90393Cls::setup() { this->mlx_.setDigitalFiltering(this->filter_); this->mlx_.setTemperatureOverSampling(this->temperature_oversampling_); + + this->mlx_.setTemperatureCompensation(this->temperature_compensation_); + + this->mlx_.setHallConf(this->hallconf_); } void MLX90393Cls::dump_config() { diff --git a/esphome/components/mlx90393/sensor_mlx90393.h b/esphome/components/mlx90393/sensor_mlx90393.h index 8dfb7e6a13..11eb849d59 100644 --- a/esphome/components/mlx90393/sensor_mlx90393.h +++ b/esphome/components/mlx90393/sensor_mlx90393.h @@ -29,7 +29,10 @@ class MLX90393Cls : public PollingComponent, public i2c::I2CDevice, public MLX90 void set_resolution(uint8_t xyz, uint8_t res) { resolutions_[xyz] = res; } void set_filter(uint8_t filter) { filter_ = filter; } void set_gain(uint8_t gain_sel) { gain_ = gain_sel; } - + void set_temperature_compensation(bool temperature_compensation) { + temperature_compensation_ = temperature_compensation; + } + void set_hallconf(uint8_t hallconf) { hallconf_ = hallconf; } // overrides for MLX library // disable lint because it keeps suggesting const uint8_t *response. @@ -52,6 +55,8 @@ class MLX90393Cls : public PollingComponent, public i2c::I2CDevice, public MLX90 uint8_t temperature_oversampling_ = 0; uint8_t filter_; uint8_t resolutions_[3] = {0}; + bool temperature_compensation_ = false; + uint8_t hallconf_ = 0xC; GPIOPin *drdy_pin_{nullptr}; }; diff --git a/tests/components/mlx90393/test.esp32-ard.yaml b/tests/components/mlx90393/test.esp32-ard.yaml index 089fd136f4..4ee8cae737 100644 --- a/tests/components/mlx90393/test.esp32-ard.yaml +++ b/tests/components/mlx90393/test.esp32-ard.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2 diff --git a/tests/components/mlx90393/test.esp32-c3-ard.yaml b/tests/components/mlx90393/test.esp32-c3-ard.yaml index 549eea8032..597ecd2b8c 100644 --- a/tests/components/mlx90393/test.esp32-c3-ard.yaml +++ b/tests/components/mlx90393/test.esp32-c3-ard.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2 diff --git a/tests/components/mlx90393/test.esp32-c3-idf.yaml b/tests/components/mlx90393/test.esp32-c3-idf.yaml index 549eea8032..597ecd2b8c 100644 --- a/tests/components/mlx90393/test.esp32-c3-idf.yaml +++ b/tests/components/mlx90393/test.esp32-c3-idf.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2 diff --git a/tests/components/mlx90393/test.esp32-idf.yaml b/tests/components/mlx90393/test.esp32-idf.yaml index 089fd136f4..4ee8cae737 100644 --- a/tests/components/mlx90393/test.esp32-idf.yaml +++ b/tests/components/mlx90393/test.esp32-idf.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2 diff --git a/tests/components/mlx90393/test.esp32-s3-ard.yaml b/tests/components/mlx90393/test.esp32-s3-ard.yaml new file mode 100644 index 0000000000..597ecd2b8c --- /dev/null +++ b/tests/components/mlx90393/test.esp32-s3-ard.yaml @@ -0,0 +1,23 @@ +i2c: + - id: i2c_mlx90393 + scl: 5 + sda: 4 + +sensor: + - platform: mlx90393 + oversampling: 1 + filter: 0 + gain: 1X + temperature_compensation: true + x_axis: + name: mlxxaxis + resolution: DIV_2 + y_axis: + name: mlxyaxis + resolution: DIV_1 + z_axis: + name: mlxzaxis + resolution: DIV_2 + temperature: + name: mlxtemp + oversampling: 2 diff --git a/tests/components/mlx90393/test.esp32-s3-idf.yaml b/tests/components/mlx90393/test.esp32-s3-idf.yaml new file mode 100644 index 0000000000..597ecd2b8c --- /dev/null +++ b/tests/components/mlx90393/test.esp32-s3-idf.yaml @@ -0,0 +1,23 @@ +i2c: + - id: i2c_mlx90393 + scl: 5 + sda: 4 + +sensor: + - platform: mlx90393 + oversampling: 1 + filter: 0 + gain: 1X + temperature_compensation: true + x_axis: + name: mlxxaxis + resolution: DIV_2 + y_axis: + name: mlxyaxis + resolution: DIV_1 + z_axis: + name: mlxzaxis + resolution: DIV_2 + temperature: + name: mlxtemp + oversampling: 2 diff --git a/tests/components/mlx90393/test.esp8266-ard.yaml b/tests/components/mlx90393/test.esp8266-ard.yaml index 549eea8032..597ecd2b8c 100644 --- a/tests/components/mlx90393/test.esp8266-ard.yaml +++ b/tests/components/mlx90393/test.esp8266-ard.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2 diff --git a/tests/components/mlx90393/test.rp2040-ard.yaml b/tests/components/mlx90393/test.rp2040-ard.yaml index 549eea8032..597ecd2b8c 100644 --- a/tests/components/mlx90393/test.rp2040-ard.yaml +++ b/tests/components/mlx90393/test.rp2040-ard.yaml @@ -7,14 +7,17 @@ sensor: - platform: mlx90393 oversampling: 1 filter: 0 - gain: 3X + gain: 1X + temperature_compensation: true x_axis: name: mlxxaxis + resolution: DIV_2 y_axis: name: mlxyaxis + resolution: DIV_1 z_axis: name: mlxzaxis - resolution: 17BIT + resolution: DIV_2 temperature: name: mlxtemp oversampling: 2