Просмотр исходного кода

重写容量计算,特殊处理放电到0和充电到100

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 лет назад
Родитель
Сommit
ea6ac852f3
1 измененных файлов с 33 добавлено и 46 удалено
  1. 33 46
      Application/app/sox/soc.c

+ 33 - 46
Application/app/sox/soc.c

@@ -17,8 +17,6 @@ static float     soc_delta_time = 0;
 static float     max_soc_delta_time = 0;
 static float _charger_coefficient = 1.0f;
 static float _discharger_coefficient = 1.0f;
-static uint8_t is_force_full = 0;
-static uint8_t is_force_empty = 0;
 uint32_t charger_remain_time = 0;
 
 #define MAX_TIME_FULL_TO_EMPTY (5 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
@@ -163,7 +161,6 @@ static __inline__ int can_modify_min_cap(void){
 
 static void _force_capacity_full(void){
 	_soc.capacity = 100;
-	is_force_full = 1;
 	force_full_ts = shark_get_seconds();
 }
 
@@ -173,20 +170,19 @@ int soc_update_by_ocv(void){
 	if (_soc.flags & SOC_FLAG_CALIBRATED){
 		if (!chargering){
 			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 (_soc.capacity && (bms_health()->powerdown_lower_voltage || bms_health()->sigle_cell_lower_voltage || bms_health()->discharger_lower_voltage)) {
 					if (can_modify_min_cap()){
 						_soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
 					}else {
 						_soc.coulomb_now = _soc.coulomb_min;
 					}
 					_soc.capacity = 0;
-					is_force_empty = 1;
 					changed = 1;
 					soc_warning("current coulomb %f\n", _soc.coulomb_now);
 				}
 			}
 		}
-		if (chargering && !is_force_full){
+		if (chargering && _soc.capacity != 100){
 			if (bms_health()->sigle_cell_over_voltage) {
 				_force_capacity_full();
 				ocv_full_count = 0;
@@ -214,7 +210,7 @@ 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 (!is_force_full){
+			if (_soc.capacity != 100){
 				if ((measure_value()->load_current <= FULL_MIN_CURRENT) && (bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE)){
 					cali_full_count ++;
 				}
@@ -224,7 +220,7 @@ static void soc_calibrate(uint8_t prev_charge_status){
 				}
 			}
 		}else if (prev_charge_status){
-			if(!is_force_full && ((bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE) || bms_health()->sigle_cell_over_voltage)){
+			if((_soc.capacity != 100) && ((bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE) || bms_health()->sigle_cell_over_voltage)){
 				soc_debug("calibrate Capacity to 100\n");
 				_force_capacity_full();
 			}
@@ -259,40 +255,41 @@ uint32_t soc_get_charger_remain_time(void){
 
 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 delta_q = current * delta_time;
+	double delta_q = current * delta_time; 
+	uint8_t est_capaticy = _soc.capacity;
+	int update_capticy = 0;
+	double est_coulomb = _soc.coulomb_now + delta_q;//计算当前容量,充电加, 放电减
+
+	if (est_coulomb < 0){
+		est_coulomb = 0;
+	}else if (est_coulomb > _soc.coulomb_max) {
+		est_coulomb = _soc.coulomb_max;
+	}
+	est_capaticy = ((est_coulomb - _soc.coulomb_min)/(_soc.coulomb_max - _soc.coulomb_min) + 0.005f) * 100;//四舍五入
+	
 	if (chargering){
 		delta_q = delta_q * _charger_coefficient;
 		_soc.charger_coulomb += abs(delta_q);
+		if (est_capaticy < 100 ){ //充电,容量不能等于100,需要靠电压和充电电流来矫正到100
+			update_capticy = 1;
+		}
 	}else {
 		delta_q = delta_q * _discharger_coefficient;
-		_soc.dischrger_coulomb += abs(delta_q); //转为正数
-	}
-	_soc.coulomb_now = _soc.coulomb_now + delta_q; //充电加, 放电减
-
-	if (_soc.coulomb_now < 0){
-		_soc.coulomb_now = 0;
-	}else if (_soc.coulomb_now > _soc.coulomb_max) {
-		_soc.coulomb_now = _soc.coulomb_max;
-	}
-	uint8_t old_cap = _soc.capacity;
-	if ((_soc.coulomb_now - _soc.coulomb_min) >= 0){
-		_soc.capacity = ((_soc.coulomb_now - _soc.coulomb_min)/(_soc.coulomb_max - _soc.coulomb_min) + 0.005f) * 100;//四舍五入
-	}else {
-		_soc.capacity = 0;
-	}
-	if (_soc.capacity > 100){
-		_soc.capacity = 100;
-	}
-	if (chargering && (_soc.capacity == 100) && (!is_force_full)){
-		_soc.capacity = 99;//充电的时候必须通过ocv才能把电量校准到100
-	}else if (!chargering && (_soc.capacity == 0) && !is_force_empty){
-		_soc.capacity = 1;
+		_soc.dischrger_coulomb += abs(delta_q);
+		if (est_capaticy > 0) {  //放电,容量不能等于0,需要靠欠压或者PowerDown 矫正到0
+			update_capticy = 1;
+		}
 	}
-	if (is_force_empty && (_soc.capacity == 1)) {
-		_soc.capacity = 0;
+	if (update_capticy) {
+		if (_soc.capacity != est_capaticy) {
+			_soc.capacity = est_capaticy;
+		}else {
+			update_capticy = 0;
+		}
+		_soc.coulomb_now = est_coulomb;
 	}
 	//通过电压校准SOC,只能在电压范围的两端校准
-	soc_update_by_ocv();
+	update_capticy |= soc_update_by_ocv();
 	soc_calibrate(prev_charge_status);
 
 	//如果没有校准过,充电过程中,电量100%后,设置校准标志位
@@ -300,7 +297,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 		_soc.coulomb_now = _soc.coulomb_max;//充满后,当前容量设置为最大容量
 		if ((_soc.flags & SOC_FLAG_CALIBRATED) == 0){
 			_soc.flags |= SOC_FLAG_CALIBRATED;
-			nv_save_soc();
+			update_capticy = 1;
 			soc_warning("calibrate OK, charging coulomb: %f\n", _soc.charger_coulomb);
 		}else { //如果校准过,单电芯过压,100%的容量,设置最大容量为当前容量
 			if (bms_health()->sigle_cell_over_voltage){
@@ -314,7 +311,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 		}
 	}
 	_soc.energy = bms_state_get()->pack_voltage/1000.f * (_soc.coulomb_now - _soc.coulomb_min);
-	if (old_cap != _soc.capacity) {
+	if (update_capticy) {
 		nv_save_soc();
 	}
 
@@ -349,16 +346,6 @@ void soc_update(void){
 		start_least_square(1);
 	}
 #endif
-	if (chargering && is_force_empty){
-		//欠压后,只有当充电0.5%后,才显示真实电量,防止骑行过程电量0,1跳变
-		if (_soc.charger_coulomb / (_soc.coulomb_max - _soc.coulomb_min) >= 0.005) {
-			is_force_empty = 0;
-		}
-	}else if (!chargering && is_force_full) {
-		if (_soc.dischrger_coulomb / (_soc.coulomb_max - _soc.coulomb_min) >= 0.005) {
-			is_force_full = 0;
-		}
-	}
 	soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
 	soc_update_charger_remain_time();
 }