|
@@ -11,8 +11,9 @@
|
|
|
|
|
|
|
|
static soc_t _soc;
|
|
static soc_t _soc;
|
|
|
static uint8_t chargering = 0;
|
|
static uint8_t chargering = 0;
|
|
|
-static u64 current_sample_ts = 0;
|
|
|
|
|
-static u64 charger_ts = 0;
|
|
|
|
|
|
|
+static u64 current_sample_ts = 0; //ms
|
|
|
|
|
+static u64 charger_ts = 0; //ms
|
|
|
|
|
+static u32 force_full_ts = 0xFFFFFFFF; //s
|
|
|
static float soc_delta_time = 0;
|
|
static float soc_delta_time = 0;
|
|
|
static float max_soc_delta_time = 0;
|
|
static float max_soc_delta_time = 0;
|
|
|
static float _charger_coefficient = 1.0f;
|
|
static float _charger_coefficient = 1.0f;
|
|
@@ -21,6 +22,7 @@ static uint8_t is_force_full = 0;
|
|
|
static uint8_t is_force_empty = 0;
|
|
static uint8_t is_force_empty = 0;
|
|
|
uint32_t charger_remain_time = 0;
|
|
uint32_t charger_remain_time = 0;
|
|
|
|
|
|
|
|
|
|
+#define MAX_TIME_FULL_TO_EMPTY (5 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
|
|
|
#define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
|
|
#define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
|
|
|
#define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
|
|
#define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
|
|
|
#define FULL_MAX_VOLTAGE (53500)//mV
|
|
#define FULL_MAX_VOLTAGE (53500)//mV
|
|
@@ -153,6 +155,17 @@ static __inline__ u32 charger_time(void){
|
|
|
return (shark_get_mseconds() - charger_ts);
|
|
return (shark_get_mseconds() - charger_ts);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static __inline__ int can_modify_min_cap(void){
|
|
|
|
|
+ if (shark_get_seconds() > force_full_ts){
|
|
|
|
|
+ if ((shark_get_seconds() - force_full_ts) > MAX_TIME_FULL_TO_EMPTY) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }else {
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
int soc_update_by_ocv(void){
|
|
int soc_update_by_ocv(void){
|
|
|
|
|
|
|
|
int changed = 0;
|
|
int changed = 0;
|
|
@@ -160,7 +173,11 @@ int soc_update_by_ocv(void){
|
|
|
if (!chargering){
|
|
if (!chargering){
|
|
|
if (bms_health()->is_work_temp_normal) {
|
|
if (bms_health()->is_work_temp_normal) {
|
|
|
if (!is_force_empty && (bms_health()->powerdown_lower_voltage || bms_health()->sigle_cell_lower_voltage || bms_health()->discharger_lower_voltage)) {
|
|
if (!is_force_empty && (bms_health()->powerdown_lower_voltage || bms_health()->sigle_cell_lower_voltage || bms_health()->discharger_lower_voltage)) {
|
|
|
- _soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
|
|
|
|
|
|
|
+ if (can_modify_min_cap()){
|
|
|
|
|
+ _soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
|
|
|
|
|
+ }else {
|
|
|
|
|
+ _soc.coulomb_now = _soc.coulomb_min;
|
|
|
|
|
+ }
|
|
|
_soc.capacity = 0;
|
|
_soc.capacity = 0;
|
|
|
is_force_empty = 1;
|
|
is_force_empty = 1;
|
|
|
changed = 1;
|
|
changed = 1;
|
|
@@ -172,6 +189,7 @@ int soc_update_by_ocv(void){
|
|
|
if (bms_state_get()->pack_voltage >= (FULL_MAX_VOLTAGE) && (measure_value()->load_current <= FULL_MIN_CURRENT)){
|
|
if (bms_state_get()->pack_voltage >= (FULL_MAX_VOLTAGE) && (measure_value()->load_current <= FULL_MIN_CURRENT)){
|
|
|
_soc.capacity = 100;
|
|
_soc.capacity = 100;
|
|
|
is_force_full = 1;
|
|
is_force_full = 1;
|
|
|
|
|
+ force_full_ts = shark_get_seconds();
|
|
|
changed = 1;
|
|
changed = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -189,6 +207,7 @@ static void soc_calibrate(uint8_t prev_charge_status){
|
|
|
if (cali_full_count == 10) {
|
|
if (cali_full_count == 10) {
|
|
|
soc_debug("calibrate Capacity to 100, measure_value()->load_current %d\n", measure_value()->load_current);
|
|
soc_debug("calibrate Capacity to 100, measure_value()->load_current %d\n", measure_value()->load_current);
|
|
|
_soc.capacity = 100;
|
|
_soc.capacity = 100;
|
|
|
|
|
+ force_full_ts = shark_get_seconds();
|
|
|
is_force_full = 1;
|
|
is_force_full = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -196,6 +215,7 @@ static void soc_calibrate(uint8_t prev_charge_status){
|
|
|
if(!is_force_full && (bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE)){
|
|
if(!is_force_full && (bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE)){
|
|
|
soc_debug("calibrate Capacity to 100\n");
|
|
soc_debug("calibrate Capacity to 100\n");
|
|
|
_soc.capacity = 100;
|
|
_soc.capacity = 100;
|
|
|
|
|
+ force_full_ts = shark_get_seconds();
|
|
|
is_force_full = 1;
|
|
is_force_full = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -323,7 +343,7 @@ void soc_update(void){
|
|
|
start_least_square(1);
|
|
start_least_square(1);
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
- if (chargering && (charger_time() >= 20 * 1000)){
|
|
|
|
|
|
|
+ if (chargering && (charger_time() >= 20 * 1000) && is_force_empty){
|
|
|
is_force_empty = 0;
|
|
is_force_empty = 0;
|
|
|
}
|
|
}
|
|
|
soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
|
|
soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
|