|
@@ -31,6 +31,7 @@ static least_square_t discharger_cell_coef;
|
|
|
static least_square_t discharger_capacity_coef;
|
|
static least_square_t discharger_capacity_coef;
|
|
|
static shark_timer_t least_square_timer = {.handler = _least_square_timer_handler};
|
|
static shark_timer_t least_square_timer = {.handler = _least_square_timer_handler};
|
|
|
static int least_square_time = 0;
|
|
static int least_square_time = 0;
|
|
|
|
|
+static int least_square_started = 0;
|
|
|
#define LEAST_SQUARE_STEP_TIME 1000
|
|
#define LEAST_SQUARE_STEP_TIME 1000
|
|
|
#endif
|
|
#endif
|
|
|
void soc_init(void){
|
|
void soc_init(void){
|
|
@@ -56,23 +57,36 @@ void soc_init(void){
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#if LEAST_SQUARE==1
|
|
#if LEAST_SQUARE==1
|
|
|
-static void start_least_square(void){
|
|
|
|
|
- least_square_init(&discharger_vol_coef, 10);
|
|
|
|
|
- least_square_init(&discharger_cell_coef, 10);
|
|
|
|
|
- least_square_init(&discharger_capacity_coef, 10);
|
|
|
|
|
- least_square_time = 0;
|
|
|
|
|
- shark_timer_post(&least_square_timer, LEAST_SQUARE_STEP_TIME);
|
|
|
|
|
|
|
+static void start_least_square(int start){
|
|
|
|
|
+ if (start && !least_square_started) {
|
|
|
|
|
+ least_square_init(&discharger_vol_coef, 100);
|
|
|
|
|
+ least_square_init(&discharger_cell_coef, 100);
|
|
|
|
|
+ least_square_init(&discharger_capacity_coef, 100);
|
|
|
|
|
+ least_square_time = 0;
|
|
|
|
|
+ least_square_started = 1;
|
|
|
|
|
+ shark_timer_post(&least_square_timer, LEAST_SQUARE_STEP_TIME);
|
|
|
|
|
+ }else if (!start && least_square_started){
|
|
|
|
|
+ least_square_time = 0;
|
|
|
|
|
+ least_square_started = 0;
|
|
|
|
|
+ shark_timer_cancel(&least_square_timer);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void _least_square_timer_handler(shark_timer_t *timer){
|
|
static void _least_square_timer_handler(shark_timer_t *timer){
|
|
|
if (least_square_put(&discharger_vol_coef, least_square_time, bms_state_get()->pack_voltage/1000.0f) == 1) {
|
|
if (least_square_put(&discharger_vol_coef, least_square_time, bms_state_get()->pack_voltage/1000.0f) == 1) {
|
|
|
soc_error("voltage: A = %f, B = %f, v: %f\n", discharger_vol_coef.Cb, discharger_vol_coef.Ka, get_y_by_x(&discharger_vol_coef, least_square_time));
|
|
soc_error("voltage: A = %f, B = %f, v: %f\n", discharger_vol_coef.Cb, discharger_vol_coef.Ka, get_y_by_x(&discharger_vol_coef, least_square_time));
|
|
|
|
|
+ int delta = get_x_by_y(&discharger_vol_coef, bms_state_get()->pack_voltage/1000.0f) - get_x_by_y(&discharger_vol_coef, bms_health_pack_lower_voltage()/1000.0f);
|
|
|
|
|
+ soc_error("remain %d s to reach lower pack voltage\n", delta);
|
|
|
}
|
|
}
|
|
|
if (least_square_put(&discharger_cell_coef, least_square_time, bms_state_get()->cell_min_vol/1000.0f) == 1) {
|
|
if (least_square_put(&discharger_cell_coef, least_square_time, bms_state_get()->cell_min_vol/1000.0f) == 1) {
|
|
|
soc_error("cell: A = %f, B = %f, v: %f\n", discharger_cell_coef.Cb, discharger_cell_coef.Ka, get_y_by_x(&discharger_cell_coef, least_square_time));
|
|
soc_error("cell: A = %f, B = %f, v: %f\n", discharger_cell_coef.Cb, discharger_cell_coef.Ka, get_y_by_x(&discharger_cell_coef, least_square_time));
|
|
|
|
|
+ int delta = get_x_by_y(&discharger_cell_coef, bms_state_get()->cell_min_vol/1000.0f) - get_x_by_y(&discharger_cell_coef, bms_health_cell_lower_voltage()/1000.0f);
|
|
|
|
|
+ soc_error("remain %d s to reach lower cell voltage\n", delta);
|
|
|
}
|
|
}
|
|
|
if (least_square_put(&discharger_capacity_coef, least_square_time, _soc.coulomb_now/3600.0f) == 1) {
|
|
if (least_square_put(&discharger_capacity_coef, least_square_time, _soc.coulomb_now/3600.0f) == 1) {
|
|
|
soc_error("capacity: A = %f, B = %f, c: %f\n", discharger_capacity_coef.Cb, discharger_capacity_coef.Ka, get_y_by_x(&discharger_capacity_coef, least_square_time));
|
|
soc_error("capacity: A = %f, B = %f, c: %f\n", discharger_capacity_coef.Cb, discharger_capacity_coef.Ka, get_y_by_x(&discharger_capacity_coef, least_square_time));
|
|
|
|
|
+ int delta = get_x_by_y(&discharger_capacity_coef, _soc.coulomb_now/3600.0f) - get_x_by_y(&discharger_capacity_coef, _soc.coulomb_min/3600.0f);
|
|
|
|
|
+ soc_error("remain %d s to reach 0 min AH\n", delta);
|
|
|
}
|
|
}
|
|
|
least_square_time ++;
|
|
least_square_time ++;
|
|
|
shark_timer_post(&least_square_timer, LEAST_SQUARE_STEP_TIME);
|
|
shark_timer_post(&least_square_timer, LEAST_SQUARE_STEP_TIME);
|
|
@@ -278,6 +292,9 @@ void soc_update(void){
|
|
|
if (_soc.capacity < 100) {
|
|
if (_soc.capacity < 100) {
|
|
|
is_force_full = 0;
|
|
is_force_full = 0;
|
|
|
}
|
|
}
|
|
|
|
|
+#if LEAST_SQUARE==1
|
|
|
|
|
+ start_least_square(0);
|
|
|
|
|
+#endif
|
|
|
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;
|
|
@@ -289,7 +306,11 @@ void soc_update(void){
|
|
|
}
|
|
}
|
|
|
soc_warning("changed to dischargering, current = %d\n", measure_value()->load_current);
|
|
soc_warning("changed to dischargering, current = %d\n", measure_value()->load_current);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+#if LEAST_SQUARE==1
|
|
|
|
|
+ if(!chargering && abs(measure_value()->load_current) >= 5000){
|
|
|
|
|
+ start_least_square(1);
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
|
|
soc_update_by_current_and_time(measure_value()->load_current, _delta_time(), pre_chargering);
|
|
|
soc_update_charger_remain_time();
|
|
soc_update_charger_remain_time();
|
|
|
}
|
|
}
|