diff --git a/KlausBMS.ino b/KlausBMS.ino index 1913a5b..26d2e8f 100644 --- a/KlausBMS.ino +++ b/KlausBMS.ino @@ -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 #include @@ -133,12 +133,19 @@ public: // Configuration variables // - // Maximum charge current to use [A]: + // Maximum charge current to use [A] + // …at 20 °C & higher: 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_recup_power; + // …at zero °C: + unsigned int max_drive_power_0c; + unsigned int max_recup_power_0c; // Drive power cutback [%]: // (100% at FULL → 100% at % → % at % → 0% at EMPTY) @@ -244,10 +251,15 @@ public: // Configuration variables: max_charge_current = MAX_CHARGE_CURRENT; - + + max_charge_current_0c = MAX_CHARGE_CURRENT_0C; + max_drive_power = MAX_DRIVE_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_soc2 = DRV_CUTBACK_SOC2; drv_cutback_lvl2 = DRV_CUTBACK_LVL2; @@ -1048,6 +1060,17 @@ public: recpwr /= 2; 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 @@ -1150,6 +1173,12 @@ public: max_charge_current = constrain(atoi(arg), 5, 35); } } + else if (strcasecmp(cmd, "mcc0") == 0) { + // mcc0 + if (arg = strtok(NULL, " ")) { + max_charge_current_0c = constrain(atoi(arg), 5, 35); + } + } else if (strcasecmp(cmd, "sc") == 0) { // sc [] @@ -1162,7 +1191,7 @@ public: } else if (strcasecmp(cmd, "mpw") == 0) { - // mpw + // mpw if (arg = strtok(NULL, " ")) { max_drive_power = constrain(atoi(arg), 500, 30000); } @@ -1170,6 +1199,15 @@ public: max_recup_power = constrain(atoi(arg), 500, 30000); } } + else if (strcasecmp(cmd, "mpw0") == 0) { + // mpw0 + 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) { // dcb @@ -1249,9 +1287,11 @@ public: s->println(F("HELP:\r\n" " soh -- set SOH%\r\n" " soc -- set SOC%\r\n" - " mcc -- set max charge current\r\n" + " mcc -- set max charge current @ 20°C\r\n" + " mcc0 -- set max charge current @ 0°C\r\n" " sc [] -- stop charge / set stop SOC\r\n" - " mpw -- set max power\r\n" + " mpw -- set max power @ 20°C\r\n" + " mpw0 -- set max power @ 0°C\r\n" " dcb -- set drive cutback\r\n" " vrd -- set voltage range discharging\r\n" " vrc -- set voltage range charging\r\n" @@ -1279,9 +1319,12 @@ public: s->println(); 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("- MPW = ")); s->print(max_drive_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(' '); s->print(drv_cutback_soc2); s->print(' '); s->println(drv_cutback_lvl2); diff --git a/KlausBMS_config.h b/KlausBMS_config.h index 282a936..c393b1a 100644 --- a/KlausBMS_config.h +++ b/KlausBMS_config.h @@ -49,8 +49,12 @@ // OPERATION // -------------------------------------------------------------------------- -// Maximum charge current to use [A] (5…35): -#define MAX_CHARGE_CURRENT 35 +// Maximum charge current to use [A] (5…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: // 35 A = 2,2 kW // 30 A = 2,1 kW @@ -60,9 +64,13 @@ // 10 A = 0,7 kW // 5 A = 0,4 kW -// Maximum driving & recuperation power limits to use [W] (500…30000): -#define MAX_DRIVE_POWER 25000 -#define MAX_RECUP_POWER 12500 +// Maximum driving & recuperation power limits to use [W] (500…30000) +// …at 20 °C and higher: +#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 [%]: diff --git a/README.md b/README.md index ddc504a..ec005dc 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,11 @@ After sending any command, the KlausBMS will respond with the current configurat | --- | --- | | `soh ` | set SOH% | | `soc ` | set SOC% | -| `mcc ` | set max charge current | +| `mcc ` | set max charge current at 20 °C | +| `mcc0 ` | set max charge current at 0 °C | | `sc []` | stop charge / set charge stop SOC | -| `mpw ` | set max power | +| `mpw ` | set max power at 20 °C | +| `mpw0 ` | set max power at 0 °C | | `dcb ` | set drive cutback | | `vrd ` | set voltage range discharging | | `vrc ` | set voltage range charging |