soc.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "soc.h"
  2. #include "app/sox/measure.h"
  3. #include "app/sox/measure_task.h"
  4. #include "app/nv_storage.h"
  5. #include "libs/logger.h"
  6. #include "health.h"
  7. #include "state.h"
  8. static soc_t _soc;
  9. static uint8_t charing = 0;
  10. static u64 time_ms = 0;
  11. static float _charger_coefficient = 1.0f;
  12. static float _discharger_coefficient = 1.0f;
  13. static void calibrate_soc_by_ocv(void);
  14. void soc_init(void){
  15. set_log_level(MOD_SOC, L_debug);
  16. time_ms = shark_get_mseconds();
  17. if (nv_restore_soc() != 0){
  18. soc_warning("SOC: nv storage is not inited, use default value!!\n");
  19. _soc.coulomb_min = 0;
  20. _soc.coulomb_max = 30.0f * 3600.0f; //30HA,这个值最总需要soh模块给
  21. calibrate_soc_by_ocv();
  22. nv_save_soc();
  23. }
  24. }
  25. //初始上电或者nv出问题后,通过开路电压对soc做一次初略校准
  26. static void calibrate_soc_by_ocv(void){
  27. uint16_t pack_vol = 0;
  28. for (int i = 0; i < CELLS_NUM; i++){
  29. pack_vol += measure_value()->cell_vol[i];
  30. }
  31. if (pack_vol < (2700 * CELLS_NUM)){
  32. _soc.capacity = 0;
  33. }else if (pack_vol < (2950 * CELLS_NUM)){
  34. _soc.capacity = 5;
  35. }else if (pack_vol < (3200 * CELLS_NUM)){
  36. _soc.capacity = 15;
  37. }else if (pack_vol < (3400 * CELLS_NUM)){
  38. _soc.capacity = 25;
  39. }else if (pack_vol < (3500 * CELLS_NUM)){
  40. _soc.capacity = 85;
  41. }else if (pack_vol < (3550 * CELLS_NUM)){
  42. _soc.capacity = 95;
  43. }else {
  44. _soc.capacity = 100;
  45. }
  46. _soc.coulomb_now = _soc.coulomb_max * _soc.capacity / 100.0f;
  47. soc_warning("SOC: calibrate_soc_by_ocv -> capacity = %d, pack_voltage = %d\n", _soc.capacity, pack_vol);
  48. }
  49. static __inline__ float _delta_time(void){
  50. u32 delta = shark_get_mseconds() - time_ms;
  51. time_ms = shark_get_mseconds();
  52. return (float)delta / (1000.0f); //秒
  53. }
  54. void soc_update(void){
  55. if (!charing && bms_state_get()->charging){
  56. _soc.charger_coulomb = 0;//clear charing
  57. charing = 1;
  58. }else if (charing && !bms_state_get()->charging){
  59. charing = 0;
  60. _soc.dischrger_coulomb = 0; //clear discharger
  61. }
  62. float current = measure_value()->load_current / 1000.0f; //A
  63. float delta_q = current * _delta_time();
  64. if (charing){
  65. delta_q = delta_q * _charger_coefficient;
  66. _soc.charger_coulomb += abs(delta_q);
  67. }else {
  68. delta_q = delta_q * _discharger_coefficient;
  69. _soc.dischrger_coulomb += abs(delta_q); //转为正数
  70. }
  71. _soc.coulomb_now += delta_q; //充电加, 放电减
  72. if (_soc.coulomb_now > _soc.coulomb_max){
  73. _soc.coulomb_now = _soc.coulomb_max;
  74. }else if (_soc.coulomb_now < _soc.coulomb_min){
  75. _soc.coulomb_now = _soc.coulomb_min;
  76. }
  77. uint8_t old_cap = _soc.capacity;
  78. _soc.capacity = (_soc.coulomb_now - _soc.coulomb_min)/(_soc.coulomb_max - _soc.coulomb_min) * 100;
  79. if (old_cap != _soc.capacity) {
  80. nv_save_soc();
  81. }
  82. }
  83. soc_t *get_soc(void){
  84. return &_soc;
  85. }