BMS_Set_Error_States.c 15 KB

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