|
@@ -13,6 +13,7 @@ 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;
|
|
|
static float _discharger_coefficient = 1.0f;
|
|
static float _discharger_coefficient = 1.0f;
|
|
|
|
|
+static uint8_t is_force_full = 0;
|
|
|
uint32_t charger_remain_time = 0;
|
|
uint32_t charger_remain_time = 0;
|
|
|
#define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
|
|
#define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
|
|
|
|
|
|
|
@@ -43,6 +44,7 @@ void soc_init(void){
|
|
|
#define TOHA(x) (float)(x/3600.0f)
|
|
#define TOHA(x) (float)(x/3600.0f)
|
|
|
|
|
|
|
|
void soc_log(void){
|
|
void soc_log(void){
|
|
|
|
|
+ soc_debug("C flags 0x%x\n", _soc.flags);
|
|
|
soc_debug("C now: %.4f\n", TOHA(_soc.coulomb_now));
|
|
soc_debug("C now: %.4f\n", TOHA(_soc.coulomb_now));
|
|
|
soc_debug("C min: %.4f\n", TOHA(_soc.coulomb_min));
|
|
soc_debug("C min: %.4f\n", TOHA(_soc.coulomb_min));
|
|
|
soc_debug("C max: %.4f\n", TOHA(_soc.coulomb_max));
|
|
soc_debug("C max: %.4f\n", TOHA(_soc.coulomb_max));
|
|
@@ -94,7 +96,7 @@ static __inline__ float _delta_time(void){
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int soc_update_by_ocv(void){
|
|
int soc_update_by_ocv(void){
|
|
|
- static int cali_full_count = 0;
|
|
|
|
|
|
|
+
|
|
|
int changed = 0;
|
|
int changed = 0;
|
|
|
if (_soc.flags & SOC_FLAG_CALIBRATED){
|
|
if (_soc.flags & SOC_FLAG_CALIBRATED){
|
|
|
if (!chargering && bms_health()->powerdown_lower_voltage){
|
|
if (!chargering && bms_health()->powerdown_lower_voltage){
|
|
@@ -104,29 +106,36 @@ int soc_update_by_ocv(void){
|
|
|
changed = 1;
|
|
changed = 1;
|
|
|
}
|
|
}
|
|
|
if (chargering){
|
|
if (chargering){
|
|
|
- if (bms_state_get()->pack_voltage >= (54000)){
|
|
|
|
|
|
|
+ if (bms_state_get()->pack_voltage >= (54000) || ((measure_value()->load_current > 0.0f) && (measure_value()->load_current <= 500.0f))){
|
|
|
_soc.capacity = 100;
|
|
_soc.capacity = 100;
|
|
|
changed = 1;
|
|
changed = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }else {
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ return changed;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static void soc_calibrate(uint8_t prev_charge_status){
|
|
|
|
|
+ static int cali_full_count = 0;
|
|
|
|
|
+ if (!(_soc.flags & SOC_FLAG_CALIBRATED)){
|
|
|
if (chargering){//用ocv进行严格校准
|
|
if (chargering){//用ocv进行严格校准
|
|
|
- if (measure_value()->load_current <= 400.0f){
|
|
|
|
|
- //判断总电压
|
|
|
|
|
- if (bms_state_get()->pack_voltage >= 53000){
|
|
|
|
|
- cali_full_count ++;
|
|
|
|
|
- if (cali_full_count == 10) {
|
|
|
|
|
- soc_debug("measure_value()->load_current %d\n", measure_value()->load_current);
|
|
|
|
|
- _soc.capacity = 100;
|
|
|
|
|
- changed = 1;
|
|
|
|
|
- }
|
|
|
|
|
- return changed;
|
|
|
|
|
|
|
+ if ((measure_value()->load_current <= 500.0f) && (bms_state_get()->pack_voltage >= 53500)){
|
|
|
|
|
+ cali_full_count ++;
|
|
|
|
|
+ if (cali_full_count == 10) {
|
|
|
|
|
+ soc_debug("calibrate Capacity to 100, measure_value()->load_current %d\n", measure_value()->load_current);
|
|
|
|
|
+ _soc.capacity = 100;
|
|
|
|
|
+ is_force_full = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ }else if (prev_charge_status){
|
|
|
|
|
+ if(bms_state_get()->pack_voltage >= 54000){
|
|
|
|
|
+ soc_debug("calibrate Capacity to 100\n");
|
|
|
|
|
+ _soc.capacity = 100;
|
|
|
|
|
+ is_force_full = 1;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- cali_full_count = 0;
|
|
|
|
|
}
|
|
}
|
|
|
- return changed;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void soc_update_charger_remain_time(void){
|
|
static void soc_update_charger_remain_time(void){
|
|
@@ -154,7 +163,7 @@ uint32_t soc_get_charger_remain_time(void){
|
|
|
return charger_remain_time;
|
|
return charger_remain_time;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void soc_update_by_current_and_time(float current_now, float delta_time){
|
|
|
|
|
|
|
+static void soc_update_by_current_and_time(float current_now, float delta_time, uint8_t prev_charge_status){
|
|
|
double current = current_now / 1000.0f; //A
|
|
double current = current_now / 1000.0f; //A
|
|
|
double delta_q = current * delta_time;
|
|
double delta_q = current * delta_time;
|
|
|
if (chargering){
|
|
if (chargering){
|
|
@@ -166,9 +175,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time){
|
|
|
}
|
|
}
|
|
|
_soc.coulomb_now = _soc.coulomb_now + delta_q; //充电加, 放电减
|
|
_soc.coulomb_now = _soc.coulomb_now + delta_q; //充电加, 放电减
|
|
|
|
|
|
|
|
- if (_soc.coulomb_now > _soc.coulomb_max){
|
|
|
|
|
- _soc.coulomb_now = _soc.coulomb_max;
|
|
|
|
|
- }else if (_soc.coulomb_now < _soc.coulomb_min){
|
|
|
|
|
|
|
+ if (_soc.coulomb_now < _soc.coulomb_min){
|
|
|
_soc.coulomb_now = _soc.coulomb_min;
|
|
_soc.coulomb_now = _soc.coulomb_min;
|
|
|
}
|
|
}
|
|
|
uint8_t old_cap = _soc.capacity;
|
|
uint8_t old_cap = _soc.capacity;
|
|
@@ -176,13 +183,14 @@ static void soc_update_by_current_and_time(float current_now, float delta_time){
|
|
|
if (_soc.capacity > 100){
|
|
if (_soc.capacity > 100){
|
|
|
_soc.capacity = 100;
|
|
_soc.capacity = 100;
|
|
|
}
|
|
}
|
|
|
- if (chargering && (_soc.capacity == 100)){
|
|
|
|
|
- _soc.capacity = 99;//充电的时候必须通过ovc才能把电量校准到100
|
|
|
|
|
|
|
+ if (chargering && (_soc.capacity == 100) && (!is_force_full)){
|
|
|
|
|
+ _soc.capacity = 99;//充电的时候必须通过ocv才能把电量校准到100
|
|
|
}else if (!chargering && (_soc.capacity == 0)){
|
|
}else if (!chargering && (_soc.capacity == 0)){
|
|
|
_soc.capacity = 1;
|
|
_soc.capacity = 1;
|
|
|
}
|
|
}
|
|
|
//通过电压校准SOC,只能在电压范围的两端校准
|
|
//通过电压校准SOC,只能在电压范围的两端校准
|
|
|
soc_update_by_ocv();
|
|
soc_update_by_ocv();
|
|
|
|
|
+ soc_calibrate(prev_charge_status);
|
|
|
|
|
|
|
|
//如果没有校准过,充电过程中,电量100%后,设置校准标志位
|
|
//如果没有校准过,充电过程中,电量100%后,设置校准标志位
|
|
|
if (chargering && (_soc.capacity == 100)){
|
|
if (chargering && (_soc.capacity == 100)){
|
|
@@ -206,25 +214,32 @@ static void soc_update_by_current_and_time(float current_now, float delta_time){
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void soc_update_for_deepsleep(float sleep_time){
|
|
void soc_update_for_deepsleep(float sleep_time){
|
|
|
- soc_update_by_current_and_time(-1.0f, sleep_time);
|
|
|
|
|
|
|
+ soc_update_by_current_and_time(-1.0f, sleep_time, 0);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void soc_update(void){
|
|
void soc_update(void){
|
|
|
|
|
+ uint8_t pre_chargering = chargering;
|
|
|
if (!chargering && bms_state_get()->charging){
|
|
if (!chargering && bms_state_get()->charging){
|
|
|
_soc.pre_charger_coulomb = _soc.charger_coulomb;
|
|
_soc.pre_charger_coulomb = _soc.charger_coulomb;
|
|
|
_soc.charger_coulomb = 0;//clear charing
|
|
_soc.charger_coulomb = 0;//clear charing
|
|
|
_soc.total_coulomb += _soc.pre_charger_coulomb / 3600.0f;
|
|
_soc.total_coulomb += _soc.pre_charger_coulomb / 3600.0f;
|
|
|
chargering = 1;
|
|
chargering = 1;
|
|
|
|
|
+ if (_soc.capacity < 100) {
|
|
|
|
|
+ is_force_full = 0;
|
|
|
|
|
+ }
|
|
|
soc_warning("changed to chargering, current = %d\n", measure_value()->load_current);
|
|
soc_warning("changed to chargering, current = %d\n", measure_value()->load_current);
|
|
|
}else if (chargering && !bms_state_get()->charging){
|
|
}else if (chargering && !bms_state_get()->charging){
|
|
|
_soc.pre_discharger_coulomb = _soc.dischrger_coulomb;
|
|
_soc.pre_discharger_coulomb = _soc.dischrger_coulomb;
|
|
|
_soc.dischrger_coulomb = 0; //clear discharger
|
|
_soc.dischrger_coulomb = 0; //clear discharger
|
|
|
_soc.total_coulomb += _soc.pre_discharger_coulomb / 3600.0f;
|
|
_soc.total_coulomb += _soc.pre_discharger_coulomb / 3600.0f;
|
|
|
chargering = 0;
|
|
chargering = 0;
|
|
|
|
|
+ if (_soc.capacity < 100) {
|
|
|
|
|
+ is_force_full = 0;
|
|
|
|
|
+ }
|
|
|
soc_warning("changed to dischargering, current = %d\n", measure_value()->load_current);
|
|
soc_warning("changed to dischargering, current = %d\n", measure_value()->load_current);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- soc_update_by_current_and_time(measure_value()->load_current, _delta_time());
|
|
|
|
|
|
|
+ soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
|
|
|
soc_update_charger_remain_time();
|
|
soc_update_charger_remain_time();
|
|
|
}
|
|
}
|
|
|
|
|
|