- Added temperature compensation for max charge current & power levels

This commit is contained in:
Michael Balzer 2017-11-08 20:01:28 +01:00
parent 7a136c9d2b
commit b9f6fefbec
3 changed files with 67 additions and 14 deletions

View file

@ -26,7 +26,7 @@
* *
*/ */
#define KLAUS_BMS_VERSION "V0.8.4 (2017-10-20)" #define KLAUS_BMS_VERSION "V0.9.0 (2017-11-08)"
#include <EEPROM.h> #include <EEPROM.h>
#include <util/crc16.h> #include <util/crc16.h>
@ -133,12 +133,19 @@ public:
// Configuration variables // Configuration variables
// //
// Maximum charge current to use [A]: // Maximum charge current to use [A]
// …at 20 °C & higher:
byte max_charge_current; byte max_charge_current;
// …at zero °C:
byte max_charge_current_0c;
// Maximum driving & recuperation power limits to use [W]: // Maximum driving & recuperation power limits to use [W]
// …at 20 °C & higher:
unsigned int max_drive_power; unsigned int max_drive_power;
unsigned int max_recup_power; unsigned int max_recup_power;
// …at zero °C:
unsigned int max_drive_power_0c;
unsigned int max_recup_power_0c;
// Drive power cutback [%]: // Drive power cutback [%]:
// (100% at FULL → 100% at <SOC1>% → <LVL2>% at <SOC2>% → 0% at EMPTY) // (100% at FULL → 100% at <SOC1>% → <LVL2>% at <SOC2>% → 0% at EMPTY)
@ -245,9 +252,14 @@ public:
max_charge_current = MAX_CHARGE_CURRENT; max_charge_current = MAX_CHARGE_CURRENT;
max_charge_current_0c = MAX_CHARGE_CURRENT_0C;
max_drive_power = MAX_DRIVE_POWER; max_drive_power = MAX_DRIVE_POWER;
max_recup_power = MAX_RECUP_POWER; max_recup_power = MAX_RECUP_POWER;
max_drive_power_0c = MAX_DRIVE_POWER_0C;
max_recup_power_0c = MAX_RECUP_POWER_0C;
drv_cutback_soc1 = DRV_CUTBACK_SOC1; drv_cutback_soc1 = DRV_CUTBACK_SOC1;
drv_cutback_soc2 = DRV_CUTBACK_SOC2; drv_cutback_soc2 = DRV_CUTBACK_SOC2;
drv_cutback_lvl2 = DRV_CUTBACK_LVL2; drv_cutback_lvl2 = DRV_CUTBACK_LVL2;
@ -1048,6 +1060,17 @@ public:
recpwr /= 2; recpwr /= 2;
chgcur = min(chgcur, 5); chgcur = min(chgcur, 5);
} }
else if (min(temp_f, temp_r) < 20) {
// reduce power levels linear by temperature:
float dt = 20 - min(temp_f, temp_r);
float dy;
dy = (max_drive_power - max_drive_power_0c) / 20;
drvpwr -= dt * dy;
dy = (max_recup_power - max_recup_power_0c) / 20;
recpwr -= dt * dy;
dy = (max_charge_current - max_charge_current_0c) / 20;
chgcur -= dt * dy;
}
#endif // CALIBRATION_MODE #endif // CALIBRATION_MODE
@ -1150,6 +1173,12 @@ public:
max_charge_current = constrain(atoi(arg), 5, 35); max_charge_current = constrain(atoi(arg), 5, 35);
} }
} }
else if (strcasecmp(cmd, "mcc0") == 0) {
// mcc0 <cur>
if (arg = strtok(NULL, " ")) {
max_charge_current_0c = constrain(atoi(arg), 5, 35);
}
}
else if (strcasecmp(cmd, "sc") == 0) { else if (strcasecmp(cmd, "sc") == 0) {
// sc [<prc>] // sc [<prc>]
@ -1162,7 +1191,7 @@ public:
} }
else if (strcasecmp(cmd, "mpw") == 0) { else if (strcasecmp(cmd, "mpw") == 0) {
// mpw <drv> <rec> // mpw <drv> <rec> <drv0c> <rec0c>
if (arg = strtok(NULL, " ")) { if (arg = strtok(NULL, " ")) {
max_drive_power = constrain(atoi(arg), 500, 30000); max_drive_power = constrain(atoi(arg), 500, 30000);
} }
@ -1170,6 +1199,15 @@ public:
max_recup_power = constrain(atoi(arg), 500, 30000); max_recup_power = constrain(atoi(arg), 500, 30000);
} }
} }
else if (strcasecmp(cmd, "mpw0") == 0) {
// mpw0 <drv> <rec>
if (arg = strtok(NULL, " ")) {
max_drive_power_0c = constrain(atoi(arg), 500, 30000);
}
if (arg = strtok(NULL, " ")) {
max_recup_power_0c = constrain(atoi(arg), 500, 30000);
}
}
else if (strcasecmp(cmd, "dcb") == 0) { else if (strcasecmp(cmd, "dcb") == 0) {
// dcb <soc1> <soc2> <lvl2> // dcb <soc1> <soc2> <lvl2>
@ -1249,9 +1287,11 @@ public:
s->println(F("HELP:\r\n" s->println(F("HELP:\r\n"
" soh <prc> -- set SOH%\r\n" " soh <prc> -- set SOH%\r\n"
" soc <prc> -- set SOC%\r\n" " soc <prc> -- set SOC%\r\n"
" mcc <cur> -- set max charge current\r\n" " mcc <cur> -- set max charge current @ 20°C\r\n"
" mcc0 <cur> -- set max charge current @ 0°C\r\n"
" sc [<prc>] -- stop charge / set stop SOC\r\n" " sc [<prc>] -- stop charge / set stop SOC\r\n"
" mpw <drv> <rec> -- set max power\r\n" " mpw <drv> <rec> -- set max power @ 20°C\r\n"
" mpw0 <drv> <rec> -- set max power @ 0°C\r\n"
" dcb <soc1> <soc2> <lvl2> -- set drive cutback\r\n" " dcb <soc1> <soc2> <lvl2> -- set drive cutback\r\n"
" vrd <min> <max> -- set voltage range discharging\r\n" " vrd <min> <max> -- set voltage range discharging\r\n"
" vrc <min> <max> -- set voltage range charging\r\n" " vrc <min> <max> -- set voltage range charging\r\n"
@ -1279,9 +1319,12 @@ public:
s->println(); s->println();
s->print(F("- MCC = ")); s->println(max_charge_current); s->print(F("- MCC = ")); s->println(max_charge_current);
s->print(F("- MCC0 = ")); s->println(max_charge_current_0c);
s->print(F("- SC = ")); s->println(chg_stop_soc); s->print(F("- SC = ")); s->println(chg_stop_soc);
s->print(F("- MPW = ")); s->print(max_drive_power); s->print(F("- MPW = ")); s->print(max_drive_power);
s->print(' '); s->println(max_recup_power); s->print(' '); s->println(max_recup_power);
s->print(F("- MPW0 = ")); s->print(max_drive_power_0c);
s->print(' '); s->println(max_recup_power_0c);
s->print(F("- DCB = ")); s->print(drv_cutback_soc1); s->print(F("- DCB = ")); s->print(drv_cutback_soc1);
s->print(' '); s->print(drv_cutback_soc2); s->print(' '); s->print(drv_cutback_soc2);
s->print(' '); s->println(drv_cutback_lvl2); s->print(' '); s->println(drv_cutback_lvl2);

View file

@ -49,8 +49,12 @@
// OPERATION // OPERATION
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Maximum charge current to use [A] (5…35): // Maximum charge current to use [A] (5…35)
#define MAX_CHARGE_CURRENT 35 // …at 20 °C and higher:
#define MAX_CHARGE_CURRENT 35
// …at 0 °C:
#define MAX_CHARGE_CURRENT_0C 20
// Charge current → power drawn from socket: // Charge current → power drawn from socket:
// 35 A = 2,2 kW // 35 A = 2,2 kW
// 30 A = 2,1 kW // 30 A = 2,1 kW
@ -60,9 +64,13 @@
// 10 A = 0,7 kW // 10 A = 0,7 kW
// 5 A = 0,4 kW // 5 A = 0,4 kW
// Maximum driving & recuperation power limits to use [W] (500…30000): // Maximum driving & recuperation power limits to use [W] (500…30000)
#define MAX_DRIVE_POWER 25000 // …at 20 °C and higher:
#define MAX_RECUP_POWER 12500 #define MAX_DRIVE_POWER 25000
#define MAX_RECUP_POWER 12500
// …at 0 °C:
#define MAX_DRIVE_POWER_0C 16000
#define MAX_RECUP_POWER_0C 6000
// Drive power cutback [%]: // Drive power cutback [%]:

View file

@ -97,9 +97,11 @@ After sending any command, the KlausBMS will respond with the current configurat
| --- | --- | | --- | --- |
| `soh <prc>` | set SOH% | | `soh <prc>` | set SOH% |
| `soc <prc>` | set SOC% | | `soc <prc>` | set SOC% |
| `mcc <cur>` | set max charge current | | `mcc <cur>` | set max charge current at 20 °C |
| `mcc0 <cur>` | set max charge current at 0 °C |
| `sc [<prc>]` | stop charge / set charge stop SOC | | `sc [<prc>]` | stop charge / set charge stop SOC |
| `mpw <drv> <rec>` | set max power | | `mpw <drv> <rec>` | set max power at 20 °C |
| `mpw0 <drv> <rec>` | set max power at 0 °C |
| `dcb <soc1> <soc2> <lvl2>` | set drive cutback | | `dcb <soc1> <soc2> <lvl2>` | set drive cutback |
| `vrd <min> <max>` | set voltage range discharging | | `vrd <min> <max>` | set voltage range discharging |
| `vrc <min> <max>` | set voltage range charging | | `vrc <min> <max>` | set voltage range charging |