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

充电full后,调整最小容量,根据当前的容量和最大容量

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 4 лет назад
Родитель
Сommit
00ba217bd1
2 измененных файлов с 75 добавлено и 60 удалено
  1. 66 58
      Application/app/sox/soc.c
  2. 9 2
      Application/app/sox/soc.h

+ 66 - 58
Application/app/sox/soc.c

@@ -17,10 +17,11 @@ 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;
-uint32_t charger_remain_time = 0;
-uint8_t battery_temp_state = 0;
+static uint32_t charger_remain_time = 0;
+static bool _is_cell_lower_vol = false;
 static const float _discharger_gain[] = {1.0f/*>0度*/, 1.002f/*-2<t<=0*/, 1.005f/*-5<t<=-2*/, 1.008f/*-10<t<=-5*/, 1.02f/*-15<t<=-10*/, 1.04f/*-20<t<=-15*/};
 #define MAX_TIME_FULL_TO_EMPTY (5 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
+#define MAX_TIME_EMPTY_TO_FULL (8 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
 #define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
 #define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
 #define FULL_MAX_VOLTAGE_CHARGING (53500)//mV
@@ -29,6 +30,8 @@ static const float _discharger_gain[] = {1.0f/*>0
 #define FULL_MIN_CURRENT (500.0f) //mA
 static int _full_reason = 0;
 static int _force_full = 0;
+static int _force_full_minc = 0;
+static double start_charger_coulomb = 0.0f; //开始充电时候的容量
 static void calibrate_soc_by_ocv(void);
 static void _soc_clear(void);
 
@@ -58,10 +61,29 @@ void soc_init(void){
 	if ((_soc.flags & SOC_FLAG_CALIBRATED) == 0){
 		calibrate_soc_by_ocv();
 		nv_save_soc();
+	}else {
+		if (_soc.capacity == 100) {
+			force_full_ts = shark_get_seconds() + 1;
+		}
+	}
+	if (soc_get_version() != SOC_CURRENT_VERSION) {
+		//DO SOMETHING, FOR SOC VERSION CHANGED
 	}
 	soc_log();
 }
 
+u8 soc_get_version(void) {
+	return SOC_FLAG_TO_VER(_soc.flags);
+}
+
+void soc_set_version(u8 version) {
+	if (version > 7) {
+		return;
+	}
+	_soc.flags &= ~SOC_FLAG_VERSON_MASK;
+	_soc.flags |= SOC_FLAG_VERSION(version);
+}
+
 static void _soc_clear(void){
 	_soc.coulomb_min = 0;
 	_soc.coulomb_max = DEFALUT_MAX_COULOMB; //30HA,这个值最总需要soh模块给
@@ -196,7 +218,8 @@ void soc_log(void){
 	soc_debug("C energy: %f\n", _soc.energy);
 	soc_debug("C delta time %f,%f, -- %d\n", max_soc_delta_time, soc_delta_time, force_full_ts);
 	soc_debug("C discharger coefficient = %f\n", _discharger_coefficient);
-	soc_debug("forcce full = %d, %d\n", _full_reason, _force_full);
+	soc_debug("forcce full = %d, %d, %d, %d\n", _full_reason, _force_full, _force_full_minc, force_full_ts);
+	soc_debug("Discharger: %s\n", _is_cell_lower_vol?"Lower vol":"Normal");
 	if (chargering){
 		soc_debug("C remain %d\n", charger_remain_time);
 	}
@@ -251,10 +274,37 @@ static __inline__ int can_modify_min_cap(void){
 	return 0;
 }
 
+static __inline__ int can_modify_min_when_full(void){
+	if (force_full_ts == 0) {
+		return 0;
+	}
+	if (shark_get_seconds() > force_full_ts){
+		if ((shark_get_seconds() - force_full_ts) > MAX_TIME_EMPTY_TO_FULL) {
+			return 0;
+		}else {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
 static void _force_capacity_full(void){
 	_soc.capacity = 100;
+	if (can_modify_min_when_full()) { //前面出现过电芯欠压, 当前容量没到最大容量
+		double curr_real_cap = start_charger_coulomb + _soc.charger_coulomb;
+		if (curr_real_cap > _soc.coulomb_max) {
+			_soc.coulomb_min = 0;
+		}else {
+			_soc.coulomb_min = _soc.coulomb_max - curr_real_cap;
+		}
+		soc_warning("current real cap %f\n", curr_real_cap);
+		_force_full_minc ++;
+	}
 	_soc.coulomb_now = _soc.coulomb_max;//充满后,当前容量设置为最大容量
+
 	force_full_ts = shark_get_seconds();
+	_is_cell_lower_vol = false;
 	_force_full = 2;
 }
 
@@ -263,20 +313,6 @@ static int _soc_is_under_voltage(void) {
 		bms_health()->discharger_lower_voltage);
 }
 
-#if 0
-static int _soc_force_capaticy(uint8_t capaticy){
-	float cap = (float)capaticy / 100.0f;
-	float min = (_soc.coulomb_now - cap * _soc.coulomb_max)/(1.0f - cap);
-	if (min > 0.0f) {
-		_soc.coulomb_min = min;
-		_soc.capacity = capaticy;
-		force_full_ts = 0xFFFFFFFF;
-		return 1;
-	}
-	return 0;
-}
-#endif
-
 static int _soc_update_by_ocv(uint8_t prev_charge_status){
 	static int ocv_full_count = 0;
 	//static int ocv_force_capaticy = 0;
@@ -293,47 +329,28 @@ static int _soc_update_by_ocv(uint8_t prev_charge_status){
 				}else if (health_is_mid_current()) {
 					_soc.coulomb_min = _soc.coulomb_now * 1.0f;
 				}else if (health_is_big_current()){
-					_soc.coulomb_min = _soc.coulomb_now * 0.95f;
+					_soc.coulomb_min = _soc.coulomb_now * 0.975f;
 				}else {
-					_soc.coulomb_min = _soc.coulomb_now * 0.90f;
+					_soc.coulomb_min = _soc.coulomb_now * 0.95f;
 				}
 				_soc.coulomb_now = _soc.coulomb_min;
 				soc_warning("calicablite coulomb_min %f\n", _soc.coulomb_min);
 			}else {
 				_soc.coulomb_now = _soc.coulomb_min;
 			}
+			_is_cell_lower_vol = true;
 			_soc.capacity = 0;
 			return 1;
-		}
-#if 0
-		else if ((!prev_charge_status) && (bms_state_get()->cell_min_vol <= 2900) && (_soc.capacity > 10)) {
-			/* 如果单电芯最小电压小于2.9v,并且容量大于10%,需要校准到10% */
-			if (ocv_force_capaticy++ >= 10) {
-				return _soc_force_capaticy(10);
-			}
-		}else {
-			ocv_force_capaticy = 0;
-		}
-#endif		
+		}	
 	}
 	if (chargering || prev_charge_status) {
-		//ocv_force_capaticy = 0;
-		/*
-		if (bms_state_get()->ps_charger_mask && !bms_state_get()->ps_charger_in) { //ps100 上报无充电器,不做处理
-			ocv_full_count = 0;
-			return changed;
-		}*/
-		if (chargering && bms_health()->sigle_cell_over_voltage) { //单电芯过压强制充满
-			_force_capacity_full();
-			_full_reason = 3;
-			if (bms_state_get()->pack_voltage < SIGAL_CELL_OV_MAX_PACK_VOL) {
-				force_full_ts = 0; //单电芯过压,总电压小于SIGAL_CELL_OV_MAX_PACK_VOL, 放电欠压后不校准最小容量
-			}
-			ocv_full_count = 0;
-			return 1;
-		}
-		if (chargering && (_soc.capacity != 100)) {
-			if (bms_state_get()->pack_voltage >= (FULL_MAX_VOLTAGE_CHARGING) && (measure_value()->load_current <= FULL_MIN_CURRENT)){
+		if (chargering && (_soc.capacity != 100)) { 
+			if (bms_health()->sigle_cell_over_voltage) { //单电芯过压强制充满
+				_force_capacity_full();
+				_full_reason = 3;
+				ocv_full_count = 0;
+				changed = 1;
+			}else if (bms_state_get()->pack_voltage >= (FULL_MAX_VOLTAGE_CHARGING) && (measure_value()->load_current <= FULL_MIN_CURRENT)){
 				if (ocv_full_count++ >= 100) { //连续100次(小电流采集30ms一次,就是3s时间)电压和电流满足条件,强制充满
 					_force_capacity_full();
 					_full_reason = 4;
@@ -343,7 +360,7 @@ static int _soc_update_by_ocv(uint8_t prev_charge_status){
 			}else {
 				ocv_full_count = 0;
 			}
-		}else if (!chargering && prev_charge_status && (_soc.capacity != 100)){
+		} else if (!chargering && prev_charge_status && (_soc.capacity != 100)){
 			if ((bms_state_get()->pack_voltage >= FULL_MAX_VOLTAGE) && (_soc.charger_coulomb >= (0.1f * 3600.0f))){//充电容量几乎接近最大容量
 				_force_capacity_full();
 				_full_reason = 5;
@@ -383,7 +400,6 @@ static void soc_calibrate(uint8_t prev_charge_status){
 			if (_soc.capacity && _soc_is_under_voltage()) {
 				_soc.capacity = 0;
 			}
-
 		}
 	}
 }
@@ -475,15 +491,6 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 			_soc.flags |= SOC_FLAG_CALIBRATED;
 			update_capticy = 1;
 			soc_warning("calibrate OK, charging coulomb: %f\n", _soc.charger_coulomb);
-		}else { //如果校准过,单电芯过压,100%的容量,设置最大容量为当前容量
-			if (bms_health()->sigle_cell_over_voltage){
-#if 0	/* 暂时去掉,最大容量不变化,只校准欠压后的可放电的最小容量 */			
-				if ((_soc.coulomb_now >= DEFALUT_MIN_COULOMB) && (_soc.coulomb_now <= DEFALUT_MAX_COULOMB)) {
-					_soc.coulomb_max = _soc.coulomb_now;
-					soc_warning("signal cell over vol, cap full, reset coul max to coul now: %f\n", _soc.coulomb_max);
-				}
-#endif 				
-			}
 		}
 	}
 	if (_soc.coulomb_now >= _soc.coulomb_min) {
@@ -508,6 +515,7 @@ void soc_update(void){
 		_soc.charger_coulomb = 0;//clear charing
 		_soc.total_coulomb += _soc.pre_charger_coulomb / 3600.0f;
 		chargering = 1;
+		start_charger_coulomb = _soc.coulomb_now - _soc.coulomb_min;
 #if LEAST_SQUARE==1		
 		start_least_square(0);
 #endif

+ 9 - 2
Application/app/sox/soc.h

@@ -2,14 +2,18 @@
 #include "libs/shark_libs.h"
 #include "bsp/shark_bsp.h"
 
-#define SOC_FLAG_CALIBRATED 1 //已经校准
+#define SOC_CURRENT_VERSION 0
+#define SOC_FLAG_VERSON_MASK (0x0E)
+#define SOC_FLAG_CALIBRATED (0x1 << 0) //已经校准
+#define SOC_FLAG_VERSION(v) (((v)<<1)& SOC_FLAG_VERSON_MASK)
+#define SOC_FLAG_TO_VER(f) (((f) & SOC_FLAG_VERSON_MASK) >> 1)
 typedef struct {
 	uint8_t flags; //比如是否校准等
 	double coulomb_now; /*AH, 若导线中载有1安培的稳定电流,则在1秒内通过导线横截面积的电量为1库仑 */
 	uint8_t capacity;  /* 电池的容量百分比 */
 	double coulomb_min;
 	double coulomb_max;
-	double power; //功率,当前的电压 x 当前的电流(w)
+	double charger_cmin; //充电计算的最小容量
 	double energy; //当前的能量(wh)
 	double charger_coulomb; //本次充电的AH
 	double dischrger_coulomb; //本次放电的AH
@@ -30,4 +34,7 @@ soc_t *get_soc(void);
 void soc_log(void);
 void soc_update_for_deepsleep(float sleep_time);
 void soc_restore_by_iap(uint8_t flags, uint8_t capaticy);
+u8 soc_get_version(void);
+void soc_set_version(u8 version);
+