ModbusTcpMaster.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Threading.Tasks;
  8. using NModbus;
  9. namespace Team.Communicate.Modbus
  10. {
  11. public class ModbusTcpMaster : IModbusTcpMaster
  12. {
  13. private readonly string _ip;
  14. private readonly int _port;
  15. public DataFormat DataFormat { get; set; } = DataFormat.CDAB;
  16. public int ConnectTimeOut { get; set; }
  17. public string Ip { get => _ip; }
  18. public int Port { get => _port; }
  19. public bool IsConnect { get; private set; }
  20. private IModbusMaster _modbusMaster;
  21. private TcpClient _client;
  22. public event EventHandler<bool> ConnectChanged;
  23. public ModbusTcpMaster(string ip, int port)
  24. {
  25. _ip = ip;
  26. _port = port;
  27. var modbusFactory = new ModbusFactory();
  28. _client = new TcpClient();
  29. _modbusMaster = modbusFactory.CreateMaster(_client);
  30. }
  31. /// <summary>
  32. /// client must is connected
  33. /// </summary>
  34. /// <param name="client"></param>
  35. public ModbusTcpMaster(TcpClient client)
  36. {
  37. if (client == null)
  38. throw new ArgumentNullException("client");
  39. if (!client.Connected) throw new ArgumentNullException("client is not connected");
  40. var iPEndPoint= client.Client.RemoteEndPoint as IPEndPoint;
  41. _ip = iPEndPoint.Address.ToString();
  42. _port= iPEndPoint.Port;
  43. //_port = port;
  44. var modbusFactory = new ModbusFactory();
  45. _client = client;
  46. _modbusMaster = modbusFactory.CreateMaster(_client);
  47. }
  48. public void Connect()
  49. {
  50. try
  51. {
  52. _client.Connect(_ip, _port);
  53. IsConnect = true;
  54. OnConnectChanged(true);
  55. }
  56. catch (Exception e)
  57. {
  58. OnConnectChanged(false);
  59. IsConnect = false;
  60. }
  61. }
  62. public byte SlaveId { get; set; } = 1;
  63. public async Task ConnectAsync()
  64. {
  65. try
  66. {
  67. if (_client.Connected)
  68. {
  69. return;
  70. }
  71. await _client.ConnectAsync(_ip, _port);
  72. OnConnectChanged(true);
  73. IsConnect = true;
  74. }
  75. catch (Exception e)
  76. {
  77. Console.WriteLine(e);
  78. OnConnectChanged(false);
  79. IsConnect = false;
  80. }
  81. }
  82. public async Task<bool> ReConnect()
  83. {
  84. if (_client != null)
  85. {
  86. _client.Dispose();
  87. }
  88. try
  89. {
  90. _client = new TcpClient();
  91. if (_client.Connected)
  92. {
  93. return true;
  94. }
  95. await _client.ConnectAsync(_ip, _port);
  96. var modbusFactory = new ModbusFactory();
  97. _modbusMaster = modbusFactory.CreateMaster(_client);
  98. OnConnectChanged(true);
  99. IsConnect = true;
  100. }
  101. catch (Exception e)
  102. {
  103. Console.WriteLine(e);
  104. OnConnectChanged(false);
  105. IsConnect = false;
  106. }
  107. return IsConnect;
  108. }
  109. public ushort[] ReadBytes(ushort start, ushort length)
  110. {
  111. var byteData = _modbusMaster.ReadHoldingRegisters(SlaveId, start, length);
  112. return byteData;
  113. }
  114. /// <summary>
  115. /// 获取单个位状态
  116. /// </summary>
  117. /// <param name="start">从PLC里读出第几个字节</param>
  118. /// <param name="index">第几位</param>
  119. /// <returns></returns>
  120. public bool GetBool(ushort start, ushort index)
  121. {
  122. try
  123. {
  124. var byteData = _modbusMaster.ReadHoldingRegisters(SlaveId, start, 1);
  125. var num = byteData[0];
  126. var bitGroup = new bool[16];
  127. for (ushort i = 0; i < 16; i++)
  128. {
  129. bitGroup[i] = ((num >> i) & 1) == 1;
  130. }
  131. return bitGroup[index];
  132. }
  133. catch (IOException)
  134. {
  135. OnConnectChanged(false);
  136. IsConnect = false;
  137. throw;
  138. }
  139. catch (Exception e)
  140. {
  141. Console.WriteLine(e);
  142. throw;
  143. }
  144. }
  145. public List<KeyValuePair<string, bool>> GetBoolList(IEnumerable<string> addresses)
  146. {
  147. var boolList = new List<KeyValuePair<string, bool>>();
  148. var byteData = _modbusMaster.ReadHoldingRegisters(SlaveId, 0, 50);
  149. foreach (var address in addresses)
  150. {
  151. var stringSplits = address.Split('.');
  152. var byteIndex = ushort.Parse(stringSplits[0]);
  153. var byteIndex1 = byteIndex % 2 == 0 ? byteIndex / 2: byteIndex-1 / 2;
  154. var index = int.Parse(stringSplits[1]);
  155. var num = byteData[byteIndex1];
  156. var bitGroup = new bool[16];
  157. for (ushort i = 0; i < 16; i++)
  158. {
  159. bitGroup[i] = ((num >> i) & 1) == 1;
  160. }
  161. var addressValue = bitGroup[index];
  162. boolList.Add(new KeyValuePair<string, bool>(address, addressValue));
  163. }
  164. return boolList;
  165. }
  166. /// <summary>
  167. /// 获取单个位状态
  168. /// </summary>
  169. /// <param name="start">从PLC里读出第几个字节</param>
  170. /// <param name="index" >第几位</param>
  171. /// <returns></returns>
  172. public async Task<bool> GetBoolAsync(ushort start, ushort index)
  173. {
  174. try
  175. {
  176. var byteData = await _modbusMaster.ReadHoldingRegistersAsync(SlaveId, start, 1);
  177. var num = byteData[0];
  178. var tempBytes = BitConverter.GetBytes(num);
  179. var revertBytes = tempBytes.Reverse().ToArray();
  180. var realValue = BitConverter.ToUInt16(revertBytes, 0);
  181. var bitGroup = new bool[16];
  182. for (ushort i = 0; i < 16; i++)
  183. {
  184. bitGroup[i] = ((realValue >> i) & 1) == 1;
  185. }
  186. return bitGroup[index];
  187. }
  188. catch (IOException)
  189. {
  190. OnConnectChanged(false);
  191. IsConnect = false;
  192. throw;
  193. }
  194. catch (Exception e)
  195. {
  196. Console.WriteLine(e);
  197. throw;
  198. }
  199. }
  200. /// <summary>
  201. /// 写modbus位
  202. /// </summary>
  203. /// <param name="start"></param>
  204. /// <param name="index"></param>
  205. /// <param name="flag"></param>
  206. public void WriteBool(ushort start, int index, bool flag)
  207. {
  208. try
  209. {
  210. var doCh = new bool[16];
  211. var currentValue = GetShort(start);
  212. for (ushort i = 0; i < 16; i++)
  213. {
  214. doCh[i] = ((currentValue >> i) & 1) == 1; //获取PLC当前状态
  215. }
  216. ushort outValue = 0;
  217. doCh[index] = flag;
  218. var front = new bool[8];
  219. var back = new bool[8];
  220. Array.Copy(doCh, 0, front, 0, 8);
  221. Array.Copy(doCh, 8, back, 0, 8);
  222. for (ushort i = 0; i < 16; i++)
  223. {
  224. outValue |= (ushort) (Convert.ToUInt16(doCh[i]) << i);
  225. }
  226. _modbusMaster.WriteMultipleRegisters(SlaveId, start, new[] {outValue});
  227. }
  228. catch (IOException)
  229. {
  230. OnConnectChanged(false);
  231. IsConnect = false;
  232. throw;
  233. }
  234. }
  235. /// <summary>
  236. /// 写modbus位
  237. /// </summary>
  238. /// <param name="start"></param>
  239. /// <param name="index"></param>
  240. /// <param name="flag"></param>
  241. public async Task WriteBoolAsync(ushort start, int index, bool flag)
  242. {
  243. try
  244. {
  245. var doCh = new bool[16];
  246. var currentValue = await GetShortAsync(start);
  247. for (ushort i = 0; i < 16; i++)
  248. {
  249. doCh[i] = ((currentValue >> i) & 1) == 1; //获取PLC当前状态
  250. }
  251. ushort outValue = 0;
  252. doCh[index] = flag;
  253. var front = new bool[8];
  254. var back = new bool[8];
  255. Array.Copy(doCh, 0, front, 0, 8);
  256. Array.Copy(doCh, 8, back, 0, 8);
  257. for (ushort i = 0; i < 16; i++)
  258. {
  259. outValue |= (ushort) (Convert.ToUInt16(doCh[i]) << i);
  260. }
  261. var reverseValue = BitConverter.GetBytes(outValue);
  262. var outValue1 = BitConverter.ToUInt16(reverseValue, 0);
  263. await _modbusMaster.WriteMultipleRegistersAsync(SlaveId, start, new[] {outValue1});
  264. }
  265. catch (IOException)
  266. {
  267. OnConnectChanged(false);
  268. IsConnect = false;
  269. throw;
  270. }
  271. }
  272. /// <summary>
  273. /// 写modbus位
  274. /// </summary>
  275. /// <param name="start"></param>
  276. /// <param name="index"></param>
  277. /// <param name="value"></param>
  278. public void WriteByte(ushort start, int index, byte value)
  279. {
  280. try
  281. {
  282. var currentValue = GetShort(start);
  283. var bytes = BitConverter.GetBytes(currentValue);
  284. bytes[index] = value;
  285. var writeValue = BitConverter.ToUInt16(bytes, 0);
  286. _modbusMaster.WriteMultipleRegisters(SlaveId, start, new[] {writeValue});
  287. }
  288. catch (IOException)
  289. {
  290. OnConnectChanged(false);
  291. IsConnect = false;
  292. throw;
  293. }
  294. }
  295. /// <summary>
  296. /// 写modbus位
  297. /// </summary>
  298. /// <param name="start"></param>
  299. /// <param name="index"></param>
  300. /// <param name="value"></param>
  301. public async Task WriteByteAsync(ushort start, int index, byte value)//todo need to test
  302. {
  303. try
  304. {
  305. var currentValue = await GetShortAsync(start);
  306. var bytes = BitConverter.GetBytes(currentValue);
  307. bytes[index] = value;
  308. var writeValue = BitConverter.ToUInt16(bytes, 0);
  309. await _modbusMaster.WriteSingleRegisterAsync(SlaveId, start, writeValue);
  310. }
  311. catch (IOException)
  312. {
  313. OnConnectChanged(false);
  314. IsConnect = false;
  315. throw;
  316. }
  317. catch (Exception e)
  318. {
  319. Console.WriteLine(e);
  320. throw;
  321. }
  322. }
  323. /// <summary>
  324. /// 获取浮点数值
  325. /// </summary>
  326. /// <param name="index">数据索引</param>
  327. /// <returns></returns>
  328. public float GetFloat(ushort index)
  329. {
  330. try
  331. {
  332. var shortData = _modbusMaster.ReadHoldingRegisters(SlaveId, index, 2);
  333. var bytes1 = BitConverter.GetBytes(shortData[0]);
  334. var bytes2 = BitConverter.GetBytes(shortData[1]);
  335. var mergeBytes = bytes1.Concat(bytes2);
  336. return BitConverter.ToSingle(mergeBytes.ToArray(), 0);
  337. }
  338. catch (IOException)
  339. {
  340. OnConnectChanged(false);
  341. IsConnect = false;
  342. throw;
  343. }
  344. catch (Exception e)
  345. {
  346. Console.WriteLine(e);
  347. throw;
  348. }
  349. }
  350. /// <summary>
  351. /// 获取浮点数值
  352. /// </summary>
  353. /// <param name="index">数据索引</param>
  354. /// <returns></returns>
  355. public async Task<float> GetFloatAsync(ushort index)
  356. {
  357. try
  358. {
  359. var shortData = await _modbusMaster.ReadHoldingRegistersAsync(SlaveId, index, 2);
  360. var bytes1 = BitConverter.GetBytes(shortData[0]);
  361. var bytes2 = BitConverter.GetBytes(shortData[1]);
  362. var mergeBytes = bytes1.Concat(bytes2);
  363. return BitConverter.ToSingle(mergeBytes.ToArray(), 0);
  364. }
  365. catch (IOException)
  366. {
  367. OnConnectChanged(false);
  368. IsConnect = false;
  369. throw;
  370. }
  371. catch (Exception e)
  372. {
  373. Console.WriteLine(e);
  374. throw;
  375. }
  376. }
  377. /// <summary>
  378. /// 获取字
  379. /// </summary>
  380. /// <param name="index">数据索引</param>
  381. /// <returns></returns>
  382. public ushort GetShort(ushort index)
  383. {
  384. try
  385. {
  386. var shortData = _modbusMaster.ReadHoldingRegisters(SlaveId, index, 1);
  387. var shortBytes = BitConverter.GetBytes(shortData[0]);
  388. var realBytes = shortBytes;
  389. var realValue = BitConverter.ToUInt16(realBytes, 0);
  390. return realValue;
  391. }
  392. catch (IOException)
  393. {
  394. OnConnectChanged(false);
  395. IsConnect = false;
  396. throw;
  397. }
  398. }
  399. /// <summary>
  400. /// 获取字
  401. /// </summary>
  402. /// <param name="index">数据索引</param>
  403. /// <returns></returns>
  404. public async Task<ushort> GetShortAsync(ushort index)
  405. {
  406. try
  407. {
  408. var shortData = await _modbusMaster.ReadHoldingRegistersAsync(SlaveId, index, 1);
  409. var shortBytes = BitConverter.GetBytes(shortData[0]);
  410. var realValue = BitConverter.ToUInt16(shortBytes, 0);
  411. return realValue;
  412. }
  413. catch (IOException)
  414. {
  415. IsConnect = false;
  416. throw;
  417. }
  418. }
  419. /// <summary>
  420. /// 获取整型数值
  421. /// </summary>
  422. /// 4字节整数
  423. /// <param name="index">数据索引</param>
  424. /// <returns></returns>
  425. public int GetInteger(ushort index)
  426. {
  427. try
  428. {
  429. var shortData = _modbusMaster.ReadHoldingRegisters(SlaveId, index, 2);
  430. var bytes1 = BitConverter.GetBytes(shortData[0]);
  431. var bytes2 = BitConverter.GetBytes(shortData[1]);
  432. var mergeBytes = bytes1.Concat(bytes2);
  433. return BitConverter.ToInt32(mergeBytes.ToArray(), 0);
  434. }
  435. catch (IOException)
  436. {
  437. IsConnect = false;
  438. throw;
  439. }
  440. catch (Exception e)
  441. {
  442. Console.WriteLine(e);
  443. throw;
  444. }
  445. }
  446. /// <summary>
  447. /// 异步获取整型数值
  448. /// </summary>
  449. /// 4字节整数
  450. /// <param name="index">数据索引</param>
  451. /// <returns></returns>
  452. public async Task<int> GetIntegerAsync(ushort index)
  453. {
  454. try
  455. {
  456. var shortData = await _modbusMaster.ReadHoldingRegistersAsync(SlaveId, index, 2);
  457. var bytes1 = BitConverter.GetBytes(shortData[0]);
  458. var bytes2 = BitConverter.GetBytes(shortData[1]);
  459. var mergeBytes = bytes1.Concat(bytes2);
  460. return BitConverter.ToInt32(mergeBytes.ToArray(), 0);
  461. }
  462. catch (IOException)
  463. {
  464. IsConnect = false;
  465. OnConnectChanged(false);
  466. throw;
  467. }
  468. catch (Exception e)
  469. {
  470. Console.WriteLine(e);
  471. throw;
  472. }
  473. }
  474. /// <summary>
  475. /// 读字节
  476. /// </summary>
  477. /// <param name="start">开始字索引</param>
  478. /// <param name="index">第几个字节</param>
  479. /// <returns></returns>
  480. public async Task<byte> GetByteAsync(ushort start, int index)
  481. {
  482. try
  483. {
  484. var shortData = await _modbusMaster.ReadHoldingRegistersAsync(SlaveId, start, 1);
  485. var bytes1 = BitConverter.GetBytes(shortData[0]).Reverse().ToArray();
  486. return bytes1[index];
  487. }
  488. catch (IOException)
  489. {
  490. IsConnect = false;
  491. OnConnectChanged(false);
  492. throw;
  493. }
  494. catch (Exception e)
  495. {
  496. Console.WriteLine(e);
  497. throw;
  498. }
  499. }
  500. /// <summary>
  501. /// 读字节
  502. /// </summary>
  503. /// <param name="start">开始字索引</param>
  504. /// <param name="index">第几个字节</param>
  505. /// <returns></returns>
  506. public byte GetByte(ushort start, int index)
  507. {
  508. try
  509. {
  510. var shortData = _modbusMaster.ReadHoldingRegisters(SlaveId, start, 1);
  511. var bytes1 = BitConverter.GetBytes(shortData[0]).Reverse().ToArray();
  512. return bytes1[index];
  513. }
  514. catch (IOException)
  515. {
  516. OnConnectChanged(false);
  517. IsConnect = false;
  518. throw;
  519. }
  520. catch (Exception e)
  521. {
  522. Console.WriteLine(e);
  523. throw;
  524. }
  525. }
  526. /// <summary>
  527. /// 反转多字节的数据信息
  528. /// </summary>
  529. /// <param name="value">数据字节</param>
  530. /// <param name="index">起始索引,默认值为0</param>
  531. /// <returns>实际字节信息</returns>
  532. protected byte[] ByteTransDataFormat2(byte[] value, int index = 0)
  533. {
  534. var buffer = new byte[2];
  535. switch (DataFormat)
  536. {
  537. case DataFormat.ABCD:
  538. {
  539. buffer[0] = value[index + 1];
  540. buffer[1] = value[index + 0];
  541. break;
  542. }
  543. case DataFormat.BADC:
  544. {
  545. buffer[0] = value[index + 0];
  546. buffer[1] = value[index + 1];
  547. break;
  548. }
  549. case DataFormat.CDAB:
  550. {
  551. buffer[0] = value[index + 1];
  552. buffer[1] = value[index + 0];
  553. break;
  554. }
  555. case DataFormat.DCBA:
  556. {
  557. buffer[0] = value[index + 0];
  558. buffer[1] = value[index + 1];
  559. break;
  560. }
  561. }
  562. return buffer;
  563. }
  564. /// <summary>
  565. /// 反转多字节的数据信息
  566. /// </summary>
  567. /// <param name="value">数据字节</param>
  568. /// <param name="index">起始索引,默认值为0</param>
  569. /// <returns>实际字节信息</returns>
  570. protected byte[] ByteTransDataFormat8(byte[] value, int index = 0)
  571. {
  572. byte[] buffer = new byte[8];
  573. switch (DataFormat)
  574. {
  575. case DataFormat.ABCD:
  576. {
  577. buffer[0] = value[index + 7];
  578. buffer[1] = value[index + 6];
  579. buffer[2] = value[index + 5];
  580. buffer[3] = value[index + 4];
  581. buffer[4] = value[index + 3];
  582. buffer[5] = value[index + 2];
  583. buffer[6] = value[index + 1];
  584. buffer[7] = value[index + 0];
  585. break;
  586. }
  587. case DataFormat.BADC:
  588. {
  589. buffer[0] = value[index + 6];
  590. buffer[1] = value[index + 7];
  591. buffer[2] = value[index + 4];
  592. buffer[3] = value[index + 5];
  593. buffer[4] = value[index + 2];
  594. buffer[5] = value[index + 3];
  595. buffer[6] = value[index + 0];
  596. buffer[7] = value[index + 1];
  597. break;
  598. }
  599. case DataFormat.CDAB:
  600. {
  601. buffer[0] = value[index + 1];
  602. buffer[1] = value[index + 0];
  603. buffer[2] = value[index + 3];
  604. buffer[3] = value[index + 2];
  605. buffer[4] = value[index + 5];
  606. buffer[5] = value[index + 4];
  607. buffer[6] = value[index + 7];
  608. buffer[7] = value[index + 6];
  609. break;
  610. }
  611. case DataFormat.DCBA:
  612. {
  613. buffer[0] = value[index + 0];
  614. buffer[1] = value[index + 1];
  615. buffer[2] = value[index + 2];
  616. buffer[3] = value[index + 3];
  617. buffer[4] = value[index + 4];
  618. buffer[5] = value[index + 5];
  619. buffer[6] = value[index + 6];
  620. buffer[7] = value[index + 7];
  621. break;
  622. }
  623. }
  624. return buffer;
  625. }
  626. /// <summary>
  627. /// 反转多字节的数据信息
  628. /// </summary>
  629. /// <param name="value">数据字节</param>
  630. /// <param name="index">起始索引,默认值为0</param>
  631. /// <returns>实际字节信息</returns>
  632. protected byte[] ByteTransDataFormat4(byte[] value, int index = 0)
  633. {
  634. var buffer = new byte[4];
  635. switch (DataFormat)
  636. {
  637. case DataFormat.ABCD:
  638. {
  639. buffer[0] = value[index + 3];
  640. buffer[1] = value[index + 2];
  641. buffer[2] = value[index + 1];
  642. buffer[3] = value[index + 0];
  643. break;
  644. }
  645. case DataFormat.BADC:
  646. {
  647. buffer[0] = value[index + 2];
  648. buffer[1] = value[index + 3];
  649. buffer[2] = value[index + 0];
  650. buffer[3] = value[index + 1];
  651. break;
  652. }
  653. case DataFormat.CDAB:
  654. {
  655. buffer[0] = value[index + 1];
  656. buffer[1] = value[index + 0];
  657. buffer[2] = value[index + 3];
  658. buffer[3] = value[index + 2];
  659. break;
  660. }
  661. case DataFormat.DCBA:
  662. {
  663. buffer[0] = value[index + 0];
  664. buffer[1] = value[index + 1];
  665. buffer[2] = value[index + 2];
  666. buffer[3] = value[index + 3];
  667. break;
  668. }
  669. }
  670. return buffer;
  671. }
  672. public virtual byte[] TransByte(int[] values)
  673. {
  674. if (values == null) return null;
  675. byte[] buffer = new byte[values.Length * 4];
  676. for (int i = 0; i < values.Length; i++)
  677. {
  678. ByteTransDataFormat4(BitConverter.GetBytes(values[i])).CopyTo(buffer, 4 * i);
  679. }
  680. return buffer;
  681. }
  682. public virtual byte[] TransByte(ushort[] values)
  683. {
  684. if (values == null) return null;
  685. byte[] buffer = new byte[values.Length * 2];
  686. for (int i = 0; i < values.Length; i++)
  687. {
  688. BitConverter.GetBytes(values[i]).CopyTo(buffer, 2 * i);
  689. }
  690. return buffer;
  691. }
  692. public void WriteDouble(ushort start, double value)
  693. {
  694. var convertBytes = BitConverter.GetBytes(value);
  695. var writeValues = new ushort[2];
  696. for (var i = 0; i < 4; i++)
  697. {
  698. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  699. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  700. }
  701. _modbusMaster.WriteMultipleRegisters(SlaveId, start, writeValues);
  702. }
  703. public async Task WriteDoubleAsync(ushort start, double value)
  704. {
  705. var convertBytes = BitConverter.GetBytes(value);
  706. var writeValues = new ushort[4];
  707. for (var i = 0; i < 4; i++)
  708. {
  709. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  710. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  711. }
  712. await _modbusMaster.WriteMultipleRegistersAsync(SlaveId, start, writeValues);
  713. }
  714. public void WriteFloat(ushort start, float value)
  715. {
  716. var convertBytes = BitConverter.GetBytes(value);
  717. var writeValues = new ushort[2];
  718. for (int i = 0; i < 4; i++)
  719. {
  720. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  721. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  722. }
  723. _modbusMaster.WriteMultipleRegisters(SlaveId, start, writeValues);
  724. }
  725. public async Task WriteFloatAsync(ushort start, float value)
  726. {
  727. var convertBytes = BitConverter.GetBytes(value);
  728. var writeValues = new ushort[2];
  729. for (var i = 0; i < 2; i++)
  730. {
  731. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  732. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  733. }
  734. await _modbusMaster.WriteMultipleRegistersAsync(SlaveId, start, writeValues);
  735. }
  736. public void WriteInt32(ushort start, int value)
  737. {
  738. var convertBytes = BitConverter.GetBytes(value);
  739. var writeValues = new ushort[2];
  740. for (int i = 0; i < 2; i++)
  741. {
  742. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  743. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  744. }
  745. _modbusMaster.WriteMultipleRegisters(SlaveId, start, writeValues);
  746. }
  747. public async Task WriteInt32Async(ushort start, int value)
  748. {
  749. var convertBytes = BitConverter.GetBytes(value);
  750. var writeValues = new ushort[2];
  751. for (var i = 0; i < 2; i++)
  752. {
  753. var bytes = new[] { convertBytes[i * 2], convertBytes[i * 2 + 1] };
  754. writeValues[i] = BitConverter.ToUInt16(bytes, 0);
  755. }
  756. await _modbusMaster.WriteMultipleRegistersAsync(SlaveId, start, writeValues);
  757. }
  758. public ushort[] GetBytes(ushort start, ushort length)
  759. {
  760. var nums= _modbusMaster.ReadInputRegisters(1,start, length);
  761. return nums;
  762. }
  763. public Task<ushort[]> GetBytesAsync(ushort start, ushort length)
  764. {
  765. return _modbusMaster.ReadInputRegistersAsync(SlaveId, start, length);
  766. }
  767. private void OnConnectChanged(bool state)
  768. {
  769. ConnectChanged?.Invoke(this, state);
  770. }
  771. }
  772. }