FinsTcpBase.cs 23 KB

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