esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
420 stars 26 forks source link

Support for power monitor INA228/229 #2549

Closed taHC81 closed 5 months ago

taHC81 commented 10 months ago

Describe the problem you have/What new integration you would like

Would it be possible to add INA228 (I2C) and INA229 (SPI) power monitoring chips? There're already some INAs supported, but these 2 are often used for battery management.

Please describe your use case for this integration and alternatives you've tried:

Battery voltage/current/power/SoC monitoring.

Additional context

taHC81 commented 10 months ago

https://www.ti.com/document-viewer/ina228/datasheet

latonita commented 10 months ago

@taHC81 I can take a look into this - I have no device, so I will need your help to test/debug

taHC81 commented 10 months ago

@taHC81 I can take a look into this - I have no device, so I will need your help to test/debug

With a pleasure, I have 3 devices ;) There are some configuration registers, so would be nice to have them accessible with input numbers.

latonita commented 10 months ago

@taHC81 try this one https://github.com/latonita/esphome-ina228 if it works at all. its i2c version

taHC81 commented 10 months ago

Tried that, had to comment out TAG read part in a component setup (https://github.com/taHC81/esphome-ina228/blob/f05410bf26457f0036598b09aa1ad7a122a0b3a5/components/ina228/ina228.cpp#L59), then it started working. Unfortunately, waiting for a bigger shunt (75mV / 400A), so can't provide some real numbers.

https://pastebin.com/B3pvi3eV

[08:48:22][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.24000 V with 2 decimals of accuracy
[08:48:22][D][sensor:094]: 'INA228 Bus Voltage': Sending state 0.00000 V with 2 decimals of accuracy
[08:48:22][D][sensor:094]: 'INA228 Current': Sending state 0.00000 A with 3 decimals of accuracy
[08:48:22][D][sensor:094]: 'INA228 Power': Sending state 0.00000 W with 2 decimals of accuracy
[08:48:24][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.24000 V with 2 decimals of accuracy
[08:48:24][D][sensor:094]: 'INA228 Bus Voltage': Sending state 0.05000 V with 2 decimals of accuracy
[08:48:24][D][sensor:094]: 'INA228 Current': Sending state 0.00078 A with 3 decimals of accuracy
[08:48:24][D][sensor:094]: 'INA228 Power': Sending state 0.00000 W with 2 decimals of accuracy
[08:48:26][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.24000 V with 2 decimals of accuracy
[08:48:26][D][sensor:094]: 'INA228 Bus Voltage': Sending state 0.05000 V with 2 decimals of accuracy
[08:48:26][D][sensor:094]: 'INA228 Current': Sending state 0.00078 A with 3 decimals of accuracy
[08:48:26][D][sensor:094]: 'INA228 Power': Sending state 0.00000 W with 2 decimals of accuracy
[08:48:28][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.24000 V with 2 decimals of accuracy
latonita commented 10 months ago

good, i actually supposed this might fail with some of the clones and forgot to make it just an informational/warning message

please check whether data is good - i hope byte order is okay

btw, do you own SPI versions of this device? then I can split this driver to base/i2c/spi

taHC81 commented 10 months ago

No, just I2C INA228, not INA229. But they should be completely same (registers) except the interface.

Die temp is not measured and energy/charge are "bit" off as well :) Capture

Have some inspiration here - https://github.com/stuartpittaway/diyBMS-CurrentShunt/tree/master/Code/diybmsCurrentShunt/src

latonita commented 10 months ago

what are the 'expected' values, approximately?

taHC81 commented 10 months ago

I've connected 3.3V on a Vbus, with no shunt connected = zero current, zero power, and I get:

Bus voltage: 849.20V Current: 1658.594A Power: 0.02W

Temperature still reported as unknown.

latonita commented 10 months ago

@taHC81 can you please send me output of these lines

ESP_LOGI(TAG, "New Rshunt=%f ohm, max current=%.3f", r_shunt, max_current); ESP_LOGI(TAG, "New CURRENT_LSB=%f, SHUNT_CAL=%u", this->currentlsb, this->shuntcal);

taHC81 commented 10 months ago

Edit: not visible via API log, just using Serial.

[10:03:34][I][ina228:057]: Manufacturer: 0x5449, Device ID: 0x2281
[10:03:34][I][ina228:080]: New Rshunt=0.000188 ohm, max current=400.000
[10:03:34][I][ina228:081]: New CURRENT_LSB=0.000381, SHUNT_CAL=937
latonita commented 10 months ago

@taHC81 i updated the code, added debug output. please enable DEBUG level logging and put output to the pastebin. thanks make sure you compile new version, sometimes it caches old one.

logger:
  level: DEBUG
taHC81 commented 10 months ago

@taHC81 i updated the code, added debug output. please enable DEBUG level logging and put output to the pastebin. thanks make sure you compile new version, sometimes it caches old one.

logger:
  level: DEBUG

Here it is - https://pastebin.com/E4rkNWKF

latonita commented 10 months ago

try one more time please + share logs. thanks

taHC81 commented 10 months ago

Charge and energy look better, voltage still zero when I connect 3.3V

[13:41:39][D][ina228:031]: read_s20_4_ 0x04, ret= 0, raw 0x00A00000
[13:41:39][D][ina228:116]: read_volt_shunt_ is TRUE, 0x00000000
[13:41:39][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.00000 V with 2 decimals of accuracy
[13:41:39][D][ina228:031]: read_s20_4_ 0x05, ret= 0, raw 0x00100000
[13:41:39][D][ina228:125]: read_voltage_ is TRUE, 0x00000000
[13:41:39][D][sensor:094]: 'INA228 Bus Voltage': Sending state 0.00000 V with 2 decimals of accuracy
[13:41:39][D][ina228:031]: read_s20_4_ 0x05, ret= 0, raw 0x00100000
[13:41:39][D][ina228:143]: read_voltage_ is TRUE, 0x00000000
[13:41:39][D][sensor:094]: 'INA228 Current': Sending state 0.00000 A with 3 decimals of accuracy
[13:41:39][D][ina228:152]: read_power_1 ret= 0, 0x00000000
[13:41:39][D][ina228:155]: read_power_2 ret= 0, 0x00000000
[13:41:39][D][sensor:094]: 'INA228 Power': Sending state 0.00000 W with 2 decimals of accuracy
[13:41:39][D][ina228:164]: read_energy_1 ret= 0, 0xFFFFA00000
[13:41:39][D][ina228:167]: read_energy_2 ret= 0, 0xA0FFFF
[13:41:39][D][sensor:094]: 'INA228 Energy': Sending state 206079.98438 J with 2 decimals of accuracy
[13:41:39][D][ina228:176]: read_charge_1 is TRUE, 0xFFFFA00000
[13:41:39][D][ina228:181]: read_charge_2 is TRUE, 0xA0FFFF
[13:41:39][D][sensor:094]: 'INA228 Charge': Sending state 4024.99951 C with 2 decimals of accuracy
latonita commented 10 months ago

please share full log when it works for few minutes. thanks.

taHC81 commented 10 months ago

Ok, in a meantime, quick serial output from the same HW with Arduino code and Adafruit library.

13:54:51.320 -> Current: 0.06 mA
13:54:51.320 -> Bus Voltage: 3316.02 mV
13:54:51.320 -> Shunt Voltage: 0.01 mV
13:54:51.320 -> Power: 0.23 mW
13:54:51.320 -> Energy: 0.00 J
13:54:51.320 -> Temperature: 24.09 *C
13:54:51.320 -> 
13:54:52.318 -> Current: 0.06 mA
13:54:52.318 -> Bus Voltage: 3315.63 mV
13:54:52.318 -> Shunt Voltage: 0.01 mV
taHC81 commented 10 months ago

https://pastebin.com/pF6FwmPq

latonita commented 10 months ago

one more try plz :)

taHC81 commented 10 months ago

one more try plz :)

Unfortunately, still the same. https://pastebin.com/ZNrRwfgi

latonita commented 10 months ago

okay, minor changes uploaded

what is strange is that for the voltages we receive data like 0x000001 or 0x00003 ..... which is odd

latonita commented 10 months ago

maybe initialization is not enough, i will check other libs how do they initialize the device

taHC81 commented 10 months ago

Looks better now! Shunt will arrive tomorrow, so I'll provide another data. Capture

latonita commented 10 months ago

@taHC81 sounds promising. please include full log when you have new shunt

latonita commented 10 months ago

@taHC81 another minor update

taHC81 commented 9 months ago

Even better, Anton! Thanks a lot! After I get the shunt, will do some preliminary tests. Capture

taHC81 commented 9 months ago

Some crazy numbers with connected 0.001 ohm shunt - no current through it, just Vbus = 3.3V Capture

taHC81 commented 9 months ago

1A current +-

[ina228:029]: read_s20_4_ 0x07, ret= 0, raw 0x00D00CFD
[ina228:140]: read_voltage_ is TRUE, 0xFFEFD0CD
[sensor:094]: 'INA228 Current': Sending state -101.15233 A with 5 decimals of accuracy

1A current -+

[ina228:029]: read_s20_4_ 0x07, ret= 0, raw 0x0060EF02
[ina228:140]: read_voltage_ is TRUE, 0x00002EF6
[sensor:094]: 'INA228 Current': Sending state 1.14651 A with 5 decimals of accuracy

Going to tweak shunt value to calibrate it. Maybe you can make a shunt resistance as an input number for easier calibration. Thanks.

taHC81 commented 9 months ago

After calibration:

[ina228:029]: read_s20_4_ 0x07, ret= 0, raw 0x00308F02
[ina228:140]: read_voltage_ is TRUE, 0x000028F3
[sensor:094]: 'INA228 Current': Sending state 0.99974 A with 5 decimals of accuracy

[ina228:029]: read_s20_4_ 0x07, ret= 0, raw 0x00606FFD
[ina228:140]: read_voltage_ is TRUE, 0xFFEFD6F6
[sensor:094]: 'INA228 Current': Sending state -101.00193 A with 5 decimals of accuracy
latonita commented 9 months ago

hi. some updates posted.

I would be happy to see full logs +if possible, your manual multimeter readings of Vbus, Vshunt, Rshunt and current

thanks!

taHC81 commented 9 months ago

Hello, here's the log - https://pastebin.com/ydERZ675

Please note the adc_range: 0 returns correct data, while I'd expect it from "1". I have 2x 10R filter resistors and 100nF cap.

10V, 99mA, 0.99W reported by a bench power supply. Charge and Energy are cleared only on a power cycle.

latonita commented 9 months ago

1) so you say in adc_range 0 data is good, but in adc_range 1 it is wrong. maybe 4 times smaller/bigger? 2) I added some code with debug output to check whether wring to registers works okay 3) looks like some defaults values contradict datasheets... need to double check new logs with your electrical values i expect v shunt to be 0.00113 ohm* 99ma = 0.11187 mV which is exactly 4 times bigger than the reading

try and i need full log again plz. and i will need to recheck all the nanos and millis :)

it would be great if you can do two runs. one with adc range 0 and another with 1

taHC81 commented 9 months ago

Thanks, now with adc_range = 1 - https://pastebin.com/L63Y12N3

taHC81 commented 9 months ago

Strange behavior - on a first power on it measure half current and power, after restart (re-upload same code) starts measuring correctly.

https://pastebin.com/1nmGVV5i

latonita commented 9 months ago

@taHC81 thanks for your tests

not clear about todays results - as for yesterdays - unfortunately old software got cached.

would you please somehow reset caches and build from scratch. i would be happy to see logs for adc_range = 0 and adc_range = 1. i hope this time its getting closer and closer to what we all need )))

latonita commented 9 months ago

one more thing. i see you are connecting to devices via network is it possible to get connected via serial? its missing setup() part of logs which are written before network is initialized for adc 0 and adc 1 thanks

taHC81 commented 9 months ago

I'm playing also with some other ESP32's, and C3 has integrated USB interface, it drops connection during restart... Here it is, logger via serial port.

adc: 0 - https://pastebin.com/e3U7LB2B adc: 1 - https://pastebin.com/MKm264kE

latonita commented 9 months ago

thanks! i found an issue with device reset. you may try new one. meanwhile i will start reworking this component to split into i2c and spi + i think its easy to add support for ina238/239 and ina237

taHC81 commented 9 months ago

Hello, some warning during compilation, but overall looks good - https://pastebin.com/M5wsseUu

In file included from src/esphome.h:21,
                 from src/main.cpp:3:
src/esphome\components\ina228\ina228.h:62:10: note: offset of packed bit-field 'esphome::ina228::ConfigurationRegister::<unnamed struct>::CONVDLY' has changed in GCC 4.4
   struct {
          ^
src/esphome\components\ina228\ina228.h:74:10: note: offset of packed bit-field 'esphome::ina228::AdcConfigurationRegister::<unnamed struct>::VSHCT' has changed in GCC 4.4
   struct {
          ^
latonita commented 9 months ago

please check updated version. supporting ina228, ina238, ina237 note, that it has a new name

external_components:
  source: github://latonita/esphome-ina228
  components: [ina2xx_base, ina2xx_i2c]

I would appreciate full log from serial. as well as your real electrical params and readings, thanks

taHC81 commented 9 months ago

Hello, some strange numbers this time - https://pastebin.com/nLj6vwgt , still same 10V/0.1A/1W.

latonita commented 9 months ago

Hello, some strange numbers this time - https://pastebin.com/nLj6vwgt , still same 10V/0.1A/1W.

Ouch, stupid copy-paste-typo. fixed, please check and send logs thanks

latonita commented 9 months ago

also here is documentation i prepared. I would be happy if you can take a look. maybe some mistakes, unclear things, etc. https://deploy-preview-3571--esphome.netlify.app/components/sensor/ina2xx

taHC81 commented 9 months ago

Hello, some strange numbers this time - https://pastebin.com/nLj6vwgt , still same 10V/0.1A/1W.

Ouch, stupid copy-paste-typo. fixed, please check and send logs thanks

Yep, now it's ok. https://pastebin.com/HxM5ijH9

taHC81 commented 9 months ago

also here is documentation i prepared. I would be happy if you can take a look. maybe some mistakes, unclear things, etc. https://deploy-preview-3571--esphome.netlify.app/components/sensor/ina2xx

Looks good, no obvious errors. Would you consider to add more human-friendly sensors like power/energy in mAh/Ah/Wh/kWh?

latonita commented 9 months ago

also here is documentation i prepared. I would be happy if you can take a look. maybe some mistakes, unclear things, etc. https://deploy-preview-3571--esphome.netlify.app/components/sensor/ina2xx

Looks good, no obvious errors. Would you consider to add more human-friendly sensors like power/energy in mAh/Ah/Wh/kWh?

Good idea. I have added Ah and Wh. energy and charge in Ah and Wh now, as its closer to real life humans :) two new sensors are energy_joules and charge_coulombs. docs updates as well please try

taHC81 commented 9 months ago

Probably you have to forgot to push the changes, still see the Joules and Couloumbs. I did the esphome cleanup...

[13:49:32][D][ina2xx:052]: Initiating new data collection
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x04, ret=OK, len=3, val=0x5900
[13:49:32][D][ina2xx:341]: read_shunt_voltage_mv_ ret=OK, shunt_cal=4440, reading_lsb=1424.000000
[13:49:32][D][sensor:094]: 'INA228 Shunt Voltage': Sending state 0.11125 mV with 5 decimals of accuracy
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x05, ret=OK, len=3, val=0xC6A30
[13:49:32][D][ina2xx:362]: read_bus_voltage_ ret=OK, reading_lsb=50851.000000
[13:49:32][D][sensor:094]: 'INA228 Bus Voltage': Sending state 9.93184 V with 5 decimals of accuracy
[13:49:32][D][ina2xx:510]: read_unsigned_16_ 0x06, ret= OK, val=0x0BB5
[13:49:32][D][ina2xx:382]: read_die_temp_c_ ret=OK, reading_lsb=2997.000000
[13:49:32][D][sensor:094]: 'INA228 DIE Temperature': Sending state 23.41406 °C with 5 decimals of accuracy
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x07, ret=OK, len=3, val=0x5340
[13:49:32][D][ina2xx:398]: read_current_a_ ret=OK. current_lsb=0.000076. reading_lsb=1332.000000
[13:49:32][D][sensor:094]: 'INA228 Current': Sending state 0.10162 A with 8 decimals of accuracy
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x08, ret=OK, len=3, val=0x1004
[13:49:32][D][ina2xx:412]: read_power_w_ ret=OK, reading_lsb=4100
[13:49:32][D][sensor:094]: 'INA228 Power': Sending state 1.00098 W with 6 decimals of accuracy
[13:49:32][D][ina2xx:510]: read_unsigned_16_ 0x0B, ret= OK, val=0x0003
[13:49:32][D][ina2xx:468]: read_diagnostics_and_act_ ret=OK, 0x0003
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x09, ret=OK, len=5, val=0x4B
[13:49:32][D][ina2xx:432]: read_energy_j_ ret=OK, reading_lsb=0x4B, current_lsb=0.000076, overflow_cnt=0
[13:49:32][D][sensor:094]: 'INA228 Energy': Sending state 0.29297 J with 8 decimals of accuracy
[13:49:32][D][ina2xx:501]: read_unsigned_ reg=0x0A, ret=OK, len=5, val=0x1AA
[13:49:32][D][ina2xx:454]: read_charge_c_ ret=1, curr_charge=426.000000 + 39-bit overflow_cnt=0
[13:49:32][D][sensor:094]: 'INA228 Charge': Sending state 0.03250 C with 8 decimals of accuracy
latonita commented 9 months ago

@taHC81 my bad, i pushed it to main PR only, but not into latonita ina228 repository. fixed

taHC81 commented 9 months ago

Perfect, I think we're close to the end :) https://pastebin.com/UGm0j1hG ina228

latonita commented 9 months ago

@taHC81 can you please test negative current.

Basically Charge/discharge cycle

P. S. Vbus shall stay almost positive as per datasheet