TemperatureControllerSerialPortDevice.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. using MECF.Framework.Simulator.Core.Driver;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace MECF.Framework.Simulator.Core.Commons
  8. {
  9. public class TemperatureControllerSerialPortDevice : BaseSerialSimulator
  10. {
  11. #region 常量
  12. private const string PORT_NAME = "com12";
  13. private const byte ADD_FLAG = 0x30;
  14. #endregion
  15. #region 内部变量
  16. /// <summary>
  17. /// 控制字字典
  18. /// </summary>
  19. private Dictionary<byte, string> dic = new Dictionary<byte, string>()
  20. {
  21. { 0x05,"ENQ" },
  22. { 0x02,"STX" },
  23. { 0x03,"ETX" },
  24. { 0x06,"ACK" },
  25. { 0x0D,"CR" },
  26. { 0x01,"SOH" }
  27. };
  28. /// <summary>
  29. /// 命令字典
  30. /// </summary>
  31. private Dictionary<byte, string> comdic = new Dictionary<byte, string>()
  32. {
  33. { 0x31,"Target Temp" },
  34. { 0x32,"Internal" },
  35. { 0x33,"External" },
  36. { 0x34,"Alarm" },
  37. { 0x35,"Average" },
  38. { 0x36,"offset" },
  39. { 0x39,"control" },
  40. { 0x41,"PB" },
  41. { 0x42,"ARW" },
  42. { 0x43,"IConstant" },
  43. { 0x44,"DConstant" },
  44. { 0x45,"OutPutRatio" },
  45. { 0x46,"HeatingLimit" },
  46. { 0x47,"CoolingLimit" },
  47. { 0x48,"Saved" }
  48. };
  49. private double[] _reserviorValues = { 16.6, 16.6, 16.6, 16.6 };
  50. private double[] _heatValues = { 16.5, 16.5, 16.5, 16.5 };
  51. private double[] _targetValues = { 0, 0, 0, 0 };
  52. private int _controlOperation = 0;
  53. //private byte[] alarm = new byte[12] { 0,0,0,0,1,0,0,0,0,0,0,0};
  54. private byte[] alarm = new byte[3] {0x30,0x33,0x30};
  55. System.Timers.Timer[] _timers = new System.Timers.Timer[4];
  56. #endregion
  57. /// <summary>
  58. /// 构造函数
  59. /// </summary>
  60. /// <param name="portName"></param>
  61. /// <param name="type"></param>
  62. public TemperatureControllerSerialPortDevice(string port) : base(port, SerialType.BUFFER)
  63. {
  64. _timers[0] = new System.Timers.Timer(50);
  65. _timers[0].Elapsed += Timer_Elapsed0;
  66. _timers[1] = new System.Timers.Timer(50);
  67. _timers[1].Elapsed += Timer_Elapsed1;
  68. _timers[2] = new System.Timers.Timer(50);
  69. _timers[2].Elapsed += Timer_Elapsed2;
  70. _timers[3] = new System.Timers.Timer(50);
  71. _timers[3].Elapsed += Timer_Elapsed3;
  72. }
  73. /// <summary>
  74. /// TC1-1的调温
  75. /// </summary>
  76. /// <param name="sender"></param>
  77. /// <param name="e"></param>
  78. private void Timer_Elapsed0(object sender, System.Timers.ElapsedEventArgs e)
  79. {
  80. if (Math.Abs(_heatValues[0] - _targetValues[0]) >=0.2)
  81. {
  82. //内部调温
  83. if(_heatValues[0] < _targetValues[0])
  84. {
  85. _heatValues[0] += 0.1;
  86. }
  87. else
  88. {
  89. _heatValues[0] -= 0.1;
  90. }
  91. //外部调温
  92. if(_reserviorValues[0] < _targetValues[0])
  93. {
  94. _reserviorValues[0] += 0.1;
  95. }
  96. else
  97. {
  98. _reserviorValues[0] -= 0.1;
  99. }
  100. }
  101. else
  102. {
  103. _timers[0].Stop();
  104. }
  105. }
  106. /// <summary>
  107. /// TC1-2的调温
  108. /// </summary>
  109. /// <param name="sender"></param>
  110. /// <param name="e"></param>
  111. private void Timer_Elapsed1(object sender, System.Timers.ElapsedEventArgs e)
  112. {
  113. if (Math.Abs(_heatValues[1] - _targetValues[1]) >= 0.2)
  114. {
  115. //内部调温
  116. if (_heatValues[1] < _targetValues[1])
  117. {
  118. _heatValues[1] += 0.1;
  119. }
  120. else
  121. {
  122. _heatValues[1] -= 0.1;
  123. }
  124. //外部调温
  125. if (_reserviorValues[1] < _targetValues[1])
  126. {
  127. _reserviorValues[1] += 0.1;
  128. }
  129. else
  130. {
  131. _reserviorValues[1] -= 0.1;
  132. }
  133. }
  134. else
  135. {
  136. _timers[1].Stop();
  137. }
  138. }
  139. /// <summary>
  140. /// TC1-3的调温
  141. /// </summary>
  142. /// <param name="sender"></param>
  143. /// <param name="e"></param>
  144. private void Timer_Elapsed2(object sender, System.Timers.ElapsedEventArgs e)
  145. {
  146. if (Math.Abs(_heatValues[2] - _targetValues[2]) >= 0.2)
  147. {
  148. //内部调温
  149. if (_heatValues[2] < _targetValues[2])
  150. {
  151. _heatValues[2] += 0.1;
  152. }
  153. else
  154. {
  155. _heatValues[2] -= 0.1;
  156. }
  157. //外部调温
  158. if (_reserviorValues[2] < _targetValues[2])
  159. {
  160. _reserviorValues[2] += 0.1;
  161. }
  162. else
  163. {
  164. _reserviorValues[2] -= 0.1;
  165. }
  166. }
  167. else
  168. {
  169. _timers[2].Stop();
  170. }
  171. }
  172. /// <summary>
  173. /// TC1-4的调温
  174. /// </summary>
  175. /// <param name="sender"></param>
  176. /// <param name="e"></param>
  177. private void Timer_Elapsed3(object sender, System.Timers.ElapsedEventArgs e)
  178. {
  179. if (Math.Abs(_heatValues[3] - _targetValues[3]) >= 0.2)
  180. {
  181. //内部调温
  182. if (_heatValues[3] < _targetValues[3])
  183. {
  184. _heatValues[3] += 0.1;
  185. }
  186. else
  187. {
  188. _heatValues[3] -= 0.1;
  189. }
  190. //外部调温
  191. if (_reserviorValues[3] < _targetValues[3])
  192. {
  193. _reserviorValues[3] += 0.1;
  194. }
  195. else
  196. {
  197. _reserviorValues[3] -= 0.1;
  198. }
  199. }
  200. else
  201. {
  202. _timers[3].Stop();
  203. }
  204. }
  205. protected override string MessageConvert(byte[] byt)
  206. {
  207. string str = "";
  208. for(int i=0;i<byt.Length;i++)
  209. {
  210. byte item = byt[i];
  211. if(dic.ContainsKey(item))
  212. {
  213. str += dic[item];
  214. }
  215. else if(i==1)
  216. {
  217. str += (item - 0x30).ToString("D2");
  218. }
  219. else if(i==3&&comdic.ContainsKey(item))
  220. {
  221. str += comdic[item];
  222. }
  223. else
  224. {
  225. str += item.ToString("X2");
  226. }
  227. str += " ";
  228. }
  229. return str;
  230. }
  231. protected override void ProcessMessageBuffer(byte[] data)
  232. {
  233. if (data[0] == 0x06 && data[2]==0x0D&&data.Length>7)
  234. {
  235. byte[] byt = new byte[data.Length - 3];
  236. Array.Copy(data, 3, byt, 0, byt.Length);
  237. ProcessNormalCommand(byt);
  238. }
  239. else if (data[0] == 0x01)
  240. {
  241. ProcessNormalCommand(data);
  242. }
  243. }
  244. private void ProcessNormalCommand(byte[] data)
  245. {
  246. if (data[0] == 0x01 && data[data.Length-1]==0x0D)
  247. {
  248. if (data.Length == 7)
  249. {
  250. ProcessReadCommand(data);
  251. }
  252. else if (data.Length > 7)
  253. {
  254. ProcessSetCommand(data);
  255. }
  256. }
  257. }
  258. private void ProcessReadCommand(byte[] data)
  259. {
  260. switch(data[3])
  261. {
  262. case 0x31:
  263. ReadTargetValue(data);
  264. break;
  265. case 0x32:
  266. ReadReserviorValue(data);
  267. break;
  268. case 0x33:
  269. ReadHeatValue(data);
  270. break;
  271. case 0x34:
  272. ReadAlarmValue(data);
  273. break;
  274. case 0x39:
  275. ReadControlOperationValue(data);
  276. break;
  277. }
  278. }
  279. private void ProcessSetCommand(byte[] data)
  280. {
  281. switch(data[3])
  282. {
  283. case 0x31:
  284. _targetValues[data[1] - ADD_FLAG - 1] = (data[4] - ADD_FLAG) * 10 + (data[5] - ADD_FLAG) + (data[6]-ADD_FLAG)*0.1;
  285. _timers[data[1] - ADD_FLAG -1].Start();
  286. break;
  287. case 0x39:
  288. _controlOperation = data[7] - ADD_FLAG;
  289. if(_controlOperation == 0)
  290. {
  291. //停止调温
  292. _timers[data[1] - ADD_FLAG - 1].Stop();
  293. }
  294. else
  295. {
  296. //继续调温
  297. _timers[data[1] - ADD_FLAG - 1].Start();
  298. }
  299. break;
  300. }
  301. WriteConfirmData(data[1]);
  302. }
  303. /// <summary>
  304. /// 回复确认
  305. /// </summary>
  306. /// <param name="id"></param>
  307. private void WriteConfirmData(byte id)
  308. {
  309. byte[] confirm = new byte[3];
  310. confirm[0] = 0x06;
  311. confirm[1] = id;
  312. confirm[2] = 0x0d;
  313. WriteBuffer(confirm);
  314. }
  315. private void ReadTargetValue(byte[] data)
  316. {
  317. byte[] byt = new byte[12];
  318. byt[0] = data[0];
  319. byt[1] = data[1];
  320. byt[2] = 0x02;
  321. byt[3] = data[3];
  322. byte[] decadeByte = GetDecadeBytes(_targetValues[data[1] - ADD_FLAG - 1]);
  323. Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
  324. byt[5 + decadeByte.Length] = 0;
  325. byt[6 + decadeByte.Length] = 0;
  326. byt[11] = 0x0D;
  327. WriteBuffer(byt);
  328. }
  329. private void ReadReserviorValue(byte[] data)
  330. {
  331. byte[] byt = new byte[12];
  332. byt[0] = data[0];
  333. byt[1] = data[1];
  334. byt[2] = 0x02;
  335. byt[3] = data[3];
  336. byte[] decadeByte = GetDecadeBytes(_reserviorValues[data[1] - ADD_FLAG - 1]);
  337. Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
  338. byt[5 + decadeByte.Length] = 0;
  339. byt[6 + decadeByte.Length] = 0;
  340. byt[11] = 0x0D;
  341. WriteBuffer(byt);
  342. }
  343. private void ReadHeatValue(byte[] data)
  344. {
  345. byte[] byt = new byte[12];
  346. byt[0] = data[0];
  347. byt[1] = data[1];
  348. byt[2] = 0x02;
  349. byt[3] = data[3];
  350. byte[] decadeByte = GetDecadeBytes(_heatValues[data[1] - ADD_FLAG - 1]);
  351. Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
  352. byt[5 + decadeByte.Length] = 0;
  353. byt[6 + decadeByte.Length] = 0;
  354. byt[11] = 0x0D;
  355. WriteBuffer(byt);
  356. }
  357. private void ReadControlOperationValue(byte[] data)
  358. {
  359. byte[] byt = new byte[12];
  360. byt[0] = data[0];
  361. byt[1] = data[1];
  362. byt[2] = 0x02;
  363. byt[3] = data[3];
  364. byte[] decadeByte = GetKilloBytes(_controlOperation);
  365. Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
  366. byt[5 + decadeByte.Length] = 0;
  367. byt[6 + decadeByte.Length] = 0;
  368. byt[11] = 0x0D;
  369. WriteBuffer(byt);
  370. }
  371. private void ReadAlarmValue(byte[] data)
  372. {
  373. byte[] byt = new byte[8+alarm.Length];
  374. byt[0] = data[0];
  375. byt[1] = data[1];
  376. byt[2] = 0x02;
  377. byt[3] = data[3];
  378. Array.Copy(alarm, 0, byt, 4, alarm.Length);
  379. byt[5 + alarm.Length] = 0;
  380. byt[6 + alarm.Length] = 0;
  381. byt[7+alarm.Length] = 0x0D;
  382. WriteBuffer(byt);
  383. }
  384. /// <summary>
  385. /// 获取温度数组(10|1|0.1|0.01)
  386. /// </summary>
  387. /// <param name="temperature"></param>
  388. /// <returns></returns>
  389. private byte[] GetDecadeBytes(double temperature)
  390. {
  391. byte decade = GetSendByteData((byte)Math.Floor(temperature / 10));
  392. byte unit = GetSendByteData((byte)Math.Floor(temperature % 10));
  393. byte digital = GetSendByteData((byte)Math.Floor(temperature * 10 % 10));
  394. return new byte[4] { decade, unit, digital, ADD_FLAG };
  395. }
  396. /// <summary>
  397. /// 获取千级数组(1000|100|10|1)
  398. /// </summary>
  399. /// <param name="temperature"></param>
  400. /// <returns></returns>
  401. private byte[] GetKilloBytes(double temperature)
  402. {
  403. byte kilo = GetSendByteData((byte)Math.Floor(temperature / 1000));
  404. byte hundred = GetSendByteData((byte)Math.Floor(temperature % 1000/100));
  405. byte decade = GetSendByteData((byte)Math.Floor(temperature % 100 / 10));
  406. byte unit = GetSendByteData((byte)Math.Floor(temperature % 10));
  407. return new byte[4] { kilo, hundred, decade, unit };
  408. }
  409. /// <summary>
  410. /// 获取发送位数据
  411. /// </summary>
  412. /// <param name="originalData"></param>
  413. /// <returns></returns>
  414. private byte GetSendByteData(byte originalData)
  415. {
  416. return (byte)(ADD_FLAG + originalData);
  417. }
  418. }
  419. }