ESPHome  2024.6.6
ina2xx_base.h
Go to the documentation of this file.
1 #pragma once
2 
5 
6 namespace esphome {
7 namespace ina2xx_base {
8 
9 enum RegisterMap : uint8_t {
10  REG_CONFIG = 0x00,
12  REG_SHUNT_CAL = 0x02,
14  REG_VSHUNT = 0x04,
15  REG_VBUS = 0x05,
16  REG_DIETEMP = 0x06,
17  REG_CURRENT = 0x07,
18  REG_POWER = 0x08,
19  REG_ENERGY = 0x09,
20  REG_CHARGE = 0x0A,
21  REG_DIAG_ALRT = 0x0B,
22  REG_SOVL = 0x0C,
23  REG_SUVL = 0x0D,
24  REG_BOVL = 0x0E,
25  REG_BUVL = 0x0F,
27  REG_PWR_LIMIT = 0x11,
30 };
31 
32 enum AdcRange : uint16_t {
35 };
36 
37 enum AdcTime : uint16_t {
46 };
47 
48 enum AdcAvgSamples : uint16_t {
57 };
58 
60  uint16_t raw_u16;
61  struct {
62  uint16_t reserved_0_3 : 4; // Reserved
63  AdcRange ADCRANGE : 1; // Shunt measurement range 0: ±163.84 mV, 1: ±40.96 mV
64  bool TEMPCOMP : 1; // Temperature compensation enable
65  uint16_t CONVDLY : 8; // Sets the Delay for initial ADC conversion in steps of 2 ms.
66  bool RSTACC : 1; // Reset counters
67  bool RST : 1; // Full device reset
68  } __attribute__((packed));
69 };
70 
72  uint16_t raw_u16;
73  struct {
75  AdcTime VTCT : 3; // Voltage conversion time
76  AdcTime VSHCT : 3; // Shunt voltage conversion time
77  AdcTime VBUSCT : 3; // Bus voltage conversion time
78  uint16_t MODE : 4;
79  } __attribute__((packed));
80 };
81 
83  uint16_t raw_u16;
84  struct {
85  uint16_t TEMPCO : 14;
86  uint16_t reserved : 2;
87  } __attribute__((packed));
88 };
89 
91  uint16_t raw_u16;
92  struct {
93  bool MEMSTAT : 1;
94  bool CNVRF : 1;
95  bool POL : 1;
96  bool BUSUL : 1;
97  bool BUSOL : 1;
98  bool SHNTUL : 1;
99  bool SHNTOL : 1;
100  bool TMPOL : 1;
101  bool RESERVED1 : 1;
102  bool MATHOF : 1;
103  bool CHARGEOF : 1;
104  bool ENERGYOF : 1;
105  bool APOL : 1;
106  bool SLOWALERT : 1;
107  bool CNVR : 1;
108  bool ALATCH : 1;
109  } __attribute__((packed));
110 };
111 
113 
114 class INA2XX : public PollingComponent {
115  public:
116  void setup() override;
117  float get_setup_priority() const override;
118  void update() override;
119  void loop() override;
120  void dump_config() override;
121 
122  void set_shunt_resistance_ohm(float shunt_resistance_ohm) { this->shunt_resistance_ohm_ = shunt_resistance_ohm; }
123  void set_max_current_a(float max_current_a) { this->max_current_a_ = max_current_a; }
124  void set_adc_range(uint8_t range) { this->adc_range_ = (range == 0) ? AdcRange::ADC_RANGE_0 : AdcRange::ADC_RANGE_1; }
125  void set_adc_time_bus_voltage(AdcTime time) { this->adc_time_bus_voltage_ = time; }
126  void set_adc_time_shunt_voltage(AdcTime time) { this->adc_time_shunt_voltage_ = time; }
127  void set_adc_time_die_temperature(AdcTime time) { this->adc_time_die_temperature_ = time; }
128  void set_adc_avg_samples(AdcAvgSamples samples) { this->adc_avg_samples_ = samples; }
129  void set_shunt_tempco(uint16_t coeff) { this->shunt_tempco_ppm_c_ = coeff; }
130 
131  void set_shunt_voltage_sensor(sensor::Sensor *sensor) { this->shunt_voltage_sensor_ = sensor; }
132  void set_bus_voltage_sensor(sensor::Sensor *sensor) { this->bus_voltage_sensor_ = sensor; }
133  void set_die_temperature_sensor(sensor::Sensor *sensor) { this->die_temperature_sensor_ = sensor; }
134  void set_current_sensor(sensor::Sensor *sensor) { this->current_sensor_ = sensor; }
135  void set_power_sensor(sensor::Sensor *sensor) { this->power_sensor_ = sensor; }
136  void set_energy_sensor_j(sensor::Sensor *sensor) { this->energy_sensor_j_ = sensor; }
137  void set_energy_sensor_wh(sensor::Sensor *sensor) { this->energy_sensor_wh_ = sensor; }
138  void set_charge_sensor_c(sensor::Sensor *sensor) { this->charge_sensor_c_ = sensor; }
139  void set_charge_sensor_ah(sensor::Sensor *sensor) { this->charge_sensor_ah_ = sensor; }
140 
141  void set_model(INAModel model) { this->ina_model_ = model; }
142 
143  bool reset_energy_counters();
144 
145  protected:
146  bool reset_config_();
147  bool check_device_model_();
148  bool configure_adc_();
149 
150  bool configure_shunt_();
151  bool configure_shunt_tempco_();
152  bool configure_adc_range_();
153 
154  bool read_shunt_voltage_mv_(float &volt_out);
155  bool read_bus_voltage_(float &volt_out);
156  bool read_die_temp_c_(float &temp);
157  bool read_current_a_(float &amps_out);
158  bool read_power_w_(float &power_out);
159  bool read_energy_(double &joules_out, double &watt_hours_out);
160  bool read_charge_(double &coulombs_out, double &amp_hours_out);
161 
162  bool read_diagnostics_and_act_();
163 
164  //
165  // User configuration
166  //
170  AdcTime adc_time_bus_voltage_{AdcTime::ADC_TIME_4120US};
171  AdcTime adc_time_shunt_voltage_{AdcTime::ADC_TIME_4120US};
172  AdcTime adc_time_die_temperature_{AdcTime::ADC_TIME_4120US};
174  uint16_t shunt_tempco_ppm_c_{0};
175 
176  //
177  // Calculated coefficients
178  //
179  uint16_t shunt_cal_{0};
180  float current_lsb_{0};
181 
182  uint32_t energy_overflows_count_{0};
183  uint32_t charge_overflows_count_{0};
184 
185  //
186  // Sensor objects
187  //
188  sensor::Sensor *shunt_voltage_sensor_{nullptr};
189  sensor::Sensor *bus_voltage_sensor_{nullptr};
190  sensor::Sensor *die_temperature_sensor_{nullptr};
191  sensor::Sensor *current_sensor_{nullptr};
192  sensor::Sensor *power_sensor_{nullptr};
193  sensor::Sensor *energy_sensor_j_{nullptr};
194  sensor::Sensor *energy_sensor_wh_{nullptr};
195  sensor::Sensor *charge_sensor_c_{nullptr};
196  sensor::Sensor *charge_sensor_ah_{nullptr};
197 
198  //
199  // FSM states
200  //
201  enum class State : uint8_t {
202  NOT_INITIALIZED = 0x0,
203  IDLE,
204  DATA_COLLECTION_1,
205  DATA_COLLECTION_2,
206  DATA_COLLECTION_3,
207  DATA_COLLECTION_4,
208  DATA_COLLECTION_5,
209  DATA_COLLECTION_6,
210  DATA_COLLECTION_7,
211  DATA_COLLECTION_8,
212  } state_{State::NOT_INITIALIZED};
213 
214  bool full_loop_is_okay_{true};
215 
216  //
217  // Device model
218  //
220  uint16_t dev_id_{0};
221  bool device_mismatch_{false};
222 
223  //
224  // Device specific parameters
225  //
226  struct {
227  float vbus_lsb;
233  float power_coeff;
235  } cfg_;
236 
237  //
238  // Register read/write
239  //
240  bool read_unsigned_(uint8_t reg, uint8_t reg_size, uint64_t &data_out);
241  bool read_unsigned_16_(uint8_t reg, uint16_t &out);
242  bool write_unsigned_16_(uint8_t reg, uint16_t val);
243 
244  int64_t two_complement_(uint64_t value, uint8_t bits);
245 
246  //
247  // Interface-specific implementation
248  //
249  virtual bool read_ina_register(uint8_t a_register, uint8_t *data, size_t len) = 0;
250  virtual bool write_ina_register(uint8_t a_register, const uint8_t *data, size_t len) = 0;
251 };
252 } // namespace ina2xx_base
253 } // namespace esphome
bool ENERGYOF
Definition: ina2xx_base.h:103
void setup()
void loop()
void set_model(INAModel model)
Definition: ina2xx_base.h:141
void set_charge_sensor_ah(sensor::Sensor *sensor)
Definition: ina2xx_base.h:139
void set_die_temperature_sensor(sensor::Sensor *sensor)
Definition: ina2xx_base.h:133
bool MATHOF
Definition: ina2xx_base.h:101
bool POL
Definition: ina2xx_base.h:94
bool MEMSTAT
Definition: ina2xx_base.h:92
bool BUSUL
Definition: ina2xx_base.h:95
mopeka_std_values val[4]
This class simplifies creating components that periodically check a state.
Definition: component.h:283
void set_adc_time_shunt_voltage(AdcTime time)
Definition: ina2xx_base.h:126
void set_shunt_tempco(uint16_t coeff)
Definition: ina2xx_base.h:129
AdcTime VTCT
Definition: ina2xx_base.h:74
AdcAvgSamples AVG
Definition: ina2xx_base.h:73
bool SLOWALERT
Definition: ina2xx_base.h:105
void set_adc_time_bus_voltage(AdcTime time)
Definition: ina2xx_base.h:125
void set_shunt_voltage_sensor(sensor::Sensor *sensor)
Definition: ina2xx_base.h:131
void set_adc_time_die_temperature(AdcTime time)
Definition: ina2xx_base.h:127
bool CNVR
Definition: ina2xx_base.h:106
bool BUSOL
Definition: ina2xx_base.h:96
bool TMPOL
Definition: ina2xx_base.h:99
bool RESERVED1
Definition: ina2xx_base.h:100
void set_adc_avg_samples(AdcAvgSamples samples)
Definition: ina2xx_base.h:128
bool SHNTUL
Definition: ina2xx_base.h:97
bool SHNTOL
Definition: ina2xx_base.h:98
bool APOL
Definition: ina2xx_base.h:104
struct esphome::ina2xx_base::ConfigurationRegister::@82 __attribute__((packed))
void set_max_current_a(float max_current_a)
Definition: ina2xx_base.h:123
void set_power_sensor(sensor::Sensor *sensor)
Definition: ina2xx_base.h:135
AdcTime VSHCT
Definition: ina2xx_base.h:75
std::string size_t len
Definition: helpers.h:292
void set_current_sensor(sensor::Sensor *sensor)
Definition: ina2xx_base.h:134
uint16_t TEMPCO
Definition: ina2xx_base.h:84
void set_charge_sensor_c(sensor::Sensor *sensor)
Definition: ina2xx_base.h:138
void set_shunt_resistance_ohm(float shunt_resistance_ohm)
Definition: ina2xx_base.h:122
void set_adc_range(uint8_t range)
Definition: ina2xx_base.h:124
bool CNVRF
Definition: ina2xx_base.h:93
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void set_energy_sensor_j(sensor::Sensor *sensor)
Definition: ina2xx_base.h:136
Base-class for all sensors.
Definition: sensor.h:57
void set_energy_sensor_wh(sensor::Sensor *sensor)
Definition: ina2xx_base.h:137
bool CHARGEOF
Definition: ina2xx_base.h:102
void set_bus_voltage_sensor(sensor::Sensor *sensor)
Definition: ina2xx_base.h:132
AdcTime VBUSCT
Definition: ina2xx_base.h:76