Sleeper85 / esphome-jk-bms-can

GNU General Public License v3.0
86 stars 23 forks source link

[Feature Request] AutoCVL Boost Charge Voltage #44

Closed luckylinux closed 2 months ago

luckylinux commented 6 months ago

I'd like to request / propose a new Feature (I can also consider coding this myself then do a PR if needed).

The Absorbtion voltage parameter is good for letting the cells balance out (55.2 VDC for a 16s LiFePo4 -> 3.45 VDC/cell), but it's not very good to ensure a rapid charge in CC "Constant Current" Mode (depending on System Cabling of course).

With my current (temporary) cabling of approx 10m length with 2x16mm2 in parallel for each polarity and each battery (2x16mm2 for DC+, 2x16mm2 for DC-), my charge current is approx. limited to 50ADC-60ADC.

Battery Voltage during Charge: approx. 54.0 VDC - 54.5 VDC

Inverter Voltage during Charge: approx. 55.2 VDC

Designed Charge Current: 100 ADC / each battery

Cable Resistance:

Plus voltage drop across breakers:

Plus all other voltage drops in the system.

Therefore the complete potential of the battery is never fully utilized.

In other terms:

Ibattery = (Uinverter - Ubattery) / (Rcabling + Rbreaker + Rterminals + Rfuses + ...) = (55.2 VDC - 54.5 VDC) / (0.01 Ohm + 0.0014 Ohm) = 61 ADC

Granted you can argue that this is due to temporary cabling, but the final 50mm2 will NOT be MUCH better than this equivalent 32mm2. And lengths will be similar.

I'd like therefore to propose a new operating mode on top of the existing ones (Wait, Float, Bulk, Balancing) called "Boost" (or whatever name we can set to it).

It will have all features of "bulk" (including Automatic Charge Voltage & Automatic Charge Current etc) and 2 configurable parameters:

In this way, the Bulk Voltage will take over in the upper end of the charge curve (CV - Constant Voltage, above the configurable parameter / state value of 80% in the example), while the Boost Voltage will take care of the lower part of the charge curve (CC - Constant Current, below the configurable parameter / state value of 80% in the example).

Ideas / Opinions ?

MrPabloUK commented 6 months ago

I'll be honest, I'm very wary of adding in this sort of logic. It'll add a fair bit of complexity and will rely on SOC being accurate (which we know is not the case for some users).

Instead, you could consider the PI functionality discussed in https://github.com/Sleeper85/esphome-jk-bms-can/issues/41.

As default, the Max CVL value that can be output is total bulk voltage. You could adjust this variable to reference a different value, perhaps 'total bulk voltage + 1.0'. The PI control should automatically reduce CVL as cells exceed bulk voltage, but it would require testing and I'm not sure it would be necessary for 99% of users.

Sleeper85 commented 6 months ago

So a Boost switch, a Boost voltage slider and a Boost end slider based on a SOC value of 80% by default?

MrPabloUK commented 6 months ago

@Sleeper85, @luckylinux, here is how the latest version of Auto Voltage Control (in testing) could meet these requirements.

https://github.com/Sleeper85/esphome-jk-bms-can/blob/1c0f196fb08b4ef73128cdc66c5c06688bf0745d/ESP32_LFP_Wire_jk-bms-can.yaml#L777

If max_CVL is set to id(bulk_voltage).state + 1.0; then the PI controller will automatically increase requested CVL to above the standard bulk voltage, as long as the max cell voltage is within limits. Once the max cell voltage starts to exceed cell_bulk_v + balance_delta then requested CVL will be reduced automatically, keeping max cell voltage near bulk voltage. This should allow users like @luckylinux to charge with maximum current, even with voltage drop issues, but prevent OVP issues as SOC approaches 100%.

It would be straightforward enough to have a substitution value instead of a fixed offset, for example:


Substitution:
charge_v_boost = 1.0;

Auto Charge Voltage Control:
max_CVL = id(bulk_voltage).state + ${charge_v_boost};
luckylinux commented 6 months ago

@Sleeper85, @luckylinux, here is how the latest version of Auto Voltage Control (in testing) could meet these requirements.

https://github.com/Sleeper85/esphome-jk-bms-can/blob/1c0f196fb08b4ef73128cdc66c5c06688bf0745d/ESP32_LFP_Wire_jk-bms-can.yaml#L777

If max_CVL is set to id(bulk_voltage).state + 1.0; then the PI controller will automatically increase requested CVL to above the standard bulk voltage, as long as the max cell voltage is within limits. Once the max cell voltage starts to exceed cell_bulk_v + balance_delta then requested CVL will be reduced automatically, keeping max cell voltage near bulk voltage. This should allow users like @luckylinux to charge with maximum current, even with voltage drop issues, but prevent OVP issues as SOC approaches 100%.

It would be straightforward enough to have a substitution value instead of a fixed offset, for example:

Substitution:
charge_v_boost = 1.0;

Auto Charge Voltage Control:
max_CVL = id(bulk_voltage).state + ${charge_v_boost};

Again, I did not think in that way, but I agree with @MrPabloUK, that this should be equivalent without the extra hassle of an extra mode to maintain and transition states in the state machine.

Why do I always think the most complex approach? :cry:

charge_v_boost in your example will effectively determine how long should charge be continued at Constant Current (CC).

As soon as one cell goes ABOVE bulk (3.45 VDC), the PI will saturate the output effectively to the current battery voltage, current ? And over a long period of time, bring all the cells up to bulk (3.45 VDC) while they balance themselves out.

MrPabloUK commented 6 months ago

Your approach made a lot of sense, it just happens that our effort to improve auto voltage can handle this case too. A nice example of leveraging one feature to do multiple things.

luckylinux commented 6 months ago

I still have some doubts about the speed of the PI controller, because in my view it needs to be FAST to REDUCE, while being slow to increase. And a PI controller, being linear, cannot do that.

Unless of course we want to add a slew-rate limiter on the charge_v_boost that gets added if the cell voltage is below 3.45 VDC.

Those are the things running in my head but I agree, we should put it to the test.

luckylinux commented 6 months ago

Just a note in case somebody wants to replicate the "boost" part.

The "dumb" (only monitored, NOT controlled by esphome-jk-bms-can) Battery 01 had its cells almost shooting up to OVP (by luck I took a look at it, when it was about to do it).

So just make you sure that if you do a "boost" you (manually) monitor the battery regularly, otherwise you might get nasty surprises ...

image

I really look forward to multiple BMS support :100:

Sleeper85 commented 2 months ago

@luckylinux

I think you could do this via script in HA directly ?

Simply change the value of the Bulk V. slider depending on the battery soc ?

luckylinux commented 2 months ago

@Sleeper85: probably so, not there yet. IIRC I managed to finally install Nodered after all the Permission Issues in Podman. But unfortunately other Priorities for the Time Being, so I "settled" on keeping 55.2 VDC / 55.3 VDC as Reference Voltage and live with the slow-ish Charging for now.

Sleeper85 commented 2 months ago

@luckylinux

I really look forward to multiple BMS support 💯

It is ready and tested by several people today. I think it can be published in the main branch (new git) soon.

YamBMS 1.4.1

Sleeper85 commented 2 months ago

@Sleeper85, @luckylinux, here is how the latest version of Auto Voltage Control (in testing) could meet these requirements.

https://github.com/Sleeper85/esphome-jk-bms-can/blob/1c0f196fb08b4ef73128cdc66c5c06688bf0745d/ESP32_LFP_Wire_jk-bms-can.yaml#L777

If max_CVL is set to id(bulk_voltage).state + 1.0; then the PI controller will automatically increase requested CVL to above the standard bulk voltage, as long as the max cell voltage is within limits. Once the max cell voltage starts to exceed cell_bulk_v + balance_delta then requested CVL will be reduced automatically, keeping max cell voltage near bulk voltage. This should allow users like @luckylinux to charge with maximum current, even with voltage drop issues, but prevent OVP issues as SOC approaches 100%.

It would be straightforward enough to have a substitution value instead of a fixed offset, for example:

Substitution:
charge_v_boost = 1.0;

Auto Charge Voltage Control:
max_CVL = id(bulk_voltage).state + ${charge_v_boost};

I'm putting this on the todo list.

@luckylinux

Tell me when you're ready to test it?

Sleeper85 commented 2 months ago

Implemented and under testing.