n3roGit / DPVControl

Your DIY diving vehicle controlled by ESP32
GNU General Public License v3.0
4 stars 1 forks source link

[FEATURE] battery level #17

Closed n3roGit closed 7 months ago

n3roGit commented 7 months ago

`void updateBatteryLevel(float voltage) { if (voltage >= 5 && CellsInSeries >= 2) { float singleCellVoltages[] = {4.18, 4.1, 3.99, 3.85, 3.77, 3.58, 3.42, 3.33, 3.21, 3.00, 2.87}; int singleCellPercentages[] = {100, 96, 82, 68, 58, 34, 20, 14, 8, 2, 0};

for (int i = 0; i < sizeof(singleCellVoltages) / sizeof(singleCellVoltages[0]); i++) {
  if (voltage >= singleCellVoltages[i] * CellsInSeries) {
    // Interpolation
    if (i > 0) {
      float voltageRange = singleCellVoltages[i] * CellsInSeries - singleCellVoltages[i - 1] * CellsInSeries;
      int percentageRange = singleCellPercentages[i - 1] - singleCellPercentages[i];
      float voltageDifference = singleCellVoltages[i] * CellsInSeries - voltage;
      float interpolationFactor = voltageDifference / voltageRange;
      batteryLevel = singleCellPercentages[i] + interpolationFactor * percentageRange;
    } else {
      batteryLevel = singleCellPercentages[i];
    }
    break;
  }
}
// Ensure that the battery level is limited to the range [0, 100]
batteryLevel = constrain(batteryLevel, 0, 100);

} else { batteryLevel = 100; } int steps = (batteryLevel + 5) / LedBar2_Num; steps = constrain(steps, 0, LedBar2_Num - 1); setBarBattery(steps); }`

I currently see a few improvements here.

  1. make singleCellVoltages and singleCellPercentages into one table.
  2. always use the average of the last X values to calculate the battery level. this is necessary because the voltage can drop briefly during acceleration. this means that for a moment, for example, only 30% of the battery is displayed, although 80% is actually still available. Here I would work with a measurement over at least the last 60 seconds.
happyherp commented 7 months ago

Current code maps voltage to soc like this:

35.00V 0.00% SOC
35.50V 0.00% SOC
36.00V 0.00% SOC
36.50V 0.00% SOC
37.00V 0.00% SOC
37.50V 0.00% SOC
38.00V 0.00% SOC
38.50V 1.00% SOC
39.00V 2.00% SOC
39.50V 3.00% SOC
40.00V 4.00% SOC
40.50V 5.00% SOC
41.00V 6.00% SOC
41.50V 7.00% SOC
42.00V 9.00% SOC
42.50V 10.00% SOC
43.00V 12.00% SOC
43.50V 15.00% SOC
44.00V 17.00% SOC
44.50V 20.00% SOC
45.00V 23.00% SOC
45.50V 27.00% SOC
46.00V 30.00% SOC
46.50V 33.00% SOC
47.00V 38.00% SOC
47.50V 43.00% SOC
48.00V 48.00% SOC
48.50V 53.00% SOC
49.00V 57.00% SOC
49.50V 62.00% SOC
50.00V 67.00% SOC
50.50V 71.00% SOC

That looks correct to you? @n3roGit

n3roGit commented 7 months ago

the output looks correct

n3roGit commented 7 months ago

the calculation is as follows:

float singleCellVoltages[] = {4.18, 4.1, 3.99, 3.85, 3.77, 3.58, 3.42, 3.33, 3.21, 3.00, 2.87};
int singleCellPercentages[] = {100, 96, 82, 68, 58, 34, 20, 14, 8, 2, 0};

The following is calculated for a 13S battery:

40V / 13S = 3,08 -> between 8 and 2%

happyherp commented 7 months ago

7227eb48cd6741c98750ec1d691655b5093dafec has a refactored soc calculation, which still works the same. It also records voltage and uses the average to calculate soc.

n3roGit commented 7 months ago

implemented