MelsecA1EAsciiNet.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using HslCommunication.Core;
  6. using HslCommunication.Core.IMessage;
  7. using HslCommunication.Core.Net;
  8. namespace HslCommunication.Profinet.Melsec
  9. {
  10. /// <summary>
  11. /// 三菱PLC通讯协议,采用A兼容1E帧协议实现,使用Ascii码通讯,请根据实际型号来进行选取
  12. /// </summary>
  13. public class MelsecA1EAsciiNet : NetworkDoubleBase<MelsecA1EAsciiMessage, RegularByteTransform>, IReadWriteNet
  14. {
  15. #region Constructor
  16. /// <summary>
  17. /// 实例化三菱的A兼容1E帧协议的通讯对象
  18. /// </summary>
  19. public MelsecA1EAsciiNet()
  20. {
  21. }
  22. /// <summary>
  23. /// 实例化一个三菱的A兼容1E帧协议的通讯对象
  24. /// </summary>
  25. /// <param name="ipAddress">PLC的Ip地址</param>
  26. /// <param name="port">PLC的端口</param>
  27. public MelsecA1EAsciiNet(string ipAddress, int port)
  28. {
  29. IpAddress = ipAddress;
  30. Port = port;
  31. }
  32. #endregion
  33. #region Public Member
  34. /// <summary>
  35. /// PLC编号
  36. /// </summary>
  37. public byte PLCNumber { get; set; } = 0xFF;
  38. #endregion
  39. #region Address Analysis
  40. /// <summary>
  41. /// 解析数据地址
  42. /// </summary>
  43. /// <param name="address">数据地址</param>
  44. /// <returns></returns>
  45. private OperateResult<MelsecA1EDataType, ushort> AnalysisAddress(string address)
  46. {
  47. var result = new OperateResult<MelsecA1EDataType, ushort>();
  48. try
  49. {
  50. switch (address[0])
  51. {
  52. case 'X':
  53. case 'x':
  54. {
  55. result.Content1 = MelsecA1EDataType.X;
  56. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.X.FromBase);
  57. break;
  58. }
  59. case 'Y':
  60. case 'y':
  61. {
  62. result.Content1 = MelsecA1EDataType.Y;
  63. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.Y.FromBase);
  64. break;
  65. }
  66. case 'M':
  67. case 'm':
  68. {
  69. result.Content1 = MelsecA1EDataType.M;
  70. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.M.FromBase);
  71. break;
  72. }
  73. case 'S':
  74. case 's':
  75. {
  76. result.Content1 = MelsecA1EDataType.S;
  77. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.S.FromBase);
  78. break;
  79. }
  80. case 'D':
  81. case 'd':
  82. {
  83. result.Content1 = MelsecA1EDataType.D;
  84. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.D.FromBase);
  85. break;
  86. }
  87. case 'R':
  88. case 'r':
  89. {
  90. result.Content1 = MelsecA1EDataType.R;
  91. result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.R.FromBase);
  92. break;
  93. }
  94. default: throw new Exception("输入的类型不支持,请重新输入");
  95. }
  96. }
  97. catch (Exception ex)
  98. {
  99. result.Message = "地址格式填写错误:" + ex.Message;
  100. return result;
  101. }
  102. result.IsSuccess = true;
  103. return result;
  104. }
  105. #endregion
  106. #region Build Command
  107. /// <summary>
  108. /// 根据类型地址长度确认需要读取的指令头
  109. /// </summary>
  110. /// <param name="address">起始地址</param>
  111. /// <param name="length">长度</param>
  112. /// <returns>带有成功标志的指令数据</returns>
  113. private OperateResult<MelsecA1EDataType, byte[]> BuildReadCommand(string address, ushort length)
  114. {
  115. var result = new OperateResult<MelsecA1EDataType, byte[]>();
  116. var analysis = AnalysisAddress(address);
  117. if (!analysis.IsSuccess)
  118. {
  119. result.CopyErrorFromOther(analysis);
  120. return result;
  121. }
  122. // 默认信息----注意:高低字节交错
  123. byte Subtitle = 0x00;
  124. if (analysis.Content1.DataType == 0x01) { Subtitle = 0x00; }
  125. else { Subtitle = 0x01; }
  126. byte[] _PLCCommand = new byte[24];
  127. _PLCCommand[0] = Subtitle; // 副标题
  128. _PLCCommand[1] = PLCNumber; // PLC号
  129. //_PLCCommand[2] = 0x0A; // CPU监视定时器(L)这里设置为0x00,0x0A,等待CPU返回的时间为10*250ms=2.5秒
  130. //_PLCCommand[3] = 0x00; // CPU监视定时器(H)
  131. //_PLCCommand[4] = (byte)(analysis.Content2 % 256); // 起始软元件(开始读取的地址)
  132. //_PLCCommand[5] = (byte)(analysis.Content2 / 256);
  133. //_PLCCommand[6] = 0x00;
  134. //_PLCCommand[7] = 0x00;
  135. //_PLCCommand[8] = analysis.Content1.DataCode[1]; // 软元件代码(L)
  136. //_PLCCommand[9] = analysis.Content1.DataCode[0]; // 软元件代码(H)
  137. //_PLCCommand[10] = (byte)(length % 256); // 软元件点数
  138. //_PLCCommand[11] = 0x00;
  139. _PLCCommand[2] = 0x00;
  140. _PLCCommand[3] = 0x0C;
  141. _PLCCommand[4] = analysis.Content1.DataCode[0]; // 软元件代码(H)
  142. _PLCCommand[5] = analysis.Content1.DataCode[1]; // 软元件代码(L)
  143. _PLCCommand[6] = 0x00;
  144. _PLCCommand[7] = 0x00;
  145. _PLCCommand[8] = (byte)(analysis.Content2 / 256);
  146. _PLCCommand[9] = (byte)(analysis.Content2 % 256); // 起始软元件(开始读取的地址)
  147. _PLCCommand[11] = 0x00;
  148. _PLCCommand[10] = (byte)(length % 256); // 软元件点数
  149. result.Content1 = analysis.Content1;
  150. result.Content2 = _PLCCommand;
  151. result.IsSuccess = true;
  152. return result;
  153. }
  154. /// <summary>
  155. /// 根据类型地址以及需要写入的数据来生成指令头
  156. /// </summary>
  157. /// <param name="address">起始地址</param>
  158. /// <param name="value"></param>
  159. /// <param name="length">指定长度</param>
  160. /// <returns></returns>
  161. private OperateResult<MelsecA1EDataType, byte[]> BuildWriteCommand(string address, byte[] value, int length = -1)
  162. {
  163. var result = new OperateResult<MelsecA1EDataType, byte[]>();
  164. var analysis = AnalysisAddress(address);
  165. if (!analysis.IsSuccess)
  166. {
  167. result.CopyErrorFromOther(analysis);
  168. return result;
  169. }
  170. // 默认信息----注意:高低字节交错
  171. byte Subtitle = 0x00;
  172. if (analysis.Content1.DataType == 0x01) { Subtitle = 0x02; }
  173. else { Subtitle = 0x03; }
  174. byte[] _PLCCommand = new byte[12 + value.Length];
  175. _PLCCommand[0] = Subtitle; // 副标题
  176. _PLCCommand[1] = PLCNumber; // PLC号
  177. _PLCCommand[2] = 0x0A; // CPU监视定时器(L)这里设置为0x00,0x0A,等待CPU返回的时间为10*250ms=2.5秒
  178. _PLCCommand[3] = 0x00; // CPU监视定时器(H)
  179. _PLCCommand[4] = (byte)(analysis.Content2 % 256); // 起始软元件(开始读取的地址)
  180. _PLCCommand[5] = (byte)(analysis.Content2 / 256);
  181. _PLCCommand[6] = 0x00;
  182. _PLCCommand[7] = 0x00;
  183. _PLCCommand[8] = analysis.Content1.DataCode[1]; // 软元件代码(L)
  184. _PLCCommand[9] = analysis.Content1.DataCode[0]; // 软元件代码(H)
  185. _PLCCommand[10] = (byte)(length % 256); // 软元件点数
  186. _PLCCommand[11] = 0x00;
  187. // 判断是否进行位操作
  188. if (analysis.Content1.DataType == 0x01)
  189. {
  190. if (length > 0)
  191. {
  192. _PLCCommand[10] = (byte)(length % 256); // 软元件点数
  193. }
  194. else
  195. {
  196. _PLCCommand[10] = (byte)(value.Length * 2 % 256); // 软元件点数
  197. }
  198. }
  199. else
  200. {
  201. _PLCCommand[10] = (byte)(value.Length / 2 % 256); // 软元件点数
  202. }
  203. Array.Copy(value, 0, _PLCCommand, 12, value.Length); // 将具体的要写入的数据附加到写入命令后面
  204. result.Content1 = analysis.Content1;
  205. result.Content2 = _PLCCommand;
  206. result.IsSuccess = true;
  207. return result;
  208. }
  209. #endregion
  210. #region Customer Support
  211. /// <summary>
  212. /// 读取自定义的数据类型,只要规定了写入和解析规则
  213. /// </summary>
  214. /// <typeparam name="T">类型名称</typeparam>
  215. /// <param name="address">起始地址</param>
  216. /// <returns></returns>
  217. public OperateResult<T> ReadCustomer<T>(string address) where T : IDataTransfer, new()
  218. {
  219. OperateResult<T> result = new OperateResult<T>();
  220. T Content = new T();
  221. OperateResult<byte[]> read = Read(address, Content.ReadCount);
  222. if (read.IsSuccess)
  223. {
  224. Content.ParseSource(read.Content);
  225. result.Content = Content;
  226. result.IsSuccess = true;
  227. }
  228. else
  229. {
  230. result.ErrorCode = read.ErrorCode;
  231. result.Message = read.Message;
  232. }
  233. return result;
  234. }
  235. /// <summary>
  236. /// 写入自定义的数据类型到PLC去,只要规定了生成字节的方法即可
  237. /// </summary>
  238. /// <typeparam name="T">自定义类型</typeparam>
  239. /// <param name="address">起始地址</param>
  240. /// <param name="data">实例对象</param>
  241. /// <returns></returns>
  242. public OperateResult WriteCustomer<T>(string address, T data) where T : IDataTransfer, new()
  243. {
  244. return Write(address, data.ToSource());
  245. }
  246. #endregion
  247. #region Read Support
  248. /// <summary>
  249. /// 从三菱PLC中读取想要的数据,返回读取结果
  250. /// </summary>
  251. /// <param name="address">读取地址,格式为"M100","D100","W1A0"</param>
  252. /// <param name="length">读取的数据长度,字最大值960,位最大值7168</param>
  253. /// <returns>带成功标志的结果数据对象</returns>
  254. public OperateResult<byte[]> Read(string address, ushort length)
  255. {
  256. var result = new OperateResult<byte[]>();
  257. //获取指令
  258. var command = BuildReadCommand(address, length);
  259. if (!command.IsSuccess)
  260. {
  261. result.CopyErrorFromOther(command);
  262. return result;
  263. }
  264. var read = ReadFromCoreServer(command.Content2);
  265. if (read.IsSuccess)
  266. {
  267. result.ErrorCode = read.Content[1]; //这里的结束代码是一个字节
  268. if (result.ErrorCode == 0)
  269. {
  270. if (command.Content1.DataType == 0x01)
  271. {
  272. result.Content = new byte[(read.Content.Length - 2) * 2];
  273. for (int i = 2; i < read.Content.Length; i++)
  274. {
  275. if ((read.Content[i] & 0x10) == 0x10)
  276. {
  277. result.Content[(i - 2) * 2 + 0] = 0x01;
  278. }
  279. if ((read.Content[i] & 0x01) == 0x01)
  280. {
  281. result.Content[(i - 2) * 2 + 1] = 0x01;
  282. }
  283. }
  284. }
  285. else
  286. {
  287. result.Content = new byte[read.Content.Length - 2];
  288. Array.Copy(read.Content, 2, result.Content, 0, result.Content.Length);
  289. }
  290. result.IsSuccess = true;
  291. }
  292. else
  293. {
  294. result.Message = "读取过程异常发生, 异常代码为:" + read.Content[1].ToString();
  295. //在A兼容1E协议中,结束代码后面紧跟的是异常信息的代码
  296. }
  297. }
  298. else
  299. {
  300. result.ErrorCode = read.ErrorCode;
  301. result.Message = read.Message;
  302. }
  303. return result;
  304. }
  305. /// <summary>
  306. /// 从三菱PLC中批量读取位软元件,返回读取结果
  307. /// </summary>
  308. /// <param name="address">起始地址</param>
  309. /// <param name="length">读取的长度</param>
  310. /// <returns>带成功标志的结果数据对象</returns>
  311. public OperateResult<bool[]> ReadBool(string address, ushort length)
  312. {
  313. var result = new OperateResult<bool[]>();
  314. var analysis = AnalysisAddress(address);
  315. if (!analysis.IsSuccess)
  316. {
  317. result.CopyErrorFromOther(analysis);
  318. return result;
  319. }
  320. else
  321. {
  322. if (analysis.Content1.DataType == 0x00)
  323. {
  324. result.Message = "读取位变量数组只能针对位软元件,如果读取字软元件,请自行转化";
  325. return result;
  326. }
  327. }
  328. var read = Read(address, length);
  329. if (!read.IsSuccess)
  330. {
  331. result.CopyErrorFromOther(read);
  332. return result;
  333. }
  334. result.Content = new bool[read.Content.Length];
  335. for (int i = 0; i < read.Content.Length; i++)
  336. {
  337. result.Content[i] = read.Content[i] == 0x01;
  338. }
  339. result.IsSuccess = true;
  340. return result;
  341. }
  342. /// <summary>
  343. /// 读取三菱PLC中字软元件指定地址的short数据
  344. /// </summary>
  345. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  346. /// <returns>带成功标志的结果数据对象</returns>
  347. public OperateResult<short> ReadInt16(string address)
  348. {
  349. return GetInt16ResultFromBytes(Read(address, 2));
  350. }
  351. /// <summary>
  352. /// 读取三菱PLC中字软元件指定地址的ushort数据
  353. /// </summary>
  354. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  355. /// <returns>带成功标志的结果数据对象</returns>
  356. public OperateResult<ushort> ReadUInt16(string address)
  357. {
  358. return GetUInt16ResultFromBytes(Read(address, 2));
  359. }
  360. /// <summary>
  361. /// 读取三菱PLC中字软元件指定地址的int数据
  362. /// </summary>
  363. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  364. /// <returns>带成功标志的结果数据对象</returns>
  365. public OperateResult<int> ReadInt32(string address)
  366. {
  367. return GetInt32ResultFromBytes(Read(address, 4));
  368. }
  369. /// <summary>
  370. /// 读取三菱PLC中字软元件指定地址的uint数据
  371. /// </summary>
  372. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  373. /// <returns>带成功标志的结果数据对象</returns>
  374. public OperateResult<uint> ReadUInt32(string address)
  375. {
  376. return GetUInt32ResultFromBytes(Read(address, 4));
  377. }
  378. /// <summary>
  379. /// 读取三菱PLC中字软元件指定地址的float数据
  380. /// </summary>
  381. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  382. /// <returns>带成功标志的结果数据对象</returns>
  383. public OperateResult<float> ReadFloat(string address)
  384. {
  385. return GetSingleResultFromBytes(Read(address, 4));
  386. }
  387. /// <summary>
  388. /// 读取三菱PLC中字软元件指定地址的long数据
  389. /// </summary>
  390. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  391. /// <returns>带成功标志的结果数据对象</returns>
  392. public OperateResult<long> ReadInt64(string address)
  393. {
  394. return GetInt64ResultFromBytes(Read(address, 8));
  395. }
  396. /// <summary>
  397. /// 读取三菱PLC中字软元件指定地址的ulong数据
  398. /// </summary>
  399. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  400. /// <returns>带成功标志的结果数据对象</returns>
  401. public OperateResult<ulong> ReadUInt64(string address)
  402. {
  403. return GetUInt64ResultFromBytes(Read(address, 8));
  404. }
  405. /// <summary>
  406. /// 读取三菱PLC中字软元件指定地址的double数据
  407. /// </summary>
  408. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  409. /// <returns>带成功标志的结果数据对象</returns>
  410. public OperateResult<double> ReadDouble(string address)
  411. {
  412. return GetDoubleResultFromBytes(Read(address, 8));
  413. }
  414. /// <summary>
  415. /// 读取三菱PLC中字软元件地址地址的String数据,编码为ASCII
  416. /// </summary>
  417. /// <param name="address">起始地址,格式为"D100","W1A0"</param>
  418. /// <param name="length">字符串长度</param>
  419. /// <returns>带成功标志的结果数据对象</returns>
  420. public OperateResult<string> ReadString(string address, ushort length)
  421. {
  422. return GetStringResultFromBytes(Read(address, length));
  423. }
  424. #endregion
  425. #region Write Base
  426. /// <summary>
  427. /// 向PLC写入数据,数据格式为原始的字节类型
  428. /// </summary>
  429. /// <param name="address">初始地址</param>
  430. /// <param name="value">原始的字节数据</param>
  431. /// <returns>结果</returns>
  432. public OperateResult Write(string address, byte[] value)
  433. {
  434. OperateResult<byte[]> result = new OperateResult<byte[]>();
  435. //获取指令
  436. var analysis = AnalysisAddress(address);
  437. if (!analysis.IsSuccess)
  438. {
  439. result.CopyErrorFromOther(analysis);
  440. return result;
  441. }
  442. OperateResult<MelsecA1EDataType, byte[]> command;
  443. // 预处理指令
  444. if (analysis.Content1.DataType == 0x01)
  445. {
  446. int length = value.Length % 2 == 0 ? value.Length / 2 : value.Length / 2 + 1;
  447. byte[] buffer = new byte[length];
  448. for (int i = 0; i < length; i++)
  449. {
  450. if (value[i * 2 + 0] != 0x00) buffer[i] += 0x10;
  451. if ((i * 2 + 1) < value.Length)
  452. {
  453. if (value[i * 2 + 1] != 0x00) buffer[i] += 0x01;
  454. }
  455. }
  456. // 位写入
  457. command = BuildWriteCommand(address, buffer, value.Length);
  458. }
  459. else
  460. {
  461. // 字写入
  462. command = BuildWriteCommand(address, value);
  463. }
  464. if (!command.IsSuccess)
  465. {
  466. result.CopyErrorFromOther(command);
  467. return result;
  468. }
  469. OperateResult<byte[]> read = ReadFromCoreServer(command.Content2);
  470. if (read.IsSuccess)
  471. {
  472. result.ErrorCode = read.Content[1];
  473. if (result.ErrorCode == 0)
  474. {
  475. result.IsSuccess = true;
  476. }
  477. else
  478. {
  479. result.Message = "写入过程异常发生, 异常代码为:" + read.Content[1].ToString();
  480. //在A兼容1E协议中,结束代码后面紧跟的是异常信息的代码}
  481. }
  482. }
  483. else
  484. {
  485. result.ErrorCode = read.ErrorCode;
  486. result.Message = read.Message;
  487. }
  488. return result;
  489. }
  490. #endregion
  491. #region Write String
  492. /// <summary>
  493. /// 向PLC中字软元件写入字符串,编码格式为ASCII
  494. /// </summary>
  495. /// <param name="address">要写入的数据地址</param>
  496. /// <param name="value">要写入的实际数据</param>
  497. /// <returns>返回读取结果</returns>
  498. public OperateResult Write(string address, string value)
  499. {
  500. byte[] temp = Encoding.ASCII.GetBytes(value);
  501. return Write(address, temp);
  502. }
  503. /// <summary>
  504. /// 向PLC中字软元件写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII
  505. /// </summary>
  506. /// <param name="address">要写入的数据地址</param>
  507. /// <param name="value">要写入的实际数据</param>
  508. /// <param name="length">指定的字符串长度,必须大于0</param>
  509. /// <returns>返回读取结果</returns>
  510. public OperateResult Write(string address, string value, int length)
  511. {
  512. byte[] temp = Encoding.ASCII.GetBytes(value);
  513. temp = BasicFramework.SoftBasic.ArrayExpandToLength(temp, length);
  514. return Write(address, temp);
  515. }
  516. /// <summary>
  517. /// 向PLC中字软元件写入字符串,编码格式为Unicode
  518. /// </summary>
  519. /// <param name="address">要写入的数据地址</param>
  520. /// <param name="value">要写入的实际数据</param>
  521. /// <returns>返回读取结果</returns>
  522. public OperateResult WriteUnicodeString(string address, string value)
  523. {
  524. byte[] temp = Encoding.Unicode.GetBytes(value);
  525. return Write(address, temp);
  526. }
  527. /// <summary>
  528. /// 向PLC中字软元件写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode
  529. /// </summary>
  530. /// <param name="address">要写入的数据地址</param>
  531. /// <param name="value">要写入的实际数据</param>
  532. /// <param name="length">指定的字符串长度,必须大于0</param>
  533. /// <returns>返回读取结果</returns>
  534. public OperateResult WriteUnicodeString(string address, string value, int length)
  535. {
  536. byte[] temp = Encoding.Unicode.GetBytes(value);
  537. temp = BasicFramework.SoftBasic.ArrayExpandToLength(temp, length * 2);
  538. return Write(address, temp);
  539. }
  540. #endregion
  541. #region Write bool[]
  542. /// <summary>
  543. /// 向PLC中位软元件写入bool数组,返回值说明,比如你写入M100,values[0]对应M100
  544. /// </summary>
  545. /// <param name="address">要写入的数据地址</param>
  546. /// <param name="value">要写入的实际数据,长度为8的倍数</param>
  547. /// <returns>返回写入结果</returns>
  548. public OperateResult Write(string address, bool value)
  549. {
  550. return Write(address, new bool[] { value });
  551. }
  552. /// <summary>
  553. /// 向PLC中位软元件写入bool数组,返回值说明,比如你写入M100,values[0]对应M100
  554. /// </summary>
  555. /// <param name="address">要写入的数据地址</param>
  556. /// <param name="values">要写入的实际数据,可以指定任意的长度</param>
  557. /// <returns>返回写入结果</returns>
  558. public OperateResult Write(string address, bool[] values)
  559. {
  560. return Write(address, values.Select(m => m ? (byte)0x01 : (byte)0x00).ToArray());
  561. }
  562. #endregion
  563. #region Write Short
  564. /// <summary>
  565. /// 向PLC中字软元件写入short数组,返回值说明
  566. /// </summary>
  567. /// <param name="address">要写入的数据地址</param>
  568. /// <param name="values">要写入的实际数据</param>
  569. /// <returns>返回写入结果</returns>
  570. public OperateResult Write(string address, short[] values)
  571. {
  572. return Write(address, ByteTransform.TransByte(values));
  573. }
  574. /// <summary>
  575. /// 向PLC中字软元件写入short数据,返回值说明
  576. /// </summary>
  577. /// <param name="address">要写入的数据地址</param>
  578. /// <param name="value">要写入的实际数据</param>
  579. /// <returns>返回写入结果</returns>
  580. public OperateResult Write(string address, short value)
  581. {
  582. return Write(address, new short[] { value });
  583. }
  584. #endregion
  585. #region Write UShort
  586. /// <summary>
  587. /// 向PLC中字软元件写入ushort数组,返回值说明
  588. /// </summary>
  589. /// <param name="address">要写入的数据地址</param>
  590. /// <param name="values">要写入的实际数据</param>
  591. /// <returns>返回写入结果</returns>
  592. public OperateResult Write(string address, ushort[] values)
  593. {
  594. return Write(address, ByteTransform.TransByte(values));
  595. }
  596. /// <summary>
  597. /// 向PLC中字软元件写入ushort数据,返回值说明
  598. /// </summary>
  599. /// <param name="address">要写入的数据地址</param>
  600. /// <param name="value">要写入的实际数据</param>
  601. /// <returns>返回写入结果</returns>
  602. public OperateResult Write(string address, ushort value)
  603. {
  604. return Write(address, new ushort[] { value });
  605. }
  606. #endregion
  607. #region Write Int
  608. /// <summary>
  609. /// 向PLC中字软元件写入int数组,返回值说明
  610. /// </summary>
  611. /// <param name="address">要写入的数据地址</param>
  612. /// <param name="values">要写入的实际数据</param>
  613. /// <returns>返回写入结果</returns>
  614. public OperateResult Write(string address, int[] values)
  615. {
  616. return Write(address, ByteTransform.TransByte(values));
  617. }
  618. /// <summary>
  619. /// 向PLC中字软元件写入int数据,返回值说明
  620. /// </summary>
  621. /// <param name="address">要写入的数据地址</param>
  622. /// <param name="value">要写入的实际数据</param>
  623. /// <returns>返回写入结果</returns>
  624. public OperateResult Write(string address, int value)
  625. {
  626. return Write(address, new int[] { value });
  627. }
  628. #endregion
  629. #region Write UInt
  630. /// <summary>
  631. /// 向PLC中字软元件写入uint数组,返回值说明
  632. /// </summary>
  633. /// <param name="address">要写入的数据地址</param>
  634. /// <param name="values">要写入的实际数据</param>
  635. /// <returns>返回写入结果</returns>
  636. public OperateResult Write(string address, uint[] values)
  637. {
  638. return Write(address, ByteTransform.TransByte(values));
  639. }
  640. /// <summary>
  641. /// 向PLC中字软元件写入uint数据,返回值说明
  642. /// </summary>
  643. /// <param name="address">要写入的数据地址</param>
  644. /// <param name="value">要写入的实际数据</param>
  645. /// <returns>返回写入结果</returns>
  646. public OperateResult Write(string address, uint value)
  647. {
  648. return Write(address, new uint[] { value });
  649. }
  650. #endregion
  651. #region Write Float
  652. /// <summary>
  653. /// 向PLC中字软元件写入float数组,返回值说明
  654. /// </summary>
  655. /// <param name="address">要写入的数据地址</param>
  656. /// <param name="values">要写入的实际数据</param>
  657. /// <returns>返回写入结果</returns>
  658. public OperateResult Write(string address, float[] values)
  659. {
  660. return Write(address, ByteTransform.TransByte(values));
  661. }
  662. /// <summary>
  663. /// 向PLC中字软元件写入float数据,返回值说明
  664. /// </summary>
  665. /// <param name="address">要写入的数据地址</param>
  666. /// <param name="value">要写入的实际数据</param>
  667. /// <returns>返回写入结果</returns>
  668. public OperateResult Write(string address, float value)
  669. {
  670. return Write(address, new float[] { value });
  671. }
  672. #endregion
  673. #region Write Long
  674. /// <summary>
  675. /// 向PLC中字软元件写入long数组,返回值说明
  676. /// </summary>
  677. /// <param name="address">要写入的数据地址</param>
  678. /// <param name="values">要写入的实际数据</param>
  679. /// <returns>返回写入结果</returns>
  680. public OperateResult Write(string address, long[] values)
  681. {
  682. return Write(address, ByteTransform.TransByte(values));
  683. }
  684. /// <summary>
  685. /// 向PLC中字软元件写入long数据,返回值说明
  686. /// </summary>
  687. /// <param name="address">要写入的数据地址</param>
  688. /// <param name="value">要写入的实际数据</param>
  689. /// <returns>返回写入结果</returns>
  690. public OperateResult Write(string address, long value)
  691. {
  692. return Write(address, new long[] { value });
  693. }
  694. #endregion
  695. #region Write ULong
  696. /// <summary>
  697. /// 向PLC中字软元件写入ulong数组,返回值说明
  698. /// </summary>
  699. /// <param name="address">要写入的数据地址</param>
  700. /// <param name="values">要写入的实际数据</param>
  701. /// <returns>返回写入结果</returns>
  702. public OperateResult Write(string address, ulong[] values)
  703. {
  704. return Write(address, ByteTransform.TransByte(values));
  705. }
  706. /// <summary>
  707. /// 向PLC中字软元件写入ulong数据,返回值说明
  708. /// </summary>
  709. /// <param name="address">要写入的数据地址</param>
  710. /// <param name="value">要写入的实际数据</param>
  711. /// <returns>返回写入结果</returns>
  712. public OperateResult Write(string address, ulong value)
  713. {
  714. return Write(address, new ulong[] { value });
  715. }
  716. #endregion
  717. #region Write Double
  718. /// <summary>
  719. /// 向PLC中字软元件写入double数组,返回值说明
  720. /// </summary>
  721. /// <param name="address">要写入的数据地址</param>
  722. /// <param name="values">要写入的实际数据</param>
  723. /// <returns>返回写入结果</returns>
  724. public OperateResult Write(string address, double[] values)
  725. {
  726. return Write(address, ByteTransform.TransByte(values));
  727. }
  728. /// <summary>
  729. /// 向PLC中字软元件写入double数据,返回值说明
  730. /// </summary>
  731. /// <param name="address">要写入的数据地址</param>
  732. /// <param name="value">要写入的实际数据</param>
  733. /// <returns>返回写入结果</returns>
  734. public OperateResult Write(string address, double value)
  735. {
  736. return Write(address, new double[] { value });
  737. }
  738. #endregion
  739. #region Object Override
  740. /// <summary>
  741. /// 获取当前对象的字符串标识形式
  742. /// </summary>
  743. /// <returns>字符串信息</returns>
  744. public override string ToString()
  745. {
  746. return "MelsecA1ENet";
  747. }
  748. #endregion
  749. }
  750. }