FinsTcpBase.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. using System.Text.RegularExpressions;
  2. namespace Universal.IO;
  3. //This is a copy of a Open library POmronFinsTCP.Net
  4. //I have modified tcpclient sendtimeout and receivetimeout time to make sure it can know connect status when device connect into a switch
  5. //Please ignore all the warnings and Messages,I know the code is in a mess, but it is working.
  6. //I will modified and optimize the code later - Zixuan
  7. //Fix all warnings and Messages and make code more readable - 2025/06/10 Zixuan
  8. public class FinsTcpBase : Tcp
  9. {
  10. public byte PlcNode { get; private set; }
  11. public byte PcNode { get; private set; }
  12. //
  13. // Summary:
  14. // Fins读写指令生成
  15. //
  16. // Parameters:
  17. // rw:
  18. // 读写类型
  19. //
  20. // mr:
  21. // 寄存器类型
  22. //
  23. // mt:
  24. // 地址类型
  25. //
  26. // ch:
  27. // 起始地址
  28. //
  29. // offset:
  30. // 位地址:00-15,字地址则为00
  31. //
  32. // cnt:
  33. // 地址个数,按位读写只能是1
  34. public bool Link(string rIP, int rPort = 9600, int sendTimeout = 1000, int receiveTimeout = 1000)
  35. {
  36. if (this._client is null)
  37. return false;
  38. _client.SendTimeout = sendTimeout;
  39. _client.ReceiveTimeout = receiveTimeout;
  40. _client.NoDelay = true;
  41. if (!_client.ConnectAsync(rIP, rPort).Wait(sendTimeout))
  42. return false;
  43. _stream = _client.GetStream();
  44. Thread.Sleep(10);
  45. if (!SendData(FinsClass.HandShakePack))
  46. return false;
  47. byte[] array = new byte[24];
  48. if (!ReceiveData(array))
  49. return false;
  50. if (array[15] != 0)
  51. return false;
  52. PcNode = array[19];
  53. PlcNode = array[23];
  54. return true;
  55. }
  56. public bool Close()
  57. {
  58. try
  59. {
  60. _stream?.Close();
  61. _client?.Close();
  62. return true;
  63. }
  64. catch
  65. {
  66. return false;
  67. }
  68. }
  69. public bool ReadWords(string mrch, short cnt, out short[]? reData)
  70. {
  71. reData = default;
  72. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  73. return false;
  74. return ReadWords(plcMemory, short.Parse(txtq), cnt, out reData);
  75. }
  76. public bool ReadWords(PlcMemory mr, short ch, short cnt, out short[] reData)
  77. {
  78. reData = new short[cnt];
  79. int num = 30 + cnt * 2;
  80. byte[] array = new byte[num];
  81. byte[] sd = FinsClass.FinsCmd(Operation.Read, mr, MemoryType.Word, ch, 0, cnt, PlcNode, PcNode);
  82. if (!SendData(sd))
  83. return false;
  84. if (!ReceiveData(array))
  85. return false;
  86. bool flag = array[11] switch
  87. {
  88. 3 => ErrorCode.CheckHeadError(array[15]),
  89. _ => true
  90. };
  91. if (!flag)
  92. return false;
  93. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  94. return false;
  95. for (int i = 0; i < cnt; i++)
  96. {
  97. byte[] value = [array[30 + i * 2 + 1], array[30 + i * 2]];
  98. reData[i] = BitConverter.ToInt16(value, 0);
  99. }
  100. return true;
  101. }
  102. public bool ReadWord(string mrch, out short reData)
  103. {
  104. reData = default;
  105. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  106. return false;
  107. return ReadWord(plcMemory, short.Parse(txtq), out reData);
  108. }
  109. public bool ReadWord(PlcMemory mr, short ch, out short reData)
  110. {
  111. reData = 0;
  112. if (!ReadWords(mr, ch, 1, out var reData2))
  113. return false;
  114. reData = reData2[0];
  115. return true;
  116. }
  117. public bool WriteWords(string mrch, short cnt, short[] inData)
  118. {
  119. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  120. return false;
  121. return WriteWords(plcMemory, short.Parse(txtq), cnt, inData);
  122. }
  123. public bool WriteWords(PlcMemory mr, short ch, short cnt, short[] inData)
  124. {
  125. byte[] array = new byte[30];
  126. byte[] array2 = FinsClass.FinsCmd(Operation.Write, mr, MemoryType.Word, ch, 0, cnt, PlcNode, PcNode);
  127. byte[] array3 = new byte[cnt * 2];
  128. for (int i = 0; i < cnt; i++)
  129. {
  130. byte[] bytes = BitConverter.GetBytes(inData[i]);
  131. array3[i * 2] = bytes[1];
  132. array3[i * 2 + 1] = bytes[0];
  133. }
  134. byte[] array4 = new byte[cnt * 2 + 34];
  135. array2.CopyTo(array4, 0);
  136. array3.CopyTo(array4, 34);
  137. if (!SendData(array4))
  138. return false;
  139. if (!ReceiveData(array))
  140. return false;
  141. bool flag = array[11] switch
  142. {
  143. 3 => ErrorCode.CheckHeadError(array[15]),
  144. _ => true
  145. };
  146. if (!flag)
  147. return false;
  148. return ErrorCode.CheckEndCode(array[28], array[29]);
  149. }
  150. public bool WriteWord(string mrch, short inData)
  151. {
  152. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  153. return false;
  154. return WriteWord(plcMemory, short.Parse(txtq), inData);
  155. }
  156. public bool WriteWord(PlcMemory mr, short ch, short inData)
  157. {
  158. short[] inData2 = [inData];
  159. if (!WriteWords(mr, ch, 1, inData2))
  160. return false;
  161. return true;
  162. }
  163. public bool GetBitState(string mrch, out short bs)
  164. {
  165. bs = default;
  166. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  167. return false;
  168. return GetBitState(plcMemory, txtq, out bs);
  169. }
  170. public bool GetBitStates(string mrch, out bool[]? bs, short cnt = 1)
  171. {
  172. bs = default;
  173. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  174. return false;
  175. return GetBitStates(plcMemory, txtq, out bs, cnt);
  176. }
  177. public bool GetBitStates(PlcMemory mr, string ch, out bool[] bs, short cnt = 1)
  178. {
  179. bs = new bool[cnt];
  180. byte[] array = new byte[30 + cnt];
  181. short ch2 = short.Parse(ch.Split(['.'])[0]);
  182. short offset = short.Parse(ch.Split(['.'])[1]);
  183. byte[] command = FinsClass.FinsCmd(Operation.Read, mr, MemoryType.Bit, ch2, offset, cnt, PlcNode, PcNode);
  184. if (!SendData(command))
  185. return false;
  186. if (!ReceiveData(array))
  187. return false;
  188. bool flag = array[11] switch
  189. {
  190. 3 => ErrorCode.CheckHeadError(array[15]),
  191. _ => true
  192. };
  193. if (!flag)
  194. return false;
  195. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  196. return false;
  197. for (int i = 0; i < cnt; i++)
  198. bs[i] = array[30 + i] == 1;
  199. return true;
  200. }
  201. public bool GetBitState(PlcMemory mr, string ch, out short bs)
  202. {
  203. bs = 0;
  204. byte[] array = new byte[31];
  205. string[] spilts = ch.Split('.');
  206. short ch2 = short.Parse(spilts[0]);
  207. short offset = short.Parse(spilts[1]);
  208. byte[] sd = FinsClass.FinsCmd(Operation.Read, mr, MemoryType.Bit, ch2, offset, 1, PlcNode, PcNode);
  209. if (!SendData(sd))
  210. return false;
  211. if (!ReceiveData(array))
  212. return false;
  213. bool flag = array[11] switch
  214. {
  215. 3 => ErrorCode.CheckHeadError(array[15]),
  216. _ => true
  217. };
  218. if (!flag)
  219. return false;
  220. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  221. return false;
  222. bs = array[30];
  223. return true;
  224. }
  225. public bool SetBitState(string mrch, BitState bs)
  226. {
  227. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  228. return false;
  229. return SetBitState(plcMemory, txtq, bs);
  230. }
  231. public bool SetBitState(PlcMemory mr, string ch, BitState bs)
  232. {
  233. byte[] array = new byte[30];
  234. string[] spilts = ch.Split('.');
  235. short ch2 = short.Parse(spilts[0]);
  236. short offset = short.Parse(spilts[1]);
  237. byte[] array2 = FinsClass.FinsCmd(Operation.Write, mr, MemoryType.Bit, ch2, offset, 1, PlcNode, PcNode);
  238. byte[] array3 = new byte[35];
  239. array2.CopyTo(array3, 0);
  240. array3[34] = (byte)bs;
  241. if (!SendData(array3))
  242. return false;
  243. if (!ReceiveData(array))
  244. return false;
  245. bool flag = array[11] switch
  246. {
  247. 3 => ErrorCode.CheckHeadError(array[15]),
  248. _ => true
  249. };
  250. if (!flag)
  251. return false;
  252. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  253. return false;
  254. return true;
  255. }
  256. public bool ReadReal(string mrch, out float reData)
  257. {
  258. reData = default;
  259. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  260. return false;
  261. return ReadReal(plcMemory, short.Parse(txtq), out reData);
  262. }
  263. public bool ReadReal(PlcMemory mr, short ch, out float reData)
  264. {
  265. reData = 0f;
  266. int num = 34;
  267. byte[] array = new byte[num];
  268. byte[] sd = FinsClass.FinsCmd(Operation.Read, mr, MemoryType.Word, ch, 0, 2, PlcNode, PcNode);
  269. if (!SendData(sd))
  270. return false;
  271. if (!ReceiveData(array))
  272. return false;
  273. bool flag = array[11] switch
  274. {
  275. 3 => ErrorCode.CheckHeadError(array[15]),
  276. _ => true
  277. };
  278. if (!flag)
  279. return false;
  280. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  281. return false;
  282. byte[] value = [array[31], array[30], array[33], array[32]];
  283. reData = BitConverter.ToSingle(value, 0);
  284. return true;
  285. }
  286. public bool WriteReal(string mrch, float reData)
  287. {
  288. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  289. return false;
  290. return WriteReal(plcMemory, short.Parse(txtq), reData);
  291. }
  292. public bool WriteReal(PlcMemory mr, short ch, float reData)
  293. {
  294. if (BitConverter.GetBytes(reData) is not byte[] bytes)
  295. return false;
  296. short[] array = new short[2];
  297. array[0] = BitConverter.ToInt16(bytes, 0);
  298. if (bytes.Length > 2)
  299. array[1] = BitConverter.ToInt16(bytes, 2);
  300. return WriteWords(mr, ch, 2, array);
  301. }
  302. public bool ReadInt32(string mrch, out int reData)
  303. {
  304. reData = default;
  305. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  306. return false;
  307. return ReadInt32(plcMemory, short.Parse(txtq), out reData);
  308. }
  309. public bool ReadInt32(PlcMemory mr, short ch, out int reData)
  310. {
  311. reData = 0;
  312. int num = 34;
  313. byte[] array = new byte[num];
  314. byte[] sd = FinsClass.FinsCmd(Operation.Read, mr, MemoryType.Word, ch, 0, 2, PlcNode, PcNode);
  315. if (!SendData(sd))
  316. return false;
  317. if (!ReceiveData(array))
  318. return false;
  319. bool flag = array[11] switch
  320. {
  321. 3 => ErrorCode.CheckHeadError(array[15]),
  322. _ => true
  323. };
  324. if (!flag)
  325. return false;
  326. if (!ErrorCode.CheckEndCode(array[28], array[29]))
  327. return false;
  328. byte[] value = [array[31], array[30], array[33], array[32]];
  329. reData = BitConverter.ToInt32(value, 0);
  330. return true;
  331. }
  332. public bool WriteInt32(string mrch, int reData)
  333. {
  334. if (!ConvertClass.GetPlcMemory(mrch, out string txtq, out PlcMemory plcMemory))
  335. return false;
  336. return WriteInt32(plcMemory, short.Parse(txtq), reData);
  337. }
  338. public bool WriteInt32(PlcMemory mr, short ch, int reData)
  339. {
  340. if (BitConverter.GetBytes(reData) is not byte[] bytes)
  341. return false;
  342. short[] array = new short[2];
  343. array[0] = BitConverter.ToInt16(bytes, 0);
  344. if (bytes.Length > 2)
  345. array[1] = BitConverter.ToInt16(bytes, 2);
  346. return WriteWords(mr, ch, 2, array);
  347. }
  348. }
  349. public class Tcp
  350. {
  351. public Tcp()
  352. {
  353. this._client = new();
  354. }
  355. protected readonly TcpClient _client;
  356. protected NetworkStream? _stream;
  357. protected bool SendData(byte[] sd)
  358. {
  359. if (_stream == null)
  360. return false;
  361. try
  362. {
  363. _stream.Write(sd, 0, sd.Length);
  364. return true;
  365. }
  366. catch
  367. {
  368. return false;
  369. }
  370. }
  371. protected bool ReceiveData(byte[] rd)
  372. {
  373. if (_stream == null)
  374. return false;
  375. try
  376. {
  377. int num = 0;
  378. do
  379. {
  380. int num2 = _stream.Read(rd, num, rd.Length - num);
  381. if (num2 == 0)
  382. return false;
  383. num += num2;
  384. }
  385. while (num < rd.Length);
  386. return true;
  387. }
  388. catch
  389. {
  390. return false;
  391. }
  392. }
  393. }
  394. internal class ConvertClass
  395. {
  396. //
  397. // Summary:
  398. // 得到枚举值
  399. //
  400. // Parameters:
  401. // txt:
  402. // 如:D100,W100.1
  403. //
  404. // txtq:100.1
  405. internal static bool GetPlcMemory(string txt, out string txtq, out PlcMemory plcMemory)
  406. {
  407. txtq = string.Empty;
  408. char c = txt.Trim().ToUpper().FirstOrDefault();
  409. plcMemory = c switch
  410. {
  411. 'D' => PlcMemory.DM,
  412. 'W' => PlcMemory.WR,
  413. 'H' => PlcMemory.HR,
  414. 'A' => PlcMemory.AR,
  415. 'C' => PlcMemory.CNT,
  416. 'I' => PlcMemory.CIO,
  417. 'T' => PlcMemory.TIM,
  418. _ => PlcMemory.Undefined,
  419. };
  420. if (plcMemory == PlcMemory.Undefined)
  421. return false;
  422. txtq = Regex.Replace(txt, "[^0-9.]", "");
  423. return true;
  424. }
  425. }
  426. internal class ErrorCode
  427. {
  428. //
  429. // Summary:
  430. // (若返回的头指令为3)检查命令头中的错误代码
  431. //
  432. // Parameters:
  433. // Code:
  434. // 错误代码
  435. //
  436. // Returns:
  437. // 指示程序是否可以继续进行
  438. internal static bool CheckHeadError(byte Code)
  439. {
  440. Console.WriteLine($"Error Code {Code}");
  441. return Code == 0;
  442. }
  443. //
  444. // Summary:
  445. // 检查命令帧中的EndCode
  446. //
  447. // Parameters:
  448. // Main:
  449. // 主码
  450. //
  451. // Sub:
  452. // 副码
  453. //
  454. // Returns:
  455. // 指示程序是否可以继续进行
  456. internal static bool CheckEndCode(byte Main, byte Sub)
  457. {
  458. //Totally dont understand what's doing here, Replace with the code below
  459. return Main == 0 && (Sub == 64 || Sub == 0);
  460. //switch (Main)
  461. //{
  462. // case 0:
  463. // switch (Sub)
  464. // {
  465. // case 0:
  466. // case 64:
  467. // return true;
  468. // case 1:
  469. // return false;
  470. // }
  471. // break;
  472. // case 1:
  473. // switch (Sub)
  474. // {
  475. // case 1:
  476. // case 2:
  477. // case 3:
  478. // case 4:
  479. // case 5:
  480. // case 6:
  481. // return false;
  482. // }
  483. // break;
  484. // case 2:
  485. // switch (Sub)
  486. // {
  487. // case 1:
  488. // case 2:
  489. // case 3:
  490. // case 4:
  491. // case 5:
  492. // return false;
  493. // }
  494. // break;
  495. // case 3:
  496. // switch (Sub)
  497. // {
  498. // case 1:
  499. // case 2:
  500. // case 3:
  501. // case 4:
  502. // return false;
  503. // }
  504. // break;
  505. // case 4:
  506. // switch (Sub)
  507. // {
  508. // case 1:
  509. // case 2:
  510. // return false;
  511. // }
  512. // break;
  513. // case 5:
  514. // switch (Sub)
  515. // {
  516. // case 1:
  517. // case 2:
  518. // case 3:
  519. // case 4:
  520. // return false;
  521. // }
  522. // break;
  523. // case 16:
  524. // switch (Sub)
  525. // {
  526. // case 1:
  527. // case 2:
  528. // case 3:
  529. // case 4:
  530. // case 5:
  531. // return false;
  532. // }
  533. // break;
  534. // case 17:
  535. // switch (Sub)
  536. // {
  537. // case 1:
  538. // case 2:
  539. // case 3:
  540. // case 4:
  541. // case 6:
  542. // case 9:
  543. // case 10:
  544. // case 11:
  545. // case 12:
  546. // return false;
  547. // }
  548. // break;
  549. // case 32:
  550. // switch (Sub)
  551. // {
  552. // case 2:
  553. // case 3:
  554. // case 4:
  555. // case 5:
  556. // case 6:
  557. // case 7:
  558. // return false;
  559. // }
  560. // break;
  561. // case 33:
  562. // switch (Sub)
  563. // {
  564. // case 1:
  565. // case 2:
  566. // case 3:
  567. // case 5:
  568. // case 6:
  569. // case 7:
  570. // case 8:
  571. // return false;
  572. // }
  573. // break;
  574. // case 34:
  575. // switch (Sub)
  576. // {
  577. // case 1:
  578. // case 2:
  579. // case 3:
  580. // case 4:
  581. // case 5:
  582. // case 6:
  583. // case 7:
  584. // case 8:
  585. // return false;
  586. // }
  587. // break;
  588. // case 35:
  589. // switch (Sub)
  590. // {
  591. // case 1:
  592. // case 2:
  593. // case 3:
  594. // return false;
  595. // }
  596. // break;
  597. // case 36:
  598. // {
  599. // byte b5 = Sub;
  600. // byte b6 = b5;
  601. // if (b6 != 1)
  602. // {
  603. // break;
  604. // }
  605. // return false;
  606. // }
  607. // case 37:
  608. // switch (Sub)
  609. // {
  610. // case 2:
  611. // case 3:
  612. // case 4:
  613. // case 5:
  614. // case 6:
  615. // case 7:
  616. // case 9:
  617. // case 10:
  618. // case 13:
  619. // case 15:
  620. // case 16:
  621. // return false;
  622. // }
  623. // break;
  624. // case 38:
  625. // switch (Sub)
  626. // {
  627. // case 1:
  628. // case 2:
  629. // case 4:
  630. // case 5:
  631. // case 6:
  632. // case 7:
  633. // case 8:
  634. // case 9:
  635. // case 10:
  636. // case 11:
  637. // return false;
  638. // }
  639. // break;
  640. // case 48:
  641. // {
  642. // byte b3 = Sub;
  643. // byte b4 = b3;
  644. // if (b4 != 1)
  645. // {
  646. // break;
  647. // }
  648. // return false;
  649. // }
  650. // case 64:
  651. // {
  652. // byte b = Sub;
  653. // byte b2 = b;
  654. // if (b2 != 1)
  655. // {
  656. // break;
  657. // }
  658. // return false;
  659. // }
  660. //}
  661. //return false;
  662. }
  663. }
  664. internal class FinsClass
  665. {
  666. //
  667. // Summary:
  668. // 获取内存区码
  669. //
  670. // Parameters:
  671. // mr:
  672. // 寄存器类型
  673. //
  674. // mt:
  675. // 地址类型
  676. internal static byte GetMemoryCode(PlcMemory mr, MemoryType mt)
  677. {
  678. if (mt == MemoryType.Bit)
  679. {
  680. return mr switch
  681. {
  682. PlcMemory.CIO => 48,
  683. PlcMemory.WR => 49,
  684. PlcMemory.HR => 50,
  685. PlcMemory.AR => 51,
  686. PlcMemory.DM => 2,
  687. PlcMemory.CNT or PlcMemory.TIM => 9,
  688. _ => 0,
  689. };
  690. }
  691. return mr switch
  692. {
  693. PlcMemory.CIO => 176,
  694. PlcMemory.WR => 177,
  695. PlcMemory.HR => 178,
  696. PlcMemory.AR => 179,
  697. PlcMemory.DM => 130,
  698. PlcMemory.CNT or PlcMemory.TIM => 137,
  699. _ => 0,
  700. };
  701. }
  702. internal static byte[] FinsCmd(Operation rw, PlcMemory mr, MemoryType mt, short ch, short offset, short cnt, byte PlcNode, byte PcNode)
  703. {
  704. byte[] array =
  705. [
  706. 70, 73, 78, 83, 0, 0, 0, 0, 0, 0,
  707. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  708. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  709. 0, 0, 0, 0
  710. ];
  711. if (rw == Operation.Read)
  712. {
  713. array[6] = 0;
  714. array[7] = 26;
  715. }
  716. else if (mt == MemoryType.Word)
  717. {
  718. array[6] = (byte)((cnt * 2 + 26) / 256);
  719. array[7] = (byte)((cnt * 2 + 26) % 256);
  720. }
  721. else
  722. {
  723. array[6] = 0;
  724. array[7] = 27;
  725. }
  726. array[11] = 2;
  727. array[16] = 128;
  728. array[18] = 2;
  729. array[20] = PlcNode;
  730. array[23] = PcNode;
  731. array[25] = byte.MaxValue;
  732. if (rw == Operation.Read)
  733. {
  734. array[26] = 1;
  735. array[27] = 1;
  736. }
  737. else
  738. {
  739. array[26] = 1;
  740. array[27] = 2;
  741. }
  742. array[28] = FinsClass.GetMemoryCode(mr, mt);
  743. if (mr == PlcMemory.CNT)
  744. {
  745. array[29] = (byte)(ch / 256 + 128);
  746. array[30] = (byte)(ch % 256);
  747. }
  748. else
  749. {
  750. array[29] = (byte)(ch / 256);
  751. array[30] = (byte)(ch % 256);
  752. array[31] = (byte)offset;
  753. }
  754. array[32] = (byte)(cnt / 256);
  755. array[33] = (byte)(cnt % 256);
  756. return array;
  757. }
  758. public static byte[] Header = [0x46, 0x49, 0x4E, 0x53];
  759. public static byte[] HandShakePack =
  760. [
  761. 0x46, 0x49, 0x4E, 0x53, //Header
  762. 0x00, 0x00, 0x00, 0x0c, //Length
  763. 0x00, 0x00, 0x00, 0x00, //Command
  764. 0x00, 0x00, 0x00, 0x00, //ErrorCode
  765. 0x00, 0x00, 0x00, 0x00 //Client Node
  766. ];
  767. }
  768. public enum PlcMemory
  769. {
  770. CIO,
  771. WR,
  772. HR,
  773. AR,
  774. DM,
  775. CNT,
  776. TIM,
  777. Undefined,
  778. }
  779. public enum Operation
  780. {
  781. Read,
  782. Write
  783. }
  784. public enum MemoryType
  785. {
  786. Bit,
  787. Word
  788. }
  789. public enum BitState
  790. {
  791. ON = 1,
  792. OFF = 0
  793. }