diff --git a/esphome/components/ina2xx_base/__init__.py b/esphome/components/ina2xx_base/__init__.py index 35b5baa83e..429988c8ed 100644 --- a/esphome/components/ina2xx_base/__init__.py +++ b/esphome/components/ina2xx_base/__init__.py @@ -30,6 +30,7 @@ CODEOWNERS = ["@latonita"] CONF_ADC_AVERAGING = "adc_averaging" CONF_ADC_RANGE = "adc_range" CONF_ADC_TIME = "adc_time" +CONF_BUS_VOLTAGE_OVER_LIMIT = "bus_voltage_over_limit" CONF_CHARGE = "charge" CONF_CHARGE_COULOMBS = "charge_coulombs" CONF_ENERGY_JOULES = "energy_joules" @@ -90,6 +91,11 @@ def validate_model_config(config): f"Device model '{model}' does not support temperature coefficient" ) + if config.get(CONF_BUS_VOLTAGE_OVER_LIMIT) and model not in ["INA228", "INA229"]: + raise cv.Invalid( + f"Device model '{model}' does not support bus voltage over limit" + ) + return config @@ -193,6 +199,9 @@ INA2XX_SCHEMA = cv.Schema( ), key=CONF_NAME, ), + cv.Optional(CONF_BUS_VOLTAGE_OVER_LIMIT): cv.All( + cv.voltage, cv.Range(min=0.0, max=0x7FFF * 3.125 / 1000) + ), } ).extend(cv.polling_component_schema("60s")) @@ -253,3 +262,6 @@ async def setup_ina2xx(var, config): if conf := config.get(CONF_CHARGE_COULOMBS): sens = await sensor.new_sensor(conf) cg.add(var.set_charge_sensor_c(sens)) + + if conf := config.get(CONF_BUS_VOLTAGE_OVER_LIMIT): + cg.add(var.set_bus_voltage_over_limit_v(conf)) diff --git a/esphome/components/ina2xx_base/ina2xx_base.cpp b/esphome/components/ina2xx_base/ina2xx_base.cpp index 924bf91e5e..aa909f650b 100644 --- a/esphome/components/ina2xx_base/ina2xx_base.cpp +++ b/esphome/components/ina2xx_base/ina2xx_base.cpp @@ -78,6 +78,9 @@ void INA2XX::setup() { this->configure_shunt_tempco_(); delay(1); + this->configure_bus_voltage_over_limit_(); + delay(1); + this->state_ = State::IDLE; } @@ -212,6 +215,7 @@ void INA2XX::dump_config() { ESP_LOGCONFIG(TAG, " ADCRANGE = %d (%s)", (uint8_t) this->adc_range_, this->adc_range_ ? "±40.96 mV" : "±163.84 mV"); ESP_LOGCONFIG(TAG, " CURRENT_LSB = %f", this->current_lsb_); ESP_LOGCONFIG(TAG, " SHUNT_CAL = %d", this->shunt_cal_); + ESP_LOGCONFIG(TAG, " BUS_VOLTAGE_OVER_LIMIT = %f V", this->bus_voltage_over_limit_v_); ESP_LOGCONFIG(TAG, " ADC Samples = %d; ADC times: Bus = %d μs, Shunt = %d μs, Temp = %d μs", ADC_SAMPLES[0b111 & (uint8_t) this->adc_avg_samples_], @@ -374,6 +378,15 @@ bool INA2XX::configure_shunt_tempco_() { return true; } +bool INA2XX::configure_bus_voltage_over_limit_() { + // Only for 228/229 + if ((this->ina_model_ == INAModel::INA_228 || this->ina_model_ == INAModel::INA_229) && + this->bus_voltage_over_limit_v_ > 0) { + return this->write_unsigned_16_(RegisterMap::REG_BOVL, (uint16_t) (this->bus_voltage_over_limit_v_ * 1000 / 3.125)); + } + return true; +} + bool INA2XX::read_shunt_voltage_mv_(float &volt_out) { // Two's complement value // 228, 229 - 24bit: 20(23-4) + 4(3-0) res diff --git a/esphome/components/ina2xx_base/ina2xx_base.h b/esphome/components/ina2xx_base/ina2xx_base.h index 261c5321bf..1e0153a845 100644 --- a/esphome/components/ina2xx_base/ina2xx_base.h +++ b/esphome/components/ina2xx_base/ina2xx_base.h @@ -127,6 +127,7 @@ class INA2XX : public PollingComponent { void set_adc_time_die_temperature(AdcTime time) { this->adc_time_die_temperature_ = time; } void set_adc_avg_samples(AdcAvgSamples samples) { this->adc_avg_samples_ = samples; } void set_shunt_tempco(uint16_t coeff) { this->shunt_tempco_ppm_c_ = coeff; } + void set_bus_voltage_over_limit_v(float limit_v) { this->bus_voltage_over_limit_v_ = limit_v; } void set_shunt_voltage_sensor(sensor::Sensor *sensor) { this->shunt_voltage_sensor_ = sensor; } void set_bus_voltage_sensor(sensor::Sensor *sensor) { this->bus_voltage_sensor_ = sensor; } @@ -150,6 +151,7 @@ class INA2XX : public PollingComponent { bool configure_shunt_(); bool configure_shunt_tempco_(); bool configure_adc_range_(); + bool configure_bus_voltage_over_limit_(); bool read_shunt_voltage_mv_(float &volt_out); bool read_bus_voltage_(float &volt_out); @@ -172,6 +174,7 @@ class INA2XX : public PollingComponent { AdcTime adc_time_die_temperature_{AdcTime::ADC_TIME_4120US}; AdcAvgSamples adc_avg_samples_{AdcAvgSamples::ADC_AVG_SAMPLES_128}; uint16_t shunt_tempco_ppm_c_{0}; + float bus_voltage_over_limit_v_; // // Calculated coefficients