| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #include "soc.h"
- #include "app/sox/measure.h"
- #include "app/sox/measure_task.h"
- #include "app/nv_storage.h"
- #include "libs/logger.h"
- #include "health.h"
- #include "state.h"
- static soc_t _soc;
- static uint8_t charing = 0;
- static u64 time_ms = 0;
- static float _charger_coefficient = 1.0f;
- static float _discharger_coefficient = 1.0f;
- static void calibrate_soc_by_ocv(void);
- void soc_init(void){
- set_log_level(MOD_SOC, L_debug);
- time_ms = shark_get_mseconds();
- if (nv_restore_soc() != 0){
- soc_warning("SOC: nv storage is not inited, use default value!!\n");
- _soc.coulomb_min = 0;
- _soc.coulomb_max = 30.0f * 3600.0f; //30HA,这个值最总需要soh模块给
- calibrate_soc_by_ocv();
- nv_save_soc();
- }
- }
- //初始上电或者nv出问题后,通过开路电压对soc做一次初略校准
- static void calibrate_soc_by_ocv(void){
- uint16_t pack_vol = 0;
- for (int i = 0; i < CELLS_NUM; i++){
- pack_vol += measure_value()->cell_vol[i];
- }
- if (pack_vol < (2700 * CELLS_NUM)){
- _soc.capacity = 0;
- }else if (pack_vol < (2950 * CELLS_NUM)){
- _soc.capacity = 5;
- }else if (pack_vol < (3200 * CELLS_NUM)){
- _soc.capacity = 15;
- }else if (pack_vol < (3400 * CELLS_NUM)){
- _soc.capacity = 25;
- }else if (pack_vol < (3500 * CELLS_NUM)){
- _soc.capacity = 85;
- }else if (pack_vol < (3550 * CELLS_NUM)){
- _soc.capacity = 95;
- }else {
- _soc.capacity = 100;
- }
- _soc.coulomb_now = _soc.coulomb_max * _soc.capacity / 100.0f;
- soc_warning("SOC: calibrate_soc_by_ocv -> capacity = %d, pack_voltage = %d\n", _soc.capacity, pack_vol);
- }
- static __inline__ float _delta_time(void){
- u32 delta = shark_get_mseconds() - time_ms;
- time_ms = shark_get_mseconds();
- return (float)delta / (1000.0f); //秒
- }
- void soc_update(void){
- if (!charing && bms_state_get()->charging){
- _soc.charger_coulomb = 0;//clear charing
- charing = 1;
- }else if (charing && !bms_state_get()->charging){
- charing = 0;
- _soc.dischrger_coulomb = 0; //clear discharger
- }
- float current = measure_value()->load_current / 1000.0f; //A
- float delta_q = current * _delta_time();
- if (charing){
- delta_q = delta_q * _charger_coefficient;
- _soc.charger_coulomb += abs(delta_q);
- }else {
- delta_q = delta_q * _discharger_coefficient;
- _soc.dischrger_coulomb += abs(delta_q); //转为正数
- }
- _soc.coulomb_now += delta_q; //充电加, 放电减
- if (_soc.coulomb_now > _soc.coulomb_max){
- _soc.coulomb_now = _soc.coulomb_max;
- }else if (_soc.coulomb_now < _soc.coulomb_min){
- _soc.coulomb_now = _soc.coulomb_min;
- }
- uint8_t old_cap = _soc.capacity;
- _soc.capacity = (_soc.coulomb_now - _soc.coulomb_min)/(_soc.coulomb_max - _soc.coulomb_min) * 100;
- if (old_cap != _soc.capacity) {
- nv_save_soc();
- }
- }
- soc_t *get_soc(void){
- return &_soc;
- }
|