Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow "CVL reset based on cell voltage diff" to operate independently of Linear or Step Mode #122

Open
BipedalPrimate opened this issue Dec 13, 2024 · 14 comments
Labels
enhancement New feature or request

Comments

@BipedalPrimate
Copy link

BipedalPrimate commented Dec 13, 2024

Is your feature request related to a problem? Please describe.

Am using Step Mode because Linear Mode takes >3 hours to switch to Absorption after first cell reaches Bulk Voltage (3.45v) in full sun - the 16 cells in battery module are not well matched.

As cell voltage increases, current is gradually reduced by CCCM_CV_ENABLE such that 0 amps is set at 3.48v - this prevents a significant overvoltage condition and significantly reduces time to Absorption compared to Linear Mode.

Consequently, am restricted to using a fixed absorption time (MAX_VOLTAGE_TIME_SEC = 7200) rather than a variable absorption time based on cell voltage difference.

Depending on length of time since last full charge and depth of discharge, time to achieve acceptable cell voltage difference in Absorption can vary between 15 minutes to 2 hours but averages about 30 minutes. This means holding Bulk Voltage for much longer than is needed.

Describe the solution you'd like

Allow "CVL reset based on cell voltage diff" to operate independently of Linear or Step Mode.

Perhaps with another Boolean CVCM_ALWAYS = TRUE (or CVCM_LINEAR = TRUE) to operate CVCM in Linear Mode but defaults to FALSE to not interfere with existing users use of CVCM

Describe alternatives you've considered

Have tried to use Linear Mode but for reasons described above, have found it to be sub-optimal.

Additional context

Linear & Step Mode is great for controlling adjustments to CVL & CCL but, IMO, its use has been extended beyond its original intent reducing the flexibility that users can make of the later enhancements.

@BipedalPrimate BipedalPrimate added the enhancement New feature or request label Dec 13, 2024
@mr-manuel
Copy link
Owner

If your battery is unbalanced and you don‘t want to wait for it to balance, you can increase CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL and CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_TIME_RESTART to a higher value like 1.000.

@BipedalPrimate
Copy link
Author

If your battery is unbalanced and you don‘t want to wait for it to balance

I actually do want to wait for the battery to balance.

The issue is the amount of time it takes to reach Absorption when using Linear Mode & that is why I use Step Mode.

However, using Step Mode forces a fixed Absorption time.

A variable Absorption time using "CVL reset based on cell voltage diff" would be the preferred option.

@mr-manuel
Copy link
Owner

Can you post your settings and a graph of min/max cell voltage for linear and step mode? So that I can see the difference you are talking about?

@BipedalPrimate
Copy link
Author

This is Linear Mode
Linear
Gold line is Max Cell V. Green line is Min Cell V. Orange line is CVL.

This is the Linear config.ini
config.linear.zip

This is Step Mode
Step
Again, Gold line is Max Cell V. Green line is Min Cell V. Orange line is CVL.

This is Step config.ini
config.step.zip

@mr-manuel
Copy link
Owner

Thanks, this is a bit more complex and will take much time to solve, since a lot of testing is needed. I have the same behavior and like also to solve that for the first graph.

You could help me to find out, why that hughe difference is happening. Probably the CVL reduction is too much.

@BipedalPrimate
Copy link
Author

According to config.ini:

penalty_sum-Method (CVL_ICONTROLLER_MODE = False)
The voltage-overshoot of all cells that exceed MAX_CELL_VOLTAGE is summed up and the control voltage is lowered by this "penalty_sum".

This screenshot is at a subset of time of the previous with slightly different measures:
image

The Purple & Gold lines are the 2 cells (2 & 16) that peak early and trigger the Penalty Sum Method, the Light Blue line is Average Cell Voltage, the Beige line is CVL and the Pink line is Min Cell Voltage.

Interestingly, when CVL is adjusted by Penalty Sum Method, it tends to closely follow the Average Cell Voltage.

At the time where the breakout measure is taken (11:24:15), Cell 2 is 3.461v and Cell 16 is 3.468v for a voltage overshoot of 0.029v (0.011v + 0.018v) suggesting CVL should be 3.45v-0.029v = 3.421v, yet it is shown as 3.998v.

From that point (and other points shown), as the voltage overshoot decreases, CVL also decreases which is not what one would expect.

In essence, it seems the Penalty Sum Method does not operate as described.

Even if that is resolved, there may be a case for a cell voltage level above which the Penalty Sum Method (or the ICONTROLLER_MODE) engages. Possibly MAX_CELL_VOLTAGE plus CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_TIME_RESTART as an option. An alternative is a separate value, say ENGAGE_LINEAR_MODE_CELL_VOLTAGE.

It should be noted that, to overcome these cells running too far ahead, I limit charge current as cell voltages increase via CCCM_CV:

CELL_VOLTAGES_WHILE_CHARGING      = 3.60, 3.59, 3.58, 3.57, 3.56, 3.55, 3.48, 3.47, 3.46, 3.45, 3.44, 3.43, 3.40
MAX_CHARGE_CURRENT_CV_FRACTION    =    0, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 1.00

which works quite well. Some experimentation for these values has occurred which is why there are values of 0A at voltage values above 3.48v.

@transistorgit
Copy link
Contributor

I haven't looked deeper into it, but at a first glance, it looks like an oscilating control problem. In terms of control theory, you have a p-controler with a control loop time of 1 minute. You can see the voltages spike in 1 minute intervalls, so I would guess your control loop is too slow for the fast voltage changes that you want to control. Maybe try with shorter loops, like 10 seconds, or smaler voltage steps. you can also think about introducing a PID-control lib. I use simple-PID with good success for controlling an outdoor water heating.

@transistorgit
Copy link
Contributor

for investigating, a shorter loop time would be an easy change to see if it's the right direction

@mr-manuel
Copy link
Owner

You can change that with this setting:

Set it to 10 or even 5 seconds.

@BipedalPrimate
Copy link
Author

Changed to 5 seconds with fewer resets to MAX_CELL_VOLTAGE but duration is similar.

Screenshot 2025-01-07 at 14-56-01 Daily Data - Grafana

You mentioned "Probably the CVL reduction is too much."

Looking at battery.py, am wondering if different calculation of control_voltage may improve CVL reduction.

control_voltage = round(
min(
max(
voltage_sum - penalty_sum,
self.min_battery_voltage,
),
self.max_battery_voltage,
),
6,
)

Replacing 786 voltage_sum - penalty_sum, with
self.max_battery_voltage - ((penalty_sum - utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL) * self.cell_count)

Currently, the starting point for CVL reduction appears to be the sum of the cell voltages (the current battery voltage) rather than the target battery voltage (max.battery_voltage) which is why it closely follows average cell voltage.

Also, by including CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL, there is a tolerance for overshoot of max cell voltage. Using the default CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL of 0.010v, a cell would be allowed to reach 3.46v (or 2 cells at 3.455v) before CVL is reduced.

CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL is included in the P-Controller for what may be a similar reason.

A perhaps simpler change would be to include CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL as follows:
voltage_sum - penalty_sum + utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL

What do you think?

@mr-manuel
Copy link
Owner

I tried now with control_voltage = self.max_battery_voltage - penalty_sum, but there is not really a change, except that the highest cell voltage goes 0.030 V over the MAX_CELL_VOLTAGE...

Additionally I have a very strange issue with my cells, that I never understood why that happens. Maybe does the balancer kick in too early (@ 3.400 V).

grafik

I made a lot of optimizations and changes in the todays nightly. Now I'm rewriting the part, where you can select a controller to calculate CVL. Probably I will push them later today or tomorrow for testing, since they will need a lot of testing.

@mr-manuel
Copy link
Owner

Just for testing and not completed at all: 78d567f

Any recommendations are very welcome.

@BipedalPrimate
Copy link
Author

BipedalPrimate commented Jan 9, 2025

Form what I understand, balancing should only start at the desired charge voltage - 3.5v in your case. The reason being is that prior to that point, the charge current is high and overwhelms any benefit of balancing, may increase cell imbalance at higher voltages (your cells 18 & 9 may show that) & may make balancing time longer than necessary.

Do you limit charge current based on cell voltage with CCCM_CV?

Have you tried setting start balance at 3.5v?

With respect to control_voltage = self.max_battery_voltage - penalty_sum, I am not surprised highest cell voltage overshot by 0.030v. Penalty_sum by itself would be not be enough to reduce CVL sufficiently - penalty_sum is a cell voltage overshoot measurement being subtracted from a desired battery voltage.

But 3.53v does not seem an excessive overshoot at CVL of 3.5v - still 120mv away from 3.65v maximum. It depends on what your tolerance is. In my case, I control charge current with CCCM_CV such that CCL is zero at a 30mv overshoot which seems to work quite well.

The intent of self.max_battery_voltage - ((penalty_sum - utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL) * self.cell_count) is to reduced CVL based on desired battery voltage less cell count * penalty_sum with some overshoot tolerance (utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL).

This is the result of self.max_battery_voltage - ((penalty_sum - utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL) * self.cell_count) in my installation:
image

Rather than immediately following Average Cell Voltage, CVL approaches Average Cell Voltage (with no rebounds back to 3.45v) as more cells exceed 3.45v then follows follows Average Cell Voltage.

Unfortunately, this calculation never really stabilises at 3.45v because there are too many cells (on average 8 cells) over 3.45v when Average Cell Voltage = 3.45v. Although I didn't let it run for a long time. It will be worse in your installation with 18 cells.

In an effort to achieve the desired outcome from the original enhancement request above, I changed battery.py to NOT adjust CVL in Linear Mode with this result:
image

For comparison, this is the current production Linear Mode shared earlier:
image

Time from first cell at 3.45v to Float has reduced from 2h 46m to 30m with 15m Absorption time in both. Less time has elapsed with cells over 3.45v having AH removed during balancing which seems to reduce those cells undershoot after Average Cell Voltage reaches 3.45v.

With regard to 78d567f, I think we are playing at the margins of potential improvements with added complexity. Based on other discussions & issues, it seems only you & I are finding this area problematic.

@mr-manuel
Copy link
Owner

Do you limit charge current based on cell voltage with CCCM_CV?

Yes

Have you tried setting start balance at 3.5v?

Not yet but soon. I tought 3.40 V is high enough, but will see the results soon.

I changed it now to control_voltage = voltage_sum - (penalty_sum * utils.CVL_CONTROLLER_KP) and switched CVL_CONTROLLER_KP to 0.99 so by default it has more or less the same effect, but can be changed by the user and one parameter.

With regard to 78d567f, I think we are playing at the margins of potential improvements with added complexity. Based on other discussions & issues, it seems only you & I are finding this area problematic.

I think the config file is now mucn more clear. Since the default config is the recommended for most systems, users which do not understand the setting should leave them as they are. :-) the most complex part is, if one wants to understand which controller to use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants