|
|
@@ -18,7 +18,8 @@ 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 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 DEFALUT_MAX_COULOMB (MAX_HA * 3600.0f)
|
|
|
#define DEFALUT_MIN_COULOMB (25.0f * 3600.0f)
|
|
|
@@ -59,6 +60,46 @@ void soc_init(void){
|
|
|
soc_log();
|
|
|
}
|
|
|
|
|
|
+void soc_restore_by_iap(uint8_t flags, uint8_t capaticy){
|
|
|
+ _soc.coulomb_min = 0;
|
|
|
+ _soc.coulomb_max = DEFALUT_MAX_COULOMB; //30HA,这个值最总需要soh模块给
|
|
|
+ _soc.flags = 0;
|
|
|
+ _soc.charger_coulomb = 0;
|
|
|
+ _soc.pre_charger_coulomb = 0;
|
|
|
+ _soc.dischrger_coulomb = 0;
|
|
|
+ _soc.pre_discharger_coulomb = 0;
|
|
|
+ _soc.total_coulomb = 0;
|
|
|
+ if (flags == 1) {
|
|
|
+ _soc.flags |= SOC_FLAG_CALIBRATED;
|
|
|
+ }
|
|
|
+ _soc.capacity = capaticy;
|
|
|
+ _soc.coulomb_now = (_soc.coulomb_max - _soc.coulomb_min) * _soc.capacity / 100.0f + _soc.coulomb_min;
|
|
|
+ nv_save_all_soc();
|
|
|
+}
|
|
|
+
|
|
|
+static void soc_jugde_temp(void){
|
|
|
+ int low_temp = 0xFFFF;
|
|
|
+ for (int i = 0; i < PACK_TEMPS_NUM-1; i++) {
|
|
|
+ low_temp = MIN(low_temp, measure_value()->pack_temp[i]);
|
|
|
+ }
|
|
|
+ if (low_temp > 0) {
|
|
|
+ _discharger_coefficient = _discharger_gain[0];
|
|
|
+ }else {
|
|
|
+ if (low_temp > -2) {
|
|
|
+ _discharger_coefficient = _discharger_gain[1];
|
|
|
+ }else if (low_temp > -5) {
|
|
|
+ _discharger_coefficient = _discharger_gain[2];
|
|
|
+ }else if (low_temp > -10) {
|
|
|
+ _discharger_coefficient = _discharger_gain[3];
|
|
|
+ }else if (low_temp > -15) {
|
|
|
+ _discharger_coefficient = _discharger_gain[4];
|
|
|
+ }else {
|
|
|
+ _discharger_coefficient = _discharger_gain[5];
|
|
|
+ }
|
|
|
+ force_full_ts = 0xFFFFFFFF;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#if LEAST_SQUARE==1
|
|
|
static void start_least_square(int start){
|
|
|
if (start && !least_square_started) {
|
|
|
@@ -109,6 +150,7 @@ void soc_log(void){
|
|
|
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);
|
|
|
if (chargering){
|
|
|
soc_debug("C remain %d\n", charger_remain_time);
|
|
|
}
|
|
|
@@ -191,18 +233,16 @@ static int _soc_update_by_ocv(uint8_t prev_charge_status){
|
|
|
return 0;
|
|
|
}
|
|
|
if (!chargering){
|
|
|
- if (bms_health()->is_work_temp_normal) {
|
|
|
- if (_soc.capacity && _soc_is_under_voltage()) {
|
|
|
- soc_warning("judge calib min col %d - %d\n", shark_get_seconds(), force_full_ts);
|
|
|
- if (can_modify_min_cap()){
|
|
|
- _soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
|
|
|
- soc_warning("calicablite coulomb_min %f\n", _soc.coulomb_min);
|
|
|
- }else {
|
|
|
- _soc.coulomb_now = _soc.coulomb_min;
|
|
|
- }
|
|
|
- _soc.capacity = 0;
|
|
|
- return 1;
|
|
|
+ if (_soc.capacity && _soc_is_under_voltage()) {
|
|
|
+ soc_warning("judge calib min col %d - %d\n", shark_get_seconds(), force_full_ts);
|
|
|
+ if (can_modify_min_cap()){
|
|
|
+ _soc.coulomb_min = _soc.coulomb_now; //已经校准过了,而且电池在常温下进入powerdown,最小容量修正为当前容量
|
|
|
+ soc_warning("calicablite coulomb_min %f\n", _soc.coulomb_min);
|
|
|
+ }else {
|
|
|
+ _soc.coulomb_now = _soc.coulomb_min;
|
|
|
}
|
|
|
+ _soc.capacity = 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
}
|
|
|
if (chargering || prev_charge_status) {
|
|
|
@@ -309,6 +349,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
|
|
|
update_capticy = 1;
|
|
|
}
|
|
|
}else {
|
|
|
+ soc_jugde_temp();
|
|
|
delta_q = delta_q * _discharger_coefficient;
|
|
|
_soc.dischrger_coulomb += abs(delta_q);
|
|
|
if ((est_capaticy > 0) && (est_capaticy <= _soc.capacity)) { //放电,容量不能等于0,需要靠欠压或者PowerDown 矫正到0
|
|
|
@@ -355,6 +396,7 @@ static void soc_update_by_current_and_time(float current_now, float delta_time,
|
|
|
/*休眠bms功耗 + 电芯自放电 28天 3% (28天1AH)*/
|
|
|
void soc_update_for_deepsleep(float sleep_time){
|
|
|
soc_update_by_current_and_time(-(0.32f + 1000.0f/(24.f * 28.f)), sleep_time, 0); //休眠功耗310uA(300uA + 10uA固定消耗)
|
|
|
+ current_sample_ts = shark_get_mseconds(); //唤醒后复位采集时间,如果不采集会重复计算
|
|
|
}
|
|
|
|
|
|
void soc_update(void){
|