Newer
Older
SCADA / plc / GRFICS_Workstation_Docs / Documents / chemical / build / plc.st
root on 8 May 2022 14 KB playing with modbus day #1
  1. TYPE
  2. LOGLEVEL : (CRITICAL, WARNING, INFO, DEBUG) := INFO;
  3. END_TYPE
  4.  
  5. FUNCTION_BLOCK LOGGER
  6. VAR_INPUT
  7. TRIG : BOOL;
  8. MSG : STRING;
  9. LEVEL : LOGLEVEL := INFO;
  10. END_VAR
  11. VAR
  12. TRIG0 : BOOL;
  13. END_VAR
  14.  
  15. IF TRIG AND NOT TRIG0 THEN
  16. {{
  17. LogMessage(GetFbVar(LEVEL),(char*)GetFbVar(MSG, .body),GetFbVar(MSG, .len));
  18. }}
  19. END_IF;
  20. TRIG0:=TRIG;
  21. END_FUNCTION_BLOCK
  22.  
  23.  
  24.  
  25. FUNCTION_BLOCK python_eval
  26. VAR_INPUT
  27. TRIG : BOOL;
  28. CODE : STRING;
  29. END_VAR
  30. VAR_OUTPUT
  31. ACK : BOOL;
  32. RESULT : STRING;
  33. END_VAR
  34. VAR
  35. STATE : DWORD;
  36. BUFFER : STRING;
  37. PREBUFFER : STRING;
  38. TRIGM1 : BOOL;
  39. TRIGGED : BOOL;
  40. END_VAR
  41.  
  42. {extern void __PythonEvalFB(int, PYTHON_EVAL*);__PythonEvalFB(0, data__);}
  43. END_FUNCTION_BLOCK
  44.  
  45. FUNCTION_BLOCK python_poll
  46. VAR_INPUT
  47. TRIG : BOOL;
  48. CODE : STRING;
  49. END_VAR
  50. VAR_OUTPUT
  51. ACK : BOOL;
  52. RESULT : STRING;
  53. END_VAR
  54. VAR
  55. STATE : DWORD;
  56. BUFFER : STRING;
  57. PREBUFFER : STRING;
  58. TRIGM1 : BOOL;
  59. TRIGGED : BOOL;
  60. END_VAR
  61.  
  62. {extern void __PythonEvalFB(int, PYTHON_EVAL*);__PythonEvalFB(1,(PYTHON_EVAL*)(void*)data__);}
  63. END_FUNCTION_BLOCK
  64.  
  65. FUNCTION_BLOCK python_gear
  66. VAR_INPUT
  67. N : UINT;
  68. TRIG : BOOL;
  69. CODE : STRING;
  70. END_VAR
  71. VAR_OUTPUT
  72. ACK : BOOL;
  73. RESULT : STRING;
  74. END_VAR
  75. VAR
  76. py_eval : python_eval;
  77. COUNTER : UINT;
  78. ADD10_OUT : UINT;
  79. EQ13_OUT : BOOL;
  80. SEL15_OUT : UINT;
  81. AND7_OUT : BOOL;
  82. END_VAR
  83.  
  84. ADD10_OUT := ADD(COUNTER, 1);
  85. EQ13_OUT := EQ(N, ADD10_OUT);
  86. SEL15_OUT := SEL(EQ13_OUT, ADD10_OUT, 0);
  87. COUNTER := SEL15_OUT;
  88. AND7_OUT := AND(EQ13_OUT, TRIG);
  89. py_eval(TRIG := AND7_OUT, CODE := CODE);
  90. ACK := py_eval.ACK;
  91. RESULT := py_eval.RESULT;
  92. END_FUNCTION_BLOCK
  93.  
  94.  
  95. FUNCTION_BLOCK scale_to_real
  96. VAR_INPUT
  97. raw_input_value : UINT;
  98. END_VAR
  99. VAR_OUTPUT
  100. scaled_real : REAL;
  101. END_VAR
  102. VAR_INPUT
  103. real_max : REAL;
  104. real_min : REAL;
  105. END_VAR
  106. VAR
  107. raw_max : UINT := 65535;
  108. raw_min : UINT := 0;
  109. rate : REAL;
  110. offset : REAL;
  111. END_VAR
  112.  
  113. rate := (real_max - real_min) / UINT_TO_REAL(raw_max - raw_min);
  114. offset := real_min - UINT_TO_REAL(raw_min)*rate;
  115. scaled_real := UINT_TO_REAL(raw_input_value)*rate + offset;
  116. END_FUNCTION_BLOCK
  117.  
  118. FUNCTION_BLOCK scale_to_uint
  119. VAR_INPUT
  120. real_in : REAL;
  121. END_VAR
  122. VAR_OUTPUT
  123. uint_out : UINT;
  124. END_VAR
  125. VAR
  126. DIV1_OUT : REAL;
  127. MUL4_OUT : REAL;
  128. REAL_TO_UINT6_OUT : UINT;
  129. END_VAR
  130.  
  131. DIV1_OUT := DIV(real_in, 100.0);
  132. MUL4_OUT := MUL(DIV1_OUT, 65535.0);
  133. REAL_TO_UINT6_OUT := REAL_TO_UINT(MUL4_OUT);
  134. uint_out := REAL_TO_UINT6_OUT;
  135. END_FUNCTION_BLOCK
  136.  
  137. FUNCTION_BLOCK composition_control
  138. VAR
  139. a_in_purge_real : REAL := 47.00;
  140. END_VAR
  141. VAR_INPUT
  142. a_in_purge : UINT := 32000;
  143. END_VAR
  144. VAR
  145. a_setpoint_real : REAL := 47.00;
  146. END_VAR
  147. VAR_INPUT
  148. a_setpoint : UINT := 32000;
  149. curr_pos : UINT := 16000;
  150. END_VAR
  151. VAR
  152. valve_pos_real : REAL := 25.0;
  153. pos_update_real : REAL := 0.0;
  154. valve_pos_nominal : REAL := 25.0;
  155. END_VAR
  156. VAR_OUTPUT
  157. new_pos : UINT := 16000;
  158. END_VAR
  159. VAR
  160. composition_k : REAL := 1.0;
  161. composition_ti : REAL := 99.0;
  162. cycle_time : TIME := T#50ms;
  163. scale_to_real3 : scale_to_real;
  164. scale_to_real2 : scale_to_real;
  165. scale_to_uint0 : scale_to_uint;
  166. comp_max : REAL := 100.0;
  167. comp_min : REAL := 0.0;
  168. pos_max : REAL := 100.0;
  169. pos_min : REAL := 0.0;
  170. scale_to_real0 : scale_to_real;
  171. SUB45_OUT : REAL;
  172. MUL46_OUT : REAL;
  173. ADD42_OUT : REAL;
  174. LIMIT44_OUT : REAL;
  175. END_VAR
  176.  
  177. scale_to_real3(raw_input_value := a_in_purge, real_max := comp_max, real_min := comp_min);
  178. a_in_purge_real := scale_to_real3.scaled_real;
  179. scale_to_real2(raw_input_value := a_setpoint, real_max := comp_max, real_min := comp_min);
  180. a_setpoint_real := scale_to_real2.scaled_real;
  181. SUB45_OUT := SUB(a_setpoint_real, a_in_purge_real);
  182. MUL46_OUT := MUL(SUB45_OUT, composition_k);
  183. pos_update_real := MUL46_OUT;
  184. scale_to_real0(raw_input_value := curr_pos, real_max := pos_max, real_min := pos_min);
  185. valve_pos_real := scale_to_real0.scaled_real;
  186. ADD42_OUT := ADD(valve_pos_real, pos_update_real);
  187. LIMIT44_OUT := LIMIT(pos_min, ADD42_OUT, pos_max);
  188. scale_to_uint0(real_in := LIMIT44_OUT);
  189. new_pos := scale_to_uint0.uint_out;
  190. END_FUNCTION_BLOCK
  191.  
  192. FUNCTION_BLOCK initialize_sp
  193. VAR CONSTANT
  194. flow_sp_c : UINT := 13107;
  195. a_sp_c : UINT := 30801;
  196. press_sp_c : UINT := 55295;
  197. over_sp_c : UINT := 31675;
  198. level_sp_c : UINT := 28835;
  199. END_VAR
  200. VAR_OUTPUT
  201. flow_sp : UINT;
  202. a_sp : UINT;
  203. press_sp : UINT;
  204. over_sp : UINT;
  205. level_sp : UINT;
  206. END_VAR
  207. VAR
  208. MOVE3_OUT : UINT;
  209. MOVE7_OUT : UINT;
  210. MOVE11_OUT : UINT;
  211. MOVE15_OUT : UINT;
  212. MOVE19_OUT : UINT;
  213. END_VAR
  214.  
  215. MOVE3_OUT := MOVE(a_sp_c);
  216. a_sp := MOVE3_OUT;
  217. MOVE7_OUT := MOVE(flow_sp_c);
  218. flow_sp := MOVE7_OUT;
  219. MOVE11_OUT := MOVE(over_sp_c);
  220. over_sp := MOVE11_OUT;
  221. MOVE15_OUT := MOVE(level_sp_c);
  222. level_sp := MOVE15_OUT;
  223. MOVE19_OUT := MOVE(press_sp_c);
  224. press_sp := MOVE19_OUT;
  225. END_FUNCTION_BLOCK
  226.  
  227. FUNCTION_BLOCK pressure_control
  228. VAR
  229. pressure_real : REAL := 2700.0;
  230. END_VAR
  231. VAR_INPUT
  232. pressure : UINT := 58981;
  233. END_VAR
  234. VAR
  235. pressure_sp_real : REAL := 2700.0;
  236. END_VAR
  237. VAR_INPUT
  238. pressure_sp : UINT := 58981;
  239. curr_pos : UINT := 30000;
  240. END_VAR
  241. VAR
  242. valve_pos_real : REAL := 39.25;
  243. pos_update_real : REAL := 0.0;
  244. valve_pos_nominal : REAL := 39.25;
  245. END_VAR
  246. VAR_OUTPUT
  247. valve_pos : UINT := 25886;
  248. END_VAR
  249. VAR
  250. pressure_k : REAL := 20.0;
  251. pressure_ti : REAL := 999.0;
  252. cycle_time : TIME := T#50ms;
  253. scale_to_real5 : scale_to_real;
  254. scale_to_real4 : scale_to_real;
  255. scale_to_uint0 : scale_to_uint;
  256. pressure_max : REAL := 3200.00;
  257. pressure_min : REAL := 0.0;
  258. pos_min : REAL := 0.0;
  259. pos_max : REAL := 100.0;
  260. scale_to_real0 : scale_to_real;
  261. SUB57_OUT : REAL;
  262. MUL60_OUT : REAL;
  263. SUB53_OUT : REAL;
  264. LIMIT55_OUT : REAL;
  265. END_VAR
  266.  
  267. scale_to_real5(raw_input_value := pressure, real_max := pressure_max, real_min := pressure_min);
  268. pressure_real := scale_to_real5.scaled_real;
  269. scale_to_real4(raw_input_value := pressure_sp, real_max := pressure_max, real_min := pressure_min);
  270. pressure_sp_real := scale_to_real4.scaled_real;
  271. SUB57_OUT := SUB(pressure_sp_real, pressure_real);
  272. MUL60_OUT := MUL(SUB57_OUT, pressure_k);
  273. pos_update_real := MUL60_OUT;
  274. scale_to_real0(raw_input_value := curr_pos, real_max := pos_max, real_min := pos_min);
  275. valve_pos_real := scale_to_real0.scaled_real;
  276. SUB53_OUT := SUB(valve_pos_real, pos_update_real);
  277. LIMIT55_OUT := LIMIT(pos_min, SUB53_OUT, pos_max);
  278. scale_to_uint0(real_in := LIMIT55_OUT);
  279. valve_pos := scale_to_uint0.uint_out;
  280. END_FUNCTION_BLOCK
  281.  
  282. FUNCTION_BLOCK flow_control
  283. VAR
  284. flow_k : REAL := 1.0;
  285. flow_ti : REAL := 999.0;
  286. flow_td : REAL := 0.0;
  287. END_VAR
  288. VAR_INPUT
  289. product_flow : UINT := 6554;
  290. END_VAR
  291. VAR
  292. product_flow_real : REAL := 100.0;
  293. cycle_time : TIME := T#50ms;
  294. pos_update_real : REAL := 0.0;
  295. curr_pos_real : REAL := 60.9;
  296. END_VAR
  297. VAR_OUTPUT
  298. new_pos : UINT := 35000;
  299. END_VAR
  300. VAR_INPUT
  301. curr_pos : UINT := 35000;
  302. END_VAR
  303. VAR
  304. flow_set_real : REAL := 100.0;
  305. END_VAR
  306. VAR_INPUT
  307. flow_set_in : UINT := 6554;
  308. END_VAR
  309. VAR
  310. scale_to_real0 : scale_to_real;
  311. scale_to_real1 : scale_to_real;
  312. flow_max : REAL := 500.0;
  313. flow_min : REAL := 0.0;
  314. pos_min : REAL := 0.0;
  315. pos_max : REAL := 100.0;
  316. scale_to_real2 : scale_to_real;
  317. scale_to_uint0 : scale_to_uint;
  318. SUB59_OUT : REAL;
  319. MUL60_OUT : REAL;
  320. ADD58_OUT : REAL;
  321. LIMIT40_OUT : REAL;
  322. END_VAR
  323.  
  324. scale_to_real0(raw_input_value := product_flow, real_max := flow_max, real_min := flow_min);
  325. product_flow_real := scale_to_real0.scaled_real;
  326. scale_to_real1(raw_input_value := flow_set_in, real_max := flow_max, real_min := flow_min);
  327. flow_set_real := scale_to_real1.scaled_real;
  328. SUB59_OUT := SUB(flow_set_real, product_flow_real);
  329. MUL60_OUT := MUL(SUB59_OUT, flow_k);
  330. pos_update_real := MUL60_OUT;
  331. scale_to_real2(raw_input_value := curr_pos, real_max := pos_max, real_min := pos_min);
  332. curr_pos_real := scale_to_real2.scaled_real;
  333. ADD58_OUT := ADD(curr_pos_real, pos_update_real);
  334. LIMIT40_OUT := LIMIT(pos_min, ADD58_OUT, pos_max);
  335. scale_to_uint0(real_in := LIMIT40_OUT);
  336. new_pos := scale_to_uint0.uint_out;
  337. END_FUNCTION_BLOCK
  338.  
  339. FUNCTION_BLOCK level_control
  340. VAR_INPUT
  341. liquid_level : UINT;
  342. level_sp : UINT := 30000;
  343. curr_pos : UINT;
  344. END_VAR
  345. VAR_OUTPUT
  346. new_pos : UINT;
  347. END_VAR
  348. VAR
  349. cycle_time : TIME := T#50ms;
  350. level_k : REAL := 10.0;
  351. level_ti : REAL := 99999.0;
  352. scale_to_real0 : scale_to_real;
  353. level_max : REAL := 100.0;
  354. level_min : REAL := 0.0;
  355. pos_max : REAL := 100.0;
  356. pos_min : REAL := 0.0;
  357. level_real : REAL := 44.18;
  358. pos_real : REAL := 47.0;
  359. pos_update_real : REAL := 0.0;
  360. sp_real : REAL := 44.18;
  361. scale_to_real1 : scale_to_real;
  362. scale_to_real2 : scale_to_real;
  363. scale_to_uint0 : scale_to_uint;
  364. SUB32_OUT : REAL;
  365. MUL33_OUT : REAL;
  366. SUB30_OUT : REAL;
  367. LIMIT25_OUT : REAL;
  368. END_VAR
  369.  
  370. scale_to_real0(raw_input_value := liquid_level, real_max := level_max, real_min := level_min);
  371. level_real := scale_to_real0.scaled_real;
  372. scale_to_real1(raw_input_value := curr_pos, real_max := pos_max, real_min := pos_min);
  373. pos_real := scale_to_real1.scaled_real;
  374. scale_to_real2(raw_input_value := level_sp, real_max := level_max, real_min := level_min);
  375. sp_real := scale_to_real2.scaled_real;
  376. SUB32_OUT := SUB(sp_real, level_real);
  377. MUL33_OUT := MUL(SUB32_OUT, level_k);
  378. pos_update_real := MUL33_OUT;
  379. SUB30_OUT := SUB(pos_real, pos_update_real);
  380. LIMIT25_OUT := LIMIT(pos_min, SUB30_OUT, pos_max);
  381. scale_to_uint0(real_in := LIMIT25_OUT);
  382. new_pos := scale_to_uint0.uint_out;
  383. END_FUNCTION_BLOCK
  384.  
  385. FUNCTION_BLOCK pressure_override
  386. VAR
  387. pressure_real : REAL := 2700.0;
  388. END_VAR
  389. VAR_INPUT
  390. pressure : UINT := 58981;
  391. curr_sp : UINT := 58981;
  392. END_VAR
  393. VAR
  394. curr_sp_real : REAL := 2700.0;
  395. product_sp_real : REAL := 100.0;
  396. sp_update : REAL := 0.0;
  397. product_sp_nominl : REAL := 100.0;
  398. END_VAR
  399. VAR_OUTPUT
  400. product_sp : UINT := 13107;
  401. END_VAR
  402. VAR
  403. override_sp_real : REAL := 2900.0;
  404. END_VAR
  405. VAR_INPUT
  406. override_sp : UINT := 63350;
  407. END_VAR
  408. VAR
  409. override_k : REAL := 1.0;
  410. override_ti : REAL := 99999.0;
  411. cycle_time : TIME := T#50ms;
  412. scale_to_real7 : scale_to_real;
  413. pressure_max : REAL := 3000.0;
  414. pressure_min : REAL := 0.0;
  415. flow_max : REAL := 500.0;
  416. flow_min : REAL := 0.0;
  417. scale_to_real0 : scale_to_real;
  418. SUB86_OUT : REAL;
  419. MUL87_OUT : REAL;
  420. MAX84_OUT : REAL;
  421. ADD85_OUT : REAL;
  422. LIMIT67_OUT : REAL;
  423. DIV73_OUT : REAL;
  424. MUL75_OUT : REAL;
  425. REAL_TO_UINT79_OUT : UINT;
  426. END_VAR
  427.  
  428. scale_to_real7(raw_input_value := pressure, real_max := pressure_max, real_min := pressure_min);
  429. pressure_real := scale_to_real7.scaled_real;
  430. SUB86_OUT := SUB(override_sp_real, pressure_real);
  431. MUL87_OUT := MUL(SUB86_OUT, override_k);
  432. MAX84_OUT := MAX(MUL87_OUT, 0.0);
  433. sp_update := MAX84_OUT;
  434. scale_to_real0(raw_input_value := curr_sp, real_max := flow_max, real_min := flow_min);
  435. curr_sp_real := scale_to_real0.scaled_real;
  436. ADD85_OUT := ADD(curr_sp_real, sp_update);
  437. LIMIT67_OUT := LIMIT(50.0, ADD85_OUT, 150.0);
  438. product_sp_real := LIMIT67_OUT;
  439. DIV73_OUT := DIV(product_sp_real, 500.0);
  440. MUL75_OUT := MUL(DIV73_OUT, 65535.0);
  441. REAL_TO_UINT79_OUT := REAL_TO_UINT(MUL75_OUT);
  442. product_sp := REAL_TO_UINT79_OUT;
  443. END_FUNCTION_BLOCK
  444.  
  445. PROGRAM main
  446. VAR
  447. flow_control0 : flow_control;
  448. first_run : BOOL := True;
  449. END_VAR
  450. VAR
  451. flow_set : UINT;
  452. a_setpoint : UINT;
  453. pressure_sp : UINT;
  454. override_sp : UINT;
  455. level_sp : UINT;
  456. END_VAR
  457. VAR
  458. composition_control0 : composition_control;
  459. END_VAR
  460. VAR
  461. f1_valve_pos : UINT;
  462. f1_flow : UINT;
  463. f2_valve_pos : UINT;
  464. f2_flow : UINT;
  465. purge_valve_pos : UINT;
  466. purge_flow : UINT;
  467. product_valve_pos : UINT;
  468. product_flow : UINT;
  469. pressure : UINT;
  470. level : UINT;
  471. a_in_purge : UINT;
  472. b_in_purge : UINT;
  473. c_in_purge : UINT;
  474. f1_valve_sp : UINT;
  475. f2_valve_sp : UINT;
  476. purge_valve_sp : UINT;
  477. product_valve_sp : UINT;
  478. END_VAR
  479. VAR
  480. product_valve_safe : UINT := 0;
  481. purge_valve_safe : UINT := 65535;
  482. f1_valve_safe : UINT;
  483. f2_valve_safe : UINT;
  484. pressure_control0 : pressure_control;
  485. END_VAR
  486. VAR
  487. hmi_pressure : INT;
  488. hmi_level : INT;
  489. hmi_f1_valve_pos : INT;
  490. hmi_f1_flow : INT;
  491. hmi_f2_valve_pos : INT;
  492. hmi_f2_flow : INT;
  493. hmi_purge_valve_pos : INT;
  494. hmi_purge_flow : INT;
  495. hmi_product_valve_pos : INT;
  496. hmi_product_flow : INT;
  497. scan_count : UINT;
  498. END_VAR
  499. VAR
  500. pressure_override0 : pressure_override;
  501. level_control0 : level_control;
  502. END_VAR
  503. VAR
  504. run_bit : BOOL;
  505. END_VAR
  506. VAR
  507. run_bit0 : BOOL := True;
  508. initialize_sp0 : initialize_sp;
  509. MOVE99_ENO : BOOL;
  510. MOVE99_OUT : UINT;
  511. MOVE4_ENO : BOOL;
  512. MOVE4_OUT : UINT;
  513. MOVE5_ENO : BOOL;
  514. MOVE5_OUT : UINT;
  515. MOVE7_ENO : BOOL;
  516. MOVE7_OUT : UINT;
  517. END_VAR
  518.  
  519. initialize_sp0(EN := first_run);
  520. IF initialize_sp0.ENO THEN
  521. first_run := FALSE; (*reset*)
  522. END_IF;
  523. IF initialize_sp0.ENO THEN
  524. flow_set := initialize_sp0.flow_sp;
  525. END_IF;
  526. IF initialize_sp0.ENO THEN
  527. a_setpoint := initialize_sp0.a_sp;
  528. END_IF;
  529. IF initialize_sp0.ENO THEN
  530. pressure_sp := initialize_sp0.press_sp;
  531. END_IF;
  532. IF initialize_sp0.ENO THEN
  533. override_sp := initialize_sp0.over_sp;
  534. END_IF;
  535. IF initialize_sp0.ENO THEN
  536. level_sp := initialize_sp0.level_sp;
  537. END_IF;
  538. flow_control0(product_flow := product_flow, curr_pos := f1_valve_pos, flow_set_in := flow_set);
  539. f1_valve_sp := flow_control0.new_pos;
  540. pressure_control0(pressure := pressure, pressure_sp := pressure_sp, curr_pos := purge_valve_pos);
  541. purge_valve_sp := pressure_control0.valve_pos;
  542. composition_control0(a_in_purge := a_in_purge, a_setpoint := a_setpoint, curr_pos := f2_valve_pos);
  543. f2_valve_sp := composition_control0.new_pos;
  544. pressure_override0(pressure := pressure, curr_sp := flow_set, override_sp := override_sp);
  545. flow_set := pressure_override0.product_sp;
  546. level_control0(liquid_level := level, level_sp := level_sp, curr_pos := product_valve_pos);
  547. product_valve_sp := level_control0.new_pos;
  548. MOVE99_OUT := MOVE(EN := run_bit, IN := 0, ENO => MOVE99_ENO);
  549. IF MOVE99_ENO THEN
  550. f1_valve_sp := MOVE99_OUT;
  551. END_IF;
  552. MOVE4_OUT := MOVE(EN := MOVE99_ENO, IN := 0, ENO => MOVE4_ENO);
  553. IF MOVE4_ENO THEN
  554. f2_valve_sp := MOVE4_OUT;
  555. END_IF;
  556. MOVE5_OUT := MOVE(EN := MOVE4_ENO, IN := 65535, ENO => MOVE5_ENO);
  557. IF MOVE5_ENO THEN
  558. purge_valve_sp := MOVE5_OUT;
  559. END_IF;
  560. MOVE7_OUT := MOVE(EN := MOVE5_ENO, IN := 65535, ENO => MOVE7_ENO);
  561. IF MOVE7_ENO THEN
  562. product_valve_sp := MOVE7_OUT;
  563. END_IF;
  564. END_PROGRAM
  565.  
  566.  
  567. CONFIGURATION Config0
  568.  
  569. RESOURCE Res0 ON PLC
  570. TASK MainTask(INTERVAL := T#50ms,PRIORITY := 0);
  571. PROGRAM instance0 WITH MainTask : main;
  572. END_RESOURCE
  573. END_CONFIGURATION
Buy Me A Coffee