BMS_Set_Error_States.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * BMS_Set_Error_States.c
  3. *
  4. * Created on: Nov 8, 2016
  5. * Author: le8041
  6. */
  7. #include "BMS_Master.h"
  8. /*
  9. * @brief check if Battery is charged or discharged
  10. * return true if discharged false if charged
  11. */
  12. uint32_t BMS_set_Error_check_if_stable_discharge(MASTER_CAN0_STRUCT_t* s) {
  13. // stable when mean value is bigger than -150mA
  14. uint8_t i;
  15. int16_t Current=0;
  16. for(i=0;i<UI_CURRENT_FIFO_SIZE;i++) {
  17. Current=Current + s->UI_Board.IbattFiFo[i] ;
  18. }
  19. Current = (Current*10) /UI_CURRENT_FIFO_SIZE ;
  20. if(Current > -150) {
  21. // stable discharge
  22. return TRUE;
  23. }
  24. //stable discharge
  25. return FALSE;
  26. }
  27. /*
  28. * @brief ceck if battery is charged stable over given amount of samples
  29. */
  30. uint32_t BMS_set_Error_check_if_stable_charge(MASTER_CAN0_STRUCT_t* s) {
  31. // stable when all values of FiFo are greater than -150
  32. uint8_t i;
  33. for(i=0;i<UI_CURRENT_FIFO_SIZE;i++) {
  34. if(s->UI_Board.IbattFiFo[i] *10 > -150) {
  35. // no stable charge
  36. return FALSE;
  37. }
  38. }
  39. //stable charge
  40. return TRUE;
  41. }
  42. /*
  43. * @brief check voltage levels Umin1 Umin2 Umin3 and set Error states accordingly
  44. * return True if everything is of return false if error occured
  45. */
  46. uint32_t BMS_Set_Error_check_Voltage_level_min(MASTER_CAN0_STRUCT_t* s){
  47. uint16_t Umin;
  48. float PvPwrAvailable;
  49. Umin=s->minCellVoltage;
  50. PvPwrAvailable=s->inverter.rxStruct.expectedInputPower;
  51. if(Umin < BMS_SOC_UMIN_3 ) {
  52. // Voltage level below Umin3
  53. // Kill Relays
  54. s->relayState.HS_closed=FALSE;
  55. s->relayState.LS_closed=FALSE;
  56. s->relayState.PRECHARGE_closed=FALSE;
  57. SwitchRelais( LS_RELAIS, 0);
  58. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  59. SwitchRelais( HS_RELAIS, 0);
  60. // set Error state 3 - should be alse set directly after test of Slave Voltage in Salve
  61. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_3,BMS_ERROR_CLASS_3);
  62. return FALSE;
  63. }
  64. else if(Umin < BMS_SOC_UMIN_2 && BMS_set_Error_check_if_stable_discharge(s) && !ErrorStackCheckifUmin2ErrorRecoveryPending(s) ) {
  65. // Voltage level below Umin2 and Battery is discharged
  66. // Kill Relays
  67. SwitchRelais( LS_RELAIS, 0);
  68. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  69. SwitchRelais( HS_RELAIS, 0);
  70. s->relayState.HS_closed=FALSE;
  71. s->relayState.LS_closed=FALSE;
  72. s->relayState.PRECHARGE_closed=FALSE;
  73. // set Error state 2
  74. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_2,BMS_ERROR_CLASS_2);
  75. return FALSE;
  76. }
  77. else if(Umin < BMS_SOC_UMIN_1 && BMS_set_Error_check_if_stable_discharge(s) && !ErrorStackCheckifUmin1ErrorRecoveryPending(s) ) {
  78. // Voltage Level below Umin1 and battery is discharged
  79. // Kill Relays
  80. SwitchRelais( LS_RELAIS, 0);
  81. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  82. SwitchRelais( HS_RELAIS, 0);
  83. s->relayState.HS_closed=FALSE;
  84. s->relayState.LS_closed=FALSE;
  85. s->relayState.PRECHARGE_closed=FALSE;
  86. // set Error state 1
  87. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMIN_1,BMS_ERROR_CLASS_1);
  88. return FALSE;
  89. }
  90. else {
  91. // everything is ok
  92. return TRUE;
  93. }
  94. }
  95. /*
  96. * @brief check max voltage level
  97. */
  98. uint32_t BMS_Set_Error_check_Voltage_level_max(MASTER_CAN0_STRUCT_t* s) {
  99. uint16_t Umax=s->maxCellVoltage;
  100. if(Umax > BMS_SOC_UMAX_3) {
  101. // set Error State 1
  102. // Kill Relays
  103. SwitchRelais( LS_RELAIS, 0);
  104. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  105. SwitchRelais( HS_RELAIS, 0);
  106. s->relayState.HS_closed=FALSE;
  107. s->relayState.LS_closed=FALSE;
  108. s->relayState.PRECHARGE_closed=FALSE;
  109. // set Error state 2
  110. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_3,BMS_ERROR_CLASS_3);
  111. return FALSE;
  112. }
  113. else if(Umax > BMS_SOC_UMAX_2) {
  114. // set Error State 1
  115. // Kill Relays
  116. SwitchRelais( LS_RELAIS, 0);
  117. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  118. SwitchRelais( HS_RELAIS, 0);
  119. s->relayState.HS_closed=FALSE;
  120. s->relayState.LS_closed=FALSE;
  121. s->relayState.PRECHARGE_closed=FALSE;
  122. // set Error state 2
  123. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_2,BMS_ERROR_CLASS_1);
  124. return FALSE;
  125. }
  126. else if(Umax > BMS_SOC_UMAX_1 ) {
  127. // set Error State 0 not implemented yet
  128. // TODO return TRUE; everything is ok
  129. return TRUE;
  130. }
  131. else {
  132. // everything is ok
  133. return TRUE;
  134. }
  135. }
  136. /*
  137. * @brief check if system exceeds maximum System Voltage in case customer plays around with the system
  138. */
  139. uint32_t BMS_Set_Error_check_System_voltage_level_max(MASTER_CAN0_STRUCT_t* s) {
  140. uint32_t Uges=s->systemVoltage;
  141. if(Uges >BMS_ERROR_THRESHOLD_UMAX_SYSTEM) {
  142. // Kill Relays
  143. SwitchRelais( LS_RELAIS, 0);
  144. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  145. SwitchRelais( HS_RELAIS, 0);
  146. s->relayState.HS_closed=FALSE;
  147. s->relayState.LS_closed=FALSE;
  148. s->relayState.PRECHARGE_closed=FALSE;
  149. // set Error state 3
  150. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_UMAX_SYSTEM,BMS_ERROR_CLASS_3);
  151. return FALSE;
  152. }
  153. else {
  154. //everything is ok
  155. return TRUE;
  156. }
  157. }
  158. /*
  159. *@brief do linear interpolation
  160. */
  161. float BMS_Set_Error_linear_interpolate(float x1,float x2,float x,float y1,float y2) {
  162. // solve linear eq y1= m*x1 + b
  163. // y2= m*x2 + b
  164. float m = (y2-y1)/(float)(x2-x1);
  165. float b = y1 - m*(float)(x1);
  166. //
  167. return m*(float)(x) + b;
  168. }
  169. /*
  170. *
  171. */
  172. float BMS_Set_Error_generate_Fcn(float* x_values,float* y_values,uint8_t NrOfPoints, float x) {
  173. uint8_t i;
  174. if(x < x_values[0]) {
  175. // value is to the left of the described area => return left most value
  176. return y_values[0];
  177. }
  178. else if( x> x_values[NrOfPoints -1] ) {
  179. // value is to the right of the described area => return right most value
  180. return y_values[NrOfPoints -1];
  181. }
  182. // find left x_value to x
  183. for(i=0;i< NrOfPoints; i++) {
  184. if(x_values[i] <= x && x_values[i+1] >= x ) {
  185. // x is between x_value[i] and x_value[i+1]
  186. return BMS_Set_Error_linear_interpolate(x_values[i],x_values[i+1],x,y_values[i],y_values[i+1]);
  187. }
  188. }
  189. }
  190. uint32_t BMS_Set_Error_Check_derating(MASTER_CAN0_STRUCT_t* s) {
  191. float Current = (float)(s->UI_Board.Ibatt*10);
  192. float minTemp = (float)s->minCellTemp;
  193. float maxTemp = (float)s->maxCellTemp;
  194. float SoC = s->SoC_estimator.SoC_percentage_smooth_FiFo[5];
  195. float capacity = 26.0 ; // capacity 26.0 Ah
  196. float temp_discharge_x[4]={0,25,40,55};
  197. float temp_discharge_y[4]={0.3,1.1,1.1,0};
  198. float temp_charge_x[5]={-5,0,25,40,50};
  199. float temp_charge_y[5]={0.3,0.6,1.1,1.1,0};
  200. float SoC_charge_x[5]={0,0.8,0.95,0.999,1};
  201. float SoC_charge_y[5]={25,25,2.5,2.5,0};
  202. float SoC_discharge_x[5]={0,0.001,0.05,0.2,1};
  203. float SoC_discharge_y[5]={0,2.5,2.5,25,25};
  204. s->currentLimits.I_max_charge_temp_max = BMS_Set_Error_generate_Fcn(temp_charge_x,temp_charge_y,5,maxTemp)*25*1000;
  205. s->currentLimits.I_max_charge_temp_min = BMS_Set_Error_generate_Fcn(temp_charge_x,temp_charge_y,5,minTemp)*25*1000;
  206. s->currentLimits.I_max_charge_SoC = BMS_Set_Error_generate_Fcn(SoC_charge_x,SoC_charge_y,5,SoC)*1000 *1.1 ;
  207. // at derating use most current SOC
  208. s->currentLimits.I_max_discharge_temp_max = BMS_Set_Error_generate_Fcn(temp_discharge_x,temp_discharge_y,4,maxTemp)*25*1000;
  209. s->currentLimits.I_max_discharge_temp_min = BMS_Set_Error_generate_Fcn(temp_discharge_x,temp_discharge_y,4,minTemp)*25*1000;
  210. s->currentLimits.I_max_discharge_SoC = BMS_Set_Error_generate_Fcn(SoC_discharge_x,SoC_discharge_y,5,s->SoC_estimator.SoC_percentage_smooth)*1000 *1.1 ;
  211. s->currentLimits.I_max_discharge_SoC_test=BMS_Set_Error_generate_Fcn(SoC_discharge_x,SoC_discharge_y,5,s->SoC_estimator.SoC_percentage_smooth)*1000 ;
  212. s->currentLimits.test_SoC = SoC;
  213. s->currentLimits.test_SoC_actual=s->SoC_estimator.SoC_percentage_smooth;
  214. if(Current < -100) {
  215. // Battery is charged
  216. // check temperature derating at tmin
  217. // check if low temperature is violated
  218. if((-1)*Current > s->currentLimits.I_max_charge_temp_min) {
  219. // current to high
  220. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
  221. // Kill Relays
  222. SwitchRelais( LS_RELAIS, 0);
  223. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  224. SwitchRelais( HS_RELAIS, 0);
  225. s->relayState.HS_closed=FALSE;
  226. s->relayState.LS_closed=FALSE;
  227. s->relayState.PRECHARGE_closed=FALSE;
  228. return FALSE;
  229. }
  230. // check temperature derating at tmax
  231. // check if low temperature is violated
  232. else if((-1)*Current > s->currentLimits.I_max_charge_temp_max ) {
  233. // current too high
  234. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
  235. // Kill Relays
  236. SwitchRelais( LS_RELAIS, 0);
  237. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  238. SwitchRelais( HS_RELAIS, 0);
  239. s->relayState.HS_closed=FALSE;
  240. s->relayState.LS_closed=FALSE;
  241. s->relayState.PRECHARGE_closed=FALSE;
  242. return FALSE;
  243. }
  244. // check SoC derating // normal derating curve + 10%
  245. else if((-1)*Current > s->currentLimits.I_max_charge_SoC) {
  246. // current too high
  247. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_CHARGE_OP,BMS_ERROR_CLASS_1);
  248. // Kill Relays
  249. SwitchRelais( LS_RELAIS, 0);
  250. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  251. SwitchRelais( HS_RELAIS, 0);
  252. s->relayState.HS_closed=FALSE;
  253. s->relayState.LS_closed=FALSE;
  254. s->relayState.PRECHARGE_closed=FALSE;
  255. return FALSE;
  256. }
  257. else {
  258. // derating is ok
  259. return TRUE;
  260. }
  261. }
  262. else if(Current > 100) {
  263. // Battery is discharged
  264. // check temperature derating at tmin
  265. // check if low temperature is violated
  266. if(Current > s->currentLimits.I_max_discharge_temp_min ) {
  267. // current to high
  268. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
  269. // Kill Relays
  270. SwitchRelais( LS_RELAIS, 0);
  271. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  272. SwitchRelais( HS_RELAIS, 0);
  273. s->relayState.HS_closed=FALSE;
  274. s->relayState.LS_closed=FALSE;
  275. s->relayState.PRECHARGE_closed=FALSE;
  276. return FALSE;
  277. }
  278. // check temperature derating at tmax
  279. // check if low temperature is violated
  280. else if(Current > s->currentLimits.I_max_discharge_temp_max ) {
  281. // current too high
  282. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
  283. // Kill Relays
  284. SwitchRelais( LS_RELAIS, 0);
  285. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  286. SwitchRelais( HS_RELAIS, 0);
  287. s->relayState.HS_closed=FALSE;
  288. s->relayState.LS_closed=FALSE;
  289. s->relayState.PRECHARGE_closed=FALSE;
  290. return FALSE;
  291. }
  292. // check SoC derating // normal derating curve + 10%
  293. else if(Current > s->currentLimits.I_max_discharge_SoC) {
  294. // current too high
  295. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_I_MAX_DISCHARGE_OP,BMS_ERROR_CLASS_1);
  296. // Kill Relays
  297. SwitchRelais( LS_RELAIS, 0);
  298. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  299. SwitchRelais( HS_RELAIS, 0);
  300. s->relayState.HS_closed=FALSE;
  301. s->relayState.LS_closed=FALSE;
  302. s->relayState.PRECHARGE_closed=FALSE;
  303. return FALSE;
  304. }
  305. else {
  306. // derating is ok
  307. return TRUE;
  308. }
  309. }
  310. else {
  311. // nothing happens
  312. return TRUE;
  313. }
  314. return TRUE;
  315. }
  316. /*
  317. * @brief check if UI has opend relays
  318. */
  319. uint32_t BMS_Set_Error_UI_Relais(MASTER_CAN0_STRUCT_t* s) {
  320. ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_RELAY_OPEN,BMS_ERROR_CLASS_2);
  321. // Kill Relays
  322. SwitchRelais( LS_RELAIS, 0);
  323. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  324. SwitchRelais( HS_RELAIS, 0);
  325. s->relayState.HS_closed=FALSE;
  326. s->relayState.LS_closed=FALSE;
  327. s->relayState.PRECHARGE_closed=FALSE;
  328. return TRUE;
  329. }
  330. uint32_t BMS_Set_Error_CAN1_Timeout(MASTER_CAN0_STRUCT_t* s) {
  331. // CAN 1 Timeout Has occured
  332. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_EXTERN_CAN_ERROR,BMS_ERROR_CLASS_1);
  333. // Kill Relays
  334. SwitchRelais( LS_RELAIS, 0);
  335. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  336. SwitchRelais( HS_RELAIS, 0);
  337. s->relayState.HS_closed=FALSE;
  338. s->relayState.LS_closed=FALSE;
  339. s->relayState.PRECHARGE_closed=FALSE;
  340. return TRUE;
  341. }
  342. /*
  343. * @brief check if current mesured by UI is consitent wit current measured by Inverter
  344. */
  345. uint32_t BMS_Set_Error_Check_current_consitency(MASTER_CAN0_STRUCT_t* s) {
  346. uint8_t i=0;
  347. float I_av_ui =0 ;
  348. float I_av_inverter =0;
  349. for(i=0; i<UI_CURRENT_FIFO_SIZE;i++) {
  350. I_av_ui = I_av_ui + (float)(s->UI_Board.IbattFiFo[i]);
  351. }
  352. I_av_ui = I_av_ui *10; // convert to mA
  353. I_av_ui = I_av_ui /UI_CURRENT_FIFO_SIZE ; // calc mean
  354. for(i=0;i<UI_CURRENT_FIFO_SIZE;i++ ) {
  355. I_av_inverter = I_av_inverter + s->UI_Board.Ibatt_Inverter_FIFO[i];
  356. }
  357. I_av_inverter = I_av_inverter *1000 /UI_CURRENT_FIFO_SIZE ; // convert to mA and calc mean
  358. // compare
  359. s->UiInverterInconsistency = bms_SoC_get_norm(I_av_inverter) - bms_SoC_get_norm(I_av_ui) ;
  360. if( s->UiInverterInconsistency > BMS_MAX_CURRENT_INCONSITENCY_MA || s->UiInverterInconsistency <( (-1) * BMS_MAX_CURRENT_INCONSITENCY_MA) ) {
  361. // error has occured
  362. ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_CURRENT_INCONSIST,BMS_ERROR_CLASS_1);
  363. // Kill Relays
  364. SwitchRelais( LS_RELAIS, 0);
  365. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  366. SwitchRelais( HS_RELAIS, 0);
  367. s->relayState.HS_closed=FALSE;
  368. s->relayState.LS_closed=FALSE;
  369. s->relayState.PRECHARGE_closed=FALSE;
  370. return TRUE;
  371. }
  372. return TRUE;
  373. }
  374. /*
  375. * @brief check if Voltage measured by UI and by Summation of Slaves are equal
  376. */
  377. uint32_t BMS_Set_Error_Check_voltage_inconsitency(MASTER_CAN0_STRUCT_t* s) {
  378. uint8_t i=0;
  379. uint32_t addedCellVoltage_mean=0;
  380. uint32_t UI_Board_voltage_mean=0;
  381. for(i=0;i<UI_VOLTAGE_FIFO_SIZE;i++) {
  382. addedCellVoltage_mean = addedCellVoltage_mean + s->UI_Board.SystemVoltageFiFo[i];
  383. UI_Board_voltage_mean = UI_Board_voltage_mean + s->UI_Board.UbattFiFo[i];
  384. }
  385. addedCellVoltage_mean = addedCellVoltage_mean /UI_VOLTAGE_FIFO_SIZE ; // voltage in mV
  386. UI_Board_voltage_mean = UI_Board_voltage_mean *100 / UI_VOLTAGE_FIFO_SIZE ;
  387. s->UiSlaveInconsistency = bms_SoC_get_norm((float)addedCellVoltage_mean - (float)UI_Board_voltage_mean) ;
  388. // if voltage error is bigger than threshold and All relais are closed kill relays
  389. if((s->UiSlaveInconsistency > (addedCellVoltage_mean * 0.05) && s->RunMode.onCounter > (UI_VOLTAGE_FIFO_SIZE* CAN0_MAX_NR_OF_SLAVES)) &&
  390. (s->relayState.HS_closed==TRUE && s->relayState.LS_closed==TRUE && s->relayState.PRECHARGE_closed==TRUE && s->UI_Board.Errors.RelayOpen == FALSE) ){
  391. ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_VOLTAGE_INCONSIST,BMS_ERROR_CLASS_1);
  392. // Kill Relays
  393. SwitchRelais( LS_RELAIS, 0);
  394. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  395. SwitchRelais( HS_RELAIS, 0);
  396. s->relayState.HS_closed=FALSE;
  397. s->relayState.LS_closed=FALSE;
  398. s->relayState.PRECHARGE_closed=FALSE;
  399. s->RunMode.onCounter=0;
  400. return TRUE;
  401. }
  402. return TRUE;
  403. }
  404. /*
  405. * @brief check if UI sends error flags
  406. */
  407. uint32_t BMS_set_Error_Check_UI_Flags(MASTER_CAN0_STRUCT_t* s) {
  408. if(s->UI_Board.Errors.OffsetError ==TRUE) {
  409. ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_OFFSET_ERROR,BMS_ERROR_CLASS_2);
  410. // Kill Relays
  411. SwitchRelais( LS_RELAIS, 0);
  412. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  413. SwitchRelais( HS_RELAIS, 0);
  414. s->relayState.HS_closed=FALSE;
  415. s->relayState.LS_closed=FALSE;
  416. s->relayState.PRECHARGE_closed=FALSE;
  417. }
  418. if(s->UI_Board.Errors.SupplyError == TRUE) {
  419. ErrorStackPushUiError(s,BMS_ERROR_STACK_UI_SUPPLY_VOLTAGE,BMS_ERROR_CLASS_2);
  420. // Kill Relays
  421. SwitchRelais( LS_RELAIS, 0);
  422. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  423. SwitchRelais( HS_RELAIS, 0);
  424. s->relayState.HS_closed=FALSE;
  425. s->relayState.LS_closed=FALSE;
  426. s->relayState.PRECHARGE_closed=FALSE;
  427. }
  428. return TRUE;
  429. }