Sfoglia il codice sorgente

充电充满后,通过内部安时积分的计算加快放大倍率

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 3 anni fa
parent
commit
a8860abe8a
3 ha cambiato i file con 58 aggiunte e 25 eliminazioni
  1. 2 0
      Application/app/event_record.h
  2. 55 24
      Application/app/sox/soc.c
  3. 1 1
      Application/app/sox/soc.h

+ 2 - 0
Application/app/event_record.h

@@ -25,6 +25,8 @@ typedef enum {
 	Cell_Under_Vol2,    //19
 	Cell_Over_Vol2,     //20
 	Min_Cap_For_DisCharger2,
+	Charger_no_full_capaticy,
+	Charger_no_full_ceof,
 }event_id_t;
 
 typedef struct {

+ 55 - 24
Application/app/sox/soc.c

@@ -19,18 +19,19 @@ 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 float _discharger_no_full_coef = 1.0f;
 static uint32_t charger_remain_time = 0;
-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*/};
+static const float _discharger_gain[] = {1.0f/*>0度*/, 1.03f/*-2<t<=0*/, 1.04f/*-5<t<=-2*/, 1.05f/*-10<t<=-5*/, 1.06f/*-15<t<=-10*/, 1.08f/*-20<t<=-15*/};
 #define MAX_TIME_FULL_TO_EMPTY (5 * 24 * 3600) //充满到欠压5天内达到,可以校准最小电量
 #define MAX_TIME_EMPTY_TO_FULL (24 * 3600) //欠压到充满24小时内达到,可以校准最小电量
 #define DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
 #define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
-#define FULL_MAX_VOLTAGE_CHARGING (54000)//mV
-#define FULL_MAX_VOLTAGE_STOP_CHARGING (53500)
+#define FULL_MAX_VOLTAGE_CHARGING (53500)//mV
+#define FULL_MAX_VOLTAGE_STOP_CHARGING (53000)
 #define AGINT_TEST_MAX_VOLTAGE_CHARGING (53000) //mV
 #define FULL_MAX_VOLTAGE (54000) //mV
 #define FULL_MIN_CURRENT (500.0f) //mA
-static double start_charger_coulomb = 0.0f; //开始充电时候的容量
+//static double start_charger_coulomb = 0.0f; //开始充电时候的容量
 static void calibrate_soc_by_ocv(void);
 static void _soc_clear(void);
 
@@ -66,6 +67,9 @@ void soc_init(void){
 		}else if (_soc.capacity == 0) {
 			force_empty_ts = shark_get_seconds() + 1;
 		}
+		if (_soc.current_real_coulomb != (_soc.coulomb_now - _soc.coulomb_min)) {
+			_soc.current_real_coulomb = (_soc.coulomb_now - _soc.coulomb_min);
+		}
 	}
 	if (soc_get_version() != SOC_CURRENT_VERSION) {
 		//DO SOMETHING, FOR SOC VERSION CHANGED
@@ -94,6 +98,7 @@ static void _soc_clear(void){
 	_soc.dischrger_coulomb = 0;
 	_soc.pre_discharger_coulomb = 0;
 	_soc.total_coulomb = 0;
+	_soc.current_real_coulomb = 0;
 }
 
 void soc_clear_calibrate(int keep_cycle) {
@@ -172,6 +177,8 @@ static void soc_update_discharger_coeff(void){
 		}
 		if ((abs(measure_value()->load_current) > 10.0f) && (abs(measure_value()->load_current) < 500)) {
 			coff = 1.05f;
+		}else {
+			coff = _discharger_no_full_coef;
 		}
 		_discharger_coefficient = _discharger_coefficient * coff;
 	}
@@ -225,9 +232,9 @@ void soc_log(void){
 	soc_debug("C pre char: %.4f\n", TOHA(_soc.pre_discharger_coulomb));
 	soc_debug("C pre dischar: %.4f\n", TOHA(_soc.pre_charger_coulomb));
 	soc_debug("C tol: %.2f\n", _soc.total_coulomb);
-	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("C real_coulomb: %f\n", _soc.current_real_coulomb);
+	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, %d\n", _discharger_coefficient, _discharger_no_full_coef);
 	if (chargering){
 		soc_debug("C remain %d\n", charger_remain_time);
 	}
@@ -311,26 +318,38 @@ bool soc_is_force_full(void) {
 static void _force_capacity_full(void){
 	is_force_full = true;
 	force_full_time = shark_get_seconds();
-	double curr_real_cap = start_charger_coulomb + _soc.charger_coulomb;
 	double curr_min_cap = 0.0f;
-	if (can_modify_min_when_full()) { //前面出现过电芯欠压, 当前容量没到最大容量
-		if (curr_real_cap > _soc.coulomb_max) {
-			curr_min_cap = _soc.coulomb_min - (curr_real_cap - _soc.coulomb_max);
-		}else {
-			curr_min_cap = _soc.coulomb_max - curr_real_cap + _soc.coulomb_min;
-		}
-		if (curr_min_cap < 0.0f) {
-			curr_min_cap = 0.0f;
+
+	if ((_soc.flags & SOC_FLAG_CALIBRATED) == 0){
+		_soc.current_real_coulomb = _soc.coulomb_max;
+		_discharger_no_full_coef = 1.0f;
+	}else {
+		if (bms_state_get()->pack_voltage >= 52500) {
+			_soc.current_real_coulomb = _soc.coulomb_max - _soc.coulomb_min;
 		}
+	}
+
+	if (_soc.current_real_coulomb < _soc.coulomb_max) {
+		curr_min_cap = _soc.coulomb_max - _soc.current_real_coulomb;
+	}
+
+	if (can_modify_min_when_full()) { //前面出现过电芯欠压, 当前容量没到最大容量
 		//don't trust if curr_min_cap big than before
-		if (curr_min_cap < _soc.coulomb_min) {
+		if (curr_min_cap <= _soc.coulomb_min) {
 			_soc.coulomb_min = _soc.coulomb_min * (1.0f - min_cap_lfp) + curr_min_cap * min_cap_lfp; //lowpass filter
 		}
 	}
-	u32 cap_x10 = (u32)(curr_real_cap / 3600.0f * 10);
+	if (curr_min_cap <= _soc.coulomb_min) {
+		_discharger_no_full_coef = 1.0f;
+	}else {
+		double delta_min = curr_min_cap - _soc.coulomb_min;
+		_discharger_no_full_coef = 1.0f + delta_min/(_soc.coulomb_max - _soc.coulomb_min);
+	}
+
+	push_event(Charger_no_full_ceof, (u32)(_discharger_no_full_coef * 10000));
+	u32 cap_x10 = (u32)(_soc.current_real_coulomb / 3600.0f * 10);
 	u32 min_x10 = (u32)(curr_min_cap / 3600.0f * 10);
 	push_event(Charger_Full_cap2, ((min_x10 & 0xFFFF) << 16) | (cap_x10 & 0xFFFF));
-
 	//充满后,当前容量设置为最大容量
 	_soc.capacity = 100;
 	_soc.coulomb_now = _soc.coulomb_max;
@@ -375,6 +394,7 @@ static int _soc_update_by_ocv(uint8_t prev_charge_status){
 			push_event(Min_Cap_For_DisCharger2, (bms_state_get()->pack_voltage << 16) | (cap_x10 & 0xFFFF));
 			force_empty_ts = shark_get_seconds();
 			_soc.capacity = 0;
+			_soc.current_real_coulomb = 0.0f;
 			return 1;
 		}	
 	}
@@ -505,12 +525,21 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 	}
 	if (chargering){
 		delta_q = delta_q * _charger_coefficient;
+		_soc.current_real_coulomb += abs(delta_q);
+		if (_soc.current_real_coulomb > _soc.coulomb_max) {
+			_soc.current_real_coulomb = _soc.coulomb_max;
+		}
 		_soc.charger_coulomb += abs(delta_q);
 		if ((est_capaticy < 100) && (est_capaticy >= _soc.capacity)){ //充电,容量不能等于100,需要靠电压和充电电流来矫正到100
 			update_capticy = 1;
 		}
 	}else {
 		_soc.dischrger_coulomb += abs(delta_q);
+		_soc.current_real_coulomb -= abs(delta_q) / _discharger_no_full_coef;
+		if (_soc.current_real_coulomb < 0) {
+			_soc.current_real_coulomb = 0;
+		}	
+
 		if (est_coulomb < _soc.coulomb_min) {
 			_soc.coulomb_min = est_coulomb;
 		}
@@ -538,9 +567,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
 			soc_warning("calibrate OK, charging coulomb: %f\n", _soc.charger_coulomb);
 		}
 	}
-	if (_soc.coulomb_now >= _soc.coulomb_min) {
-		_soc.energy = bms_state_get()->pack_voltage/1000.f * (_soc.coulomb_now - _soc.coulomb_min);
-	}
+
 	if (update_capticy) {
 		nv_save_soc();
 	}
@@ -559,8 +586,7 @@ void soc_update(void){
 		_soc.pre_charger_coulomb = _soc.charger_coulomb;
 		_soc.charger_coulomb = 0;//clear charing
 		_soc.total_coulomb += _soc.pre_charger_coulomb / 3600.0f;
-		chargering = 1;
-		start_charger_coulomb = _soc.coulomb_now;
+		chargering = 1;	
 #if LEAST_SQUARE==1		
 		start_least_square(0);
 #endif
@@ -571,6 +597,11 @@ void soc_update(void){
 		_soc.total_coulomb += _soc.pre_discharger_coulomb / 3600.0f;
 		chargering = 0;
 		charger_remain_time = 0;
+		if (_is_normal_charging() && (_soc.capacity != 100)) {
+			u32 charger_cap_x10 = (u32)(_soc.charger_coulomb / 3600.0f * 10);
+			u32 cur_cap_x10 = (u32)(_soc.coulomb_now / 3600.0f * 10);
+			push_event(Charger_no_full_capaticy, ((cur_cap_x10 & 0xFFFF) << 16) | (charger_cap_x10 & 0xFFFF));
+		}
 		soc_warning("changed to dischargering, current = %d\n", measure_value()->load_current);
 	}
 #if LEAST_SQUARE==1	

+ 1 - 1
Application/app/sox/soc.h

@@ -14,7 +14,7 @@ typedef struct {
 	double coulomb_min;
 	double coulomb_max;
 	double charger_cmin; //充电计算的最小容量
-	double energy; //当前的能量(wh)
+	double current_real_coulomb; //当前的能量(wh)
 	double charger_coulomb; //本次充电的AH
 	double dischrger_coulomb; //本次放电的AH