BMS_Connect_Inverter.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /*
  2. * BMS_Connect_Inverter.c
  3. *
  4. * Created on: Mar 14, 2017
  5. * Author: le8041
  6. */
  7. #include "BMS_Master.h"
  8. #include "BMS_Connect_Inverter.h"
  9. float get_Norm(float value) {
  10. if(value >=0) {
  11. return value;
  12. }
  13. else {
  14. return (-1)*value;
  15. }
  16. }
  17. uint32_t check_if_voltage_equal(MASTER_CAN0_STRUCT_t* s) {
  18. float U_ui=(float)s->UI_Board.Ubatt *100 ;
  19. float U_cells=(float)s->systemVoltage ;
  20. if(get_Norm(U_ui - U_cells) < U_cells *BMS_CONNECT_VOLTAGE_EQUAL_MARGIN) {
  21. return TRUE;
  22. }
  23. else {
  24. return FALSE;
  25. }
  26. }
  27. uint32_t check_if_Ui_voltage_is_stable(MASTER_CAN0_STRUCT_t* s) {
  28. // find highest and lowest UI-Voltage
  29. uint8_t i=0;
  30. uint32_t Umin=s->UI_Board.UbattFiFo[0];
  31. uint32_t Umax=s->UI_Board.UbattFiFo[0];
  32. for(i=0;i<UI_VOLTAGE_STABILITY_CHECK;i++) {
  33. if(Umin > s->UI_Board.UbattFiFo[i] ) {
  34. Umin = s->UI_Board.UbattFiFo[i];
  35. }
  36. if(Umax < s->UI_Board.UbattFiFo[i]) {
  37. Umax = s->UI_Board.UbattFiFo[i];
  38. }
  39. }
  40. if ((Umax - Umin) *100 > UI_VOLTAGE_STABILITY_MAX_DEVIATION*1000) {
  41. // max deviation reached
  42. return FALSE;
  43. }
  44. else {
  45. return TRUE;
  46. }
  47. }
  48. /*
  49. * @brief check if expected voltage is at clamps
  50. * if return = FALSE shortcircuit at clamps
  51. */
  52. uint32_t check_if_expected_clamp_voltage_occures(MASTER_CAN0_STRUCT_t* s) {
  53. float U_ui=(float)s->UI_Board.Ubatt *100 ;
  54. if(get_Norm(U_ui - CONNECT_INVERTER_SHORT_CIRCUIT_TEST_VOLTAGE) < CONNECT_INVERTER_SHORT_CIRCUIT_TEST_VOLTAGE *BMS_CONNECT_VOLTAGE_TEST_MARGIN_MV) {
  55. return TRUE;
  56. }
  57. else {
  58. return FALSE;
  59. }
  60. }
  61. uint32_t OPModeFSM(MASTER_CAN0_STRUCT_t* s){
  62. float SoC=s->SoC_estimator.SoC_percentage_smooth;
  63. // check if Inverster still allows startup
  64. if(s->inverter.rxStruct.BatteryControlStatus.batteryDisconnected == 1 && \
  65. s->inverter.rxStruct.BatteryControlStatus.relayTestPermitted==0 && \
  66. s->inverter.rxStruct.BatteryControlStatus.readyToStart ==0) {
  67. if(s->RunMode.OperationMode == OP_MODE_INIT ||\
  68. s->RunMode.OperationMode == OP_MODE_CHECK_STARTUP_CONDITIONS || \
  69. s->RunMode.OperationMode == BAT_CONNECT_CHECK_SHORTCIRCUIT_REQUEST_RELAY_TEST) {
  70. }
  71. else {
  72. // FSM not in first 3 states => go back to initial state
  73. s->RunMode.OperationMode = OP_MODE_INIT;
  74. // open all relays
  75. SwitchRelais( HS_RELAIS, 0);
  76. s->relayState.HS_closed=FALSE;
  77. SwitchRelais( LS_RELAIS, 0);
  78. s->relayState.LS_closed=FALSE;
  79. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  80. s->relayState.PRECHARGE_closed=FALSE;
  81. }
  82. }
  83. switch(s->RunMode.OperationMode) {
  84. case OP_MODE_INIT:
  85. // just jump to checkup startup conditions
  86. s->RunMode.OperationMode=OP_MODE_CHECK_STARTUP_CONDITIONS;
  87. s->RunMode.BatteryExtraStatus.value=1;
  88. CLEAR_OUTPIN(PIN_REGNR_LED4);
  89. return TRUE;
  90. break;
  91. case OP_MODE_CHECK_STARTUP_CONDITIONS:
  92. if(s->allValuesInitialized==TRUE) {
  93. // all values initalized and no error occured
  94. // => Startup conditions apply => start startup
  95. // check if all relays are open
  96. if(s->relayState.HS_closed==FALSE && s->relayState.LS_closed == FALSE && s->relayState.PRECHARGE_closed ==FALSE) {
  97. // everything ok oll relay open
  98. }
  99. else{
  100. // relays somehow closed open relays
  101. SwitchRelais( HS_RELAIS, 0);
  102. s->relayState.HS_closed=FALSE;
  103. SwitchRelais( LS_RELAIS, 0);
  104. s->relayState.LS_closed=FALSE;
  105. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  106. s->relayState.PRECHARGE_closed=FALSE;
  107. }
  108. // set battery status
  109. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  110. s->RunMode.BatteryExtraStatus.readyToStart=0;
  111. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  112. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  113. s->RunMode.OperationMode=BAT_CONNECT_CHECK_SHORTCIRCUIT_REQUEST_RELAY_TEST;
  114. s->RunMode.onCounter=0;
  115. return TRUE;
  116. }
  117. else {
  118. // wait till all values are initialiezd
  119. s->RunMode.OperationMode=OP_MODE_CHECK_STARTUP_CONDITIONS;
  120. return TRUE;
  121. }
  122. break;
  123. case BAT_CONNECT_CHECK_SHORTCIRCUIT_REQUEST_RELAY_TEST:
  124. // set battery status - request relay test by inverter
  125. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  126. s->RunMode.BatteryExtraStatus.readyToStart=0;
  127. s->RunMode.BatteryExtraStatus.requestRelayTest=1;
  128. if(s->inverter.rxStruct.BatteryControlStatus.relayTestPermitted == TRUE) {
  129. // relay tests are enabled for inverter side
  130. // inverter does its own relais tests
  131. // inverter sets Voltage at clamps to 100V
  132. // inverter disconnects from grid - Power from PV
  133. s->RunMode.OperationMode=BAT_CONNECT_CHECK_SHORTCIRCUIT_NET_DISCONNECTED;
  134. return TRUE;
  135. }
  136. else {
  137. // wait for relay test permmited flag from inverter
  138. s->RunMode.OperationMode=BAT_CONNECT_CHECK_SHORTCIRCUIT_REQUEST_RELAY_TEST;
  139. return TRUE;
  140. }
  141. return TRUE;
  142. break;
  143. case BAT_CONNECT_CHECK_SHORTCIRCUIT_NET_DISCONNECTED:
  144. // grid is now disconnected
  145. s->RunMode.OperationMode=BAT_CONNECT_CHECK_SHORTCIRCUIT_CHECK_CLAMPS;
  146. return TRUE;
  147. break;
  148. case BAT_CONNECT_CHECK_SHORTCIRCUIT_CHECK_CLAMPS:
  149. if(check_if_expected_clamp_voltage_occures(s) == FALSE) {
  150. // voltage is not as expected, therefore shorcircuit exitsts
  151. // DONT TURN ON BATTERY
  152. s->RunMode.OperationMode=BAT_CONNECT_ERROR_SHORTCIRCUIT_DETECTED;
  153. return TRUE;
  154. }
  155. else {
  156. // everything ok,proceed
  157. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_LS_STUCK;
  158. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  159. return TRUE;
  160. }
  161. return TRUE;
  162. break;
  163. case BAT_CONNECT_CHECK_IF_LS_STUCK:
  164. // close PC RELAIS
  165. // IF PC Relays is closed and LS relay is stuck closed Battery voltage should be detectet
  166. SwitchRelais( PRE_CHARGE_RELAIS, 1);
  167. s->relayState.PRECHARGE_closed=TRUE;
  168. if(s->RunMode.OperationModeTimestamp + CONNECT_INVERTER_MIN_WAIT_TIME_MS <= Global_1msCounter) {
  169. // everything ok, proceed
  170. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_LS_OR_PC_BROKEN;
  171. return TRUE;
  172. }
  173. else if(check_if_voltage_equal(s)) {
  174. // Battery voltage == clamp voltage => LS is stuck close: ERROR
  175. s->RunMode.OperationMode=BAT_CONNECT_ERROR_LS_STUCK;
  176. return TRUE;
  177. }
  178. else {
  179. //wait
  180. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_LS_STUCK;
  181. return TRUE;
  182. }
  183. return TRUE;
  184. break;
  185. case BAT_CONNECT_CHECK_IF_LS_OR_PC_BROKEN:
  186. // close LS and PRECHARGE
  187. // expected current dependend on Battery voltage, therefore not clear yet
  188. // skip
  189. SwitchRelais( LS_RELAIS, 1);
  190. s->relayState.LS_closed=TRUE;
  191. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  192. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_LS_OR_PC_BROKEN_OK;
  193. return TRUE;
  194. break;
  195. case BAT_CONNECT_CHECK_IF_LS_OR_PC_BROKEN_OK:
  196. // open PC RELAIS AGAIN
  197. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  198. s->relayState.PRECHARGE_closed=FALSE;
  199. if(s->RunMode.OperationModeTimestamp + 1000 <= Global_1msCounter) {
  200. // wait for LS to be open everything ok, proceed
  201. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  202. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_HS_STUCK;
  203. return TRUE;
  204. }
  205. else {
  206. //wait
  207. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_LS_OR_PC_BROKEN_OK;
  208. }
  209. return TRUE;
  210. break;
  211. case BAT_CONNECT_CHECK_IF_HS_STUCK:
  212. // check if 100V is at clamps again
  213. if(check_if_expected_clamp_voltage_occures(s)) {
  214. // everything ok
  215. s->RunMode.OperationMode=BAT_CONNECT_TEST_COMPLETE;
  216. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  217. return TRUE;
  218. }
  219. else if(s->RunMode.OperationModeTimestamp + CONNECT_INVERTER_MAX_WAIT_TIME_MS <= Global_1msCounter) {
  220. // timeout, error occured, HS relays is stuck
  221. s->RunMode.OperationMode=BAT_CONNECT_ERROR_HS_STUCK;
  222. return TRUE;
  223. }
  224. else {
  225. //wait
  226. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_HS_STUCK;
  227. return TRUE;
  228. }
  229. return TRUE;
  230. break;
  231. case BAT_CONNECT_TEST_COMPLETE:
  232. // all tests are complete
  233. // close PC AND LS
  234. SwitchRelais( HS_RELAIS, 0);
  235. s->relayState.HS_closed=FALSE;
  236. SwitchRelais( LS_RELAIS, 1);
  237. s->relayState.LS_closed=TRUE;
  238. SwitchRelais( PRE_CHARGE_RELAIS, 1);
  239. s->relayState.PRECHARGE_closed=TRUE;
  240. //disable relays test mode
  241. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  242. s->RunMode.BatteryExtraStatus.readyToStart=1;
  243. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  244. // wait for relays to open
  245. if(s->RunMode.OperationModeTimestamp + 1000 <= Global_1msCounter) {
  246. s->RunMode.OperationMode=BAT_CONNECT_WAIT_FOR_READY_TO_START_ACK;
  247. return TRUE;
  248. }
  249. else {
  250. //wait
  251. s->RunMode.OperationMode=BAT_CONNECT_TEST_COMPLETE;
  252. return TRUE;
  253. }
  254. return TRUE;
  255. break;
  256. case BAT_CONNECT_CLOSE_LS:
  257. // set Low Side relays unnecessary state because ls already closed
  258. s->relayState.LS_closed=TRUE;
  259. SwitchRelais( LS_RELAIS, 1);
  260. if(s->RunMode.OperationModeTimestamp + 1000 <= Global_1msCounter) {
  261. s->RunMode.OperationMode=BAT_CONNECT_CLOSE_PC;
  262. s->RunMode.OperationModeTimestamp = Global_1msCounter;
  263. return TRUE;
  264. }
  265. else {
  266. s->RunMode.OperationMode= BAT_CONNECT_CLOSE_LS;
  267. return TRUE;
  268. }
  269. break;
  270. case BAT_CONNECT_CLOSE_PC:
  271. // close precharge relays
  272. s->relayState.PRECHARGE_closed=TRUE;
  273. SwitchRelais( PRE_CHARGE_RELAIS, 1);
  274. if(s->RunMode.OperationModeTimestamp + 1000 <= Global_1msCounter) {
  275. s->RunMode.OperationMode=BAT_CONNECT_WAIT_FOR_READY_TO_START_ACK;
  276. s->RunMode.OperationModeTimestamp = Global_1msCounter;
  277. return TRUE;
  278. }
  279. else {
  280. s->RunMode.OperationMode= BAT_CONNECT_CLOSE_PC;
  281. return TRUE;
  282. }
  283. return TRUE;
  284. break;
  285. case BAT_CONNECT_WAIT_FOR_READY_TO_START_ACK:
  286. //set ready to start bit
  287. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  288. s->RunMode.BatteryExtraStatus.readyToStart=1;
  289. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  290. // wait till inverter has connected
  291. if(s->inverter.rxStruct.BatteryControlStatus.readyToStart ==TRUE) {
  292. s->RunMode.OperationMode=BAT_CONNECT_WAIT_FOR_VOLTAGE_IS_EQUAL;
  293. return TRUE;
  294. }
  295. else {
  296. //wait;
  297. return TRUE;
  298. }
  299. return TRUE;
  300. break;
  301. case BAT_CONNECT_WAIT_FOR_VOLTAGE_IS_EQUAL:
  302. if(check_if_voltage_equal(s)== TRUE) {
  303. // go to voltage stability check
  304. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_VOLTAGE_IS_STABLE;
  305. s->RunMode.OperationModeTimestamp = Global_1msCounter;
  306. return TRUE;
  307. }
  308. else {
  309. // wait for voltage to equalize
  310. s->RunMode.OperationMode=BAT_CONNECT_WAIT_FOR_VOLTAGE_IS_EQUAL;
  311. return TRUE;
  312. }
  313. return TRUE;
  314. break;
  315. case BAT_CONNECT_CHECK_IF_VOLTAGE_IS_STABLE:
  316. if(check_if_voltage_equal(s)== FALSE) {
  317. // return to BAT_CONNECT_CLOSE_PC and try again
  318. s->RunMode.OperationMode= BAT_CONNECT_CLOSE_PC;
  319. return TRUE;
  320. }
  321. else if((s->RunMode.OperationModeTimestamp + CONNECT_INVERTER_MIN_WAIT_TIME_MS > Global_1msCounter) && check_if_Ui_voltage_is_stable(s)) {
  322. // Voltages are equal Highside relays can be closed
  323. s->RunMode.OperationMode= BAT_CONNECT_CLOSE_HS;
  324. s->RunMode.OperationModeTimestamp=Global_1msCounter;
  325. return TRUE;
  326. }
  327. else if(s->RunMode.OperationModeTimestamp + CONNECT_INVERTER_MAX_WAIT_TIME_MS > Global_1msCounter) {
  328. s->RunMode.OperationMode= BAT_CONNECT_WAIT_FOR_VOLTAGE_IS_EQUAL;
  329. return TRUE;
  330. }
  331. else {
  332. // just wait
  333. s->RunMode.OperationMode=BAT_CONNECT_CHECK_IF_VOLTAGE_IS_STABLE;
  334. return TRUE;
  335. }
  336. return TRUE;
  337. break;
  338. case BAT_CONNECT_CLOSE_HS:
  339. // Switch Highside relais
  340. SwitchRelais( HS_RELAIS, 1);
  341. s->relayState.HS_closed=TRUE;
  342. if(s->RunMode.OperationModeTimestamp + CONNECT_INVERTER_WAIT_FOR_HS_TO_CLOSE_MS > Global_1msCounter) {
  343. s->RunMode.OperationMode= BAT_CONNECT_OPEN_PC;
  344. return TRUE;
  345. }
  346. else {
  347. // do nothing
  348. s->RunMode.OperationMode= BAT_CONNECT_CLOSE_HS;
  349. return TRUE;
  350. }
  351. return TRUE;
  352. break;
  353. case BAT_CONNECT_OPEN_PC:
  354. s->RunMode.OperationMode=OP_MODE_NORMAL;
  355. s->relayState.PRECHARGE_closed=FALSE;
  356. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  357. return TRUE;
  358. break;
  359. case OP_MODE_NORMAL:
  360. // do nothing until SoC becomes low
  361. s->RunMode.BatteryExtraStatus.batteryDisconnected = 0;
  362. s->RunMode.BatteryExtraStatus.readyToStart=0;
  363. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  364. s->RunMode.onCounter++;
  365. if ( SoC < BMS_SOC_LOW_MARK) {
  366. s->RunMode.OperationMode=OP_MODE_SOC_LOW;
  367. return TRUE;
  368. }
  369. else {
  370. s->RunMode.OperationMode=OP_MODE_NORMAL;
  371. return TRUE;
  372. }
  373. return TRUE;
  374. break;
  375. case OP_MODE_SOC_LOW:
  376. s->RunMode.onCounter++;
  377. // do nothing until SoC becomes high again
  378. if ( SoC > BMS_SOC_LOW_MARK) {
  379. s->RunMode.OperationMode=OP_MODE_NORMAL;
  380. return TRUE;
  381. }
  382. else {
  383. s->RunMode.OperationMode=OP_MODE_SOC_LOW;
  384. return TRUE;
  385. }
  386. break;
  387. case BAT_CONNECT_ERROR_SHORTCIRCUIT_DETECTED:
  388. // stay here and don't turn on anything
  389. // just to be sure open everything
  390. SwitchRelais( HS_RELAIS, 0);
  391. s->relayState.HS_closed=FALSE;
  392. SwitchRelais( LS_RELAIS, 0);
  393. s->relayState.LS_closed=FALSE;
  394. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  395. s->relayState.PRECHARGE_closed=FALSE;
  396. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_INVERTER_CONNECT_SHORT_CIRCUIT,BMS_ERROR_CLASS_3);
  397. // set battery status
  398. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  399. s->RunMode.BatteryExtraStatus.readyToStart=0;
  400. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  401. s->RunMode.OperationMode=BAT_CONNECT_ERROR_SHORTCIRCUIT_DETECTED;
  402. return TRUE;
  403. break;
  404. case BAT_CONNECT_ERROR_LS_STUCK:
  405. // stay here and don't turn on anything
  406. // just to be sure open everything
  407. SwitchRelais( HS_RELAIS, 0);
  408. s->relayState.HS_closed=FALSE;
  409. SwitchRelais( LS_RELAIS, 0);
  410. s->relayState.LS_closed=FALSE;
  411. SwitchRelais( PRE_CHARGE_RELAIS, 0);
  412. s->relayState.PRECHARGE_closed=FALSE;
  413. ErrorStackPushMasterError(s,BMS_ERROR_STACK_MASTER_INVERTER_CONNECT_LS_STUCK,BMS_ERROR_CLASS_3);
  414. // set battery status
  415. s->RunMode.BatteryExtraStatus.batteryDisconnected = 1;
  416. s->RunMode.BatteryExtraStatus.readyToStart=0;
  417. s->RunMode.BatteryExtraStatus.requestRelayTest=0;
  418. return TRUE;
  419. break;
  420. default:
  421. // something went horribly wrong
  422. return FALSE;
  423. break;
  424. }
  425. }