ModbusTcpNet.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using HslCommunication.BasicFramework;
  6. using HslCommunication.Core;
  7. using HslCommunication.Core.IMessage;
  8. using HslCommunication.Core.Net;
  9. namespace HslCommunication.ModBus
  10. {
  11. /// <summary>
  12. /// Modbus-Tcp协议的客户端通讯类,方便的和服务器进行数据交互
  13. /// </summary>
  14. public class ModbusTcpNet : NetworkDoubleBase<ModbusTcpMessage, ReverseWordTransform>, IReadWriteNet
  15. {
  16. #region Constructor
  17. /// <summary>
  18. /// 实例化一个MOdbus-Tcp协议的客户端对象
  19. /// </summary>
  20. public ModbusTcpNet( )
  21. {
  22. softIncrementCount = new SoftIncrementCount( ushort.MaxValue );
  23. }
  24. /// <summary>
  25. /// 指定服务器地址,端口号,客户端自己的站号来初始化
  26. /// </summary>
  27. /// <param name="ipAddress">服务器的Ip地址</param>
  28. /// <param name="port">服务器的端口号</param>
  29. /// <param name="station">客户端自身的站号</param>
  30. public ModbusTcpNet( string ipAddress, int port = 502, byte station = 0x01 )
  31. {
  32. softIncrementCount = new SoftIncrementCount( ushort.MaxValue );
  33. IpAddress = ipAddress;
  34. Port = port;
  35. this.station = station;
  36. }
  37. #endregion
  38. #region Private Member
  39. private byte station = ModbusInfo.ReadCoil; // 本客户端的站号
  40. private SoftIncrementCount softIncrementCount; // 自增消息的对象
  41. #endregion
  42. #region Address Analysis
  43. /// <summary>
  44. /// 解析数据地址,解析出地址类型,起始地址
  45. /// </summary>
  46. /// <param name="address">数据地址</param>
  47. /// <returns>解析出地址类型,起始地址,DB块的地址</returns>
  48. private OperateResult<int> AnalysisAddress( string address )
  49. {
  50. try
  51. {
  52. return OperateResult.CreateSuccessResult( Convert.ToInt32( address ) );
  53. }
  54. catch (Exception ex)
  55. {
  56. return new OperateResult<int>( )
  57. {
  58. Message = ex.Message
  59. };
  60. }
  61. }
  62. #endregion
  63. #region Build Command
  64. /// <summary>
  65. /// 读取数据的基础指令,需要指定指令码,地址,长度
  66. /// </summary>
  67. /// <param name="code"></param>
  68. /// <param name="address"></param>
  69. /// <param name="count"></param>
  70. /// <returns></returns>
  71. private OperateResult<byte[]> BuildReadCommandBase( byte code, string address, ushort count )
  72. {
  73. OperateResult<int> analysis = AnalysisAddress( address );
  74. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  75. ushort messageId = (ushort)softIncrementCount.GetCurrentValue( );
  76. byte[] buffer = new byte[12];
  77. buffer[0] = (byte)(messageId / 256);
  78. buffer[1] = (byte)(messageId % 256);
  79. buffer[2] = 0x00;
  80. buffer[3] = 0x00;
  81. buffer[4] = 0x00;
  82. buffer[5] = 0x06;
  83. buffer[6] = station;
  84. buffer[7] = code;
  85. buffer[8] = (byte)(analysis.Content / 256);
  86. buffer[9] = (byte)(analysis.Content % 256);
  87. buffer[10] = (byte)(count / 256);
  88. buffer[11] = (byte)(count % 256);
  89. return OperateResult.CreateSuccessResult( buffer );
  90. }
  91. /// <summary>
  92. /// 生成一个读取线圈的指令头
  93. /// </summary>
  94. /// <param name="address">地址</param>
  95. /// <param name="count">长度</param>
  96. /// <returns>携带有命令字节</returns>
  97. private OperateResult<byte[]> BuildReadCoilCommand( string address, ushort count )
  98. {
  99. return BuildReadCommandBase( ModbusInfo.ReadCoil, address, count );
  100. }
  101. /// <summary>
  102. /// 生成一个读取离散信息的指令头
  103. /// </summary>
  104. /// <param name="address">地址</param>
  105. /// <param name="count">长度</param>
  106. /// <returns>携带有命令字节</returns>
  107. private OperateResult<byte[]> BuildReadDiscreteCommand( string address, ushort count )
  108. {
  109. return BuildReadCommandBase( ModbusInfo.ReadDiscrete, address, count );
  110. }
  111. /// <summary>
  112. /// 生成一个读取寄存器的指令头
  113. /// </summary>
  114. /// <param name="address"></param>
  115. /// <param name="count"></param>
  116. /// <returns>携带有命令字节</returns>
  117. private OperateResult<byte[]> BuildReadRegisterCommand( string address, ushort count )
  118. {
  119. return BuildReadCommandBase( ModbusInfo.ReadRegister, address, count );
  120. }
  121. private OperateResult<byte[]> BuildWriteOneCoilCommand( string address, bool value )
  122. {
  123. OperateResult<int> analysis = AnalysisAddress( address );
  124. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  125. ushort messageId = (ushort)softIncrementCount.GetCurrentValue( );
  126. byte[] buffer = new byte[12];
  127. buffer[0] = (byte)(messageId / 256);
  128. buffer[1] = (byte)(messageId % 256);
  129. buffer[2] = 0x00;
  130. buffer[3] = 0x00;
  131. buffer[4] = 0x00;
  132. buffer[5] = 0x06;
  133. buffer[6] = station;
  134. buffer[7] = ModbusInfo.WriteOneCoil;
  135. buffer[8] = (byte)(analysis.Content / 256);
  136. buffer[9] = (byte)(analysis.Content % 256);
  137. buffer[10] = (byte)(value ? 0xFF : 0x00);
  138. buffer[11] = 0x00;
  139. return OperateResult.CreateSuccessResult( buffer );
  140. }
  141. private OperateResult<byte[]> BuildWriteOneRegisterCommand( string address, byte[] data )
  142. {
  143. OperateResult<int> analysis = AnalysisAddress( address );
  144. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  145. ushort messageId = (ushort)softIncrementCount.GetCurrentValue( );
  146. byte[] buffer = new byte[12];
  147. buffer[0] = (byte)(messageId / 256);
  148. buffer[1] = (byte)(messageId % 256);
  149. buffer[2] = 0x00;
  150. buffer[3] = 0x00;
  151. buffer[4] = 0x00;
  152. buffer[5] = 0x06;
  153. buffer[6] = station;
  154. buffer[7] = ModbusInfo.WriteOneRegister;
  155. buffer[8] = (byte)(analysis.Content / 256);
  156. buffer[9] = (byte)(analysis.Content % 256);
  157. buffer[10] = data[1];
  158. buffer[11] = data[0];
  159. return OperateResult.CreateSuccessResult( buffer );
  160. }
  161. private OperateResult<byte[]> BuildWriteCoilCommand( string address, bool[] values )
  162. {
  163. byte[] data = SoftBasic.BoolArrayToByte( values );
  164. OperateResult<int> analysis = AnalysisAddress( address );
  165. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  166. ushort messageId = (ushort)softIncrementCount.GetCurrentValue( );
  167. byte[] buffer = new byte[13 + data.Length];
  168. buffer[0] = (byte)(messageId / 256);
  169. buffer[1] = (byte)(messageId % 256);
  170. buffer[2] = 0x00;
  171. buffer[3] = 0x00;
  172. buffer[4] = (byte)((buffer.Length - 6) / 256);
  173. buffer[5] = (byte)((buffer.Length - 6) % 256);
  174. buffer[6] = station;
  175. buffer[7] = ModbusInfo.WriteCoil;
  176. buffer[8] = (byte)(analysis.Content / 256);
  177. buffer[9] = (byte)(analysis.Content % 256);
  178. buffer[10] = (byte)(values.Length / 256);
  179. buffer[11] = (byte)(values.Length % 256);
  180. buffer[12] = (byte)(data.Length);
  181. data.CopyTo( buffer, 13 );
  182. return OperateResult.CreateSuccessResult( buffer );
  183. }
  184. private OperateResult<byte[]> BuildWriteRegisterCommand( string address, byte[] data )
  185. {
  186. OperateResult<int> analysis = AnalysisAddress( address );
  187. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  188. ushort messageId = (ushort)softIncrementCount.GetCurrentValue( );
  189. byte[] buffer = new byte[13 + data.Length];
  190. buffer[0] = (byte)(messageId / 256);
  191. buffer[1] = (byte)(messageId % 256);
  192. buffer[2] = 0x00;
  193. buffer[3] = 0x00;
  194. buffer[4] = (byte)((buffer.Length - 6) / 256);
  195. buffer[5] = (byte)((buffer.Length - 6) % 256);
  196. buffer[6] = station;
  197. buffer[7] = ModbusInfo.WriteRegister;
  198. buffer[8] = (byte)(analysis.Content / 256);
  199. buffer[9] = (byte)(analysis.Content % 256);
  200. buffer[10] = (byte)(data.Length / 2 / 256);
  201. buffer[11] = (byte)(data.Length / 2 % 256);
  202. buffer[12] = (byte)(data.Length);
  203. data.CopyTo( buffer, 13 );
  204. return OperateResult.CreateSuccessResult( buffer );
  205. }
  206. #endregion
  207. #region Core Interative
  208. /// <summary>
  209. /// 通过错误码来获取到对应的文本消息
  210. /// </summary>
  211. /// <param name="code"></param>
  212. /// <returns></returns>
  213. private string GetDescriptionByErrorCode( byte code )
  214. {
  215. switch (code)
  216. {
  217. case ModbusInfo.FunctionCodeNotSupport: return StringResources.ModbusTcpFunctionCodeNotSupport;
  218. case ModbusInfo.FunctionCodeOverBound: return StringResources.ModbusTcpFunctionCodeOverBound;
  219. case ModbusInfo.FunctionCodeQuantityOver: return StringResources.ModbusTcpFunctionCodeQuantityOver;
  220. case ModbusInfo.FunctionCodeReadWriteException: return StringResources.ModbusTcpFunctionCodeReadWriteException;
  221. default: return StringResources.UnknownError;
  222. }
  223. }
  224. private OperateResult<byte[]> CheckModbusTcpResponse( byte[] send )
  225. {
  226. OperateResult<byte[]> result = ReadFromCoreServer( send );
  227. if (result.IsSuccess)
  228. {
  229. if ((send[7] + 0x80) == result.Content[7])
  230. {
  231. // 发生了错误
  232. result.IsSuccess = false;
  233. result.Message = GetDescriptionByErrorCode( result.Content[8] );
  234. result.ErrorCode = result.Content[8];
  235. }
  236. }
  237. return result;
  238. }
  239. #endregion
  240. #region Customer Support
  241. /// <summary>
  242. /// 读取自定义的数据类型,只针对寄存器而言,需要规定了写入和解析规则
  243. /// </summary>
  244. /// <typeparam name="T">类型名称</typeparam>
  245. /// <param name="address">起始地址</param>
  246. /// <returns>带是否成功的特定类型的对象</returns>
  247. public OperateResult<T> ReadCustomer<T>( string address ) where T : IDataTransfer, new()
  248. {
  249. OperateResult<T> result = new OperateResult<T>( );
  250. T Content = new T( );
  251. OperateResult<byte[]> read = Read( address, Content.ReadCount );
  252. if (read.IsSuccess)
  253. {
  254. Content.ParseSource( read.Content );
  255. result.Content = Content;
  256. result.IsSuccess = true;
  257. }
  258. else
  259. {
  260. result.ErrorCode = read.ErrorCode;
  261. result.Message = read.Message;
  262. }
  263. return result;
  264. }
  265. /// <summary>
  266. /// 写入自定义的数据类型到寄存器去,只要规定了生成字节的方法即可
  267. /// </summary>
  268. /// <typeparam name="T">自定义类型</typeparam>
  269. /// <param name="address">起始地址</param>
  270. /// <param name="data">实例对象</param>
  271. /// <returns>是否成功</returns>
  272. public OperateResult WriteCustomer<T>( string address, T data ) where T : IDataTransfer, new()
  273. {
  274. return Write( address, data.ToSource( ) );
  275. }
  276. #endregion
  277. #region Read Support
  278. /// <summary>
  279. /// 读取服务器的数据,需要指定不同的功能码
  280. /// </summary>
  281. /// <param name="code">指令</param>
  282. /// <param name="address">地址</param>
  283. /// <param name="length">长度</param>
  284. /// <returns></returns>
  285. private OperateResult<byte[]> ReadModBusBase( byte code, string address, ushort length )
  286. {
  287. OperateResult<byte[]> command = BuildReadCommandBase( code, address, length );
  288. if (!command.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( command );
  289. OperateResult<byte[]> resultBytes = CheckModbusTcpResponse( command.Content );
  290. if (resultBytes.IsSuccess)
  291. {
  292. // 二次数据处理
  293. if (resultBytes.Content?.Length >= 9)
  294. {
  295. byte[] buffer = new byte[resultBytes.Content.Length - 9];
  296. Array.Copy( resultBytes.Content, 9, buffer, 0, buffer.Length );
  297. resultBytes.Content = buffer;
  298. }
  299. }
  300. return resultBytes;
  301. }
  302. /// <summary>
  303. /// 读取线圈,需要指定起始地址
  304. /// </summary>
  305. /// <param name="address">起始地址,格式为"1234"</param>
  306. /// <returns>带有成功标志的bool对象</returns>
  307. public OperateResult<bool> ReadCoil( string address )
  308. {
  309. var read = ReadModBusBase( ModbusInfo.ReadCoil, address, 1 );
  310. if (!read.IsSuccess) return OperateResult.CreateFailedResult<bool>( read );
  311. return GetBoolResultFromBytes( read );
  312. }
  313. /// <summary>
  314. /// 批量的读取线圈,需要指定起始地址,读取长度
  315. /// </summary>
  316. /// <param name="address">起始地址,格式为"1234"</param>
  317. /// <param name="length">读取长度</param>
  318. /// <returns>带有成功标志的bool数组对象</returns>
  319. public OperateResult<bool[]> ReadCoil( string address, ushort length )
  320. {
  321. var read = ReadModBusBase( ModbusInfo.ReadCoil, address, length );
  322. if (!read.IsSuccess) return OperateResult.CreateFailedResult<bool[]>( read );
  323. return OperateResult.CreateSuccessResult( SoftBasic.ByteToBoolArray( read.Content, length ) );
  324. }
  325. /// <summary>
  326. /// 批量的离散变量,需要指定起始地址,读取长度
  327. /// </summary>
  328. /// <param name="address">起始地址,格式为"1234"</param>
  329. /// <param name="length">读取长度</param>
  330. /// <returns>带有成功标志的bool数组对象</returns>
  331. public OperateResult<bool[]> ReadDiscrete( string address, ushort length )
  332. {
  333. var read = ReadModBusBase( ModbusInfo.ReadDiscrete, address, length );
  334. if (!read.IsSuccess) return OperateResult.CreateFailedResult<bool[]>( read );
  335. return OperateResult.CreateSuccessResult( SoftBasic.ByteToBoolArray( read.Content, length ) );
  336. }
  337. /// <summary>
  338. /// 从Modbus服务器批量读取寄存器的信息,需要指定起始地址,读取长度
  339. /// </summary>
  340. /// <param name="address">起始地址,格式为"1234"</param>
  341. /// <param name="length">读取的数量</param>
  342. /// <returns>带有成功标志的字节信息</returns>
  343. public OperateResult<byte[]> Read( string address, ushort length )
  344. {
  345. OperateResult<int> analysis = AnalysisAddress( address );
  346. if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis );
  347. List<byte> lists = new List<byte>( );
  348. ushort alreadyFinished = 0;
  349. while (alreadyFinished < length)
  350. {
  351. ushort lengthTmp = (ushort)Math.Min( (length - alreadyFinished), 120 );
  352. OperateResult<byte[]> read = ReadModBusBase( ModbusInfo.ReadRegister, (analysis.Content + alreadyFinished).ToString( ), lengthTmp );
  353. if (!read.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( read );
  354. lists.AddRange( read.Content );
  355. alreadyFinished += lengthTmp;
  356. }
  357. return OperateResult.CreateSuccessResult( lists.ToArray( ) );
  358. }
  359. /// <summary>
  360. /// 读取指定地址的short数据
  361. /// </summary>
  362. /// <param name="address">起始地址,格式为"1234"</param>
  363. /// <returns>带有成功标志的short数据</returns>
  364. public OperateResult<short> ReadInt16( string address )
  365. {
  366. return GetInt16ResultFromBytes( Read( address, 1 ) );
  367. }
  368. /// <summary>
  369. /// 读取指定地址的ushort数据
  370. /// </summary>
  371. /// <param name="address">起始地址,格式为"1234"</param>
  372. /// <returns>带有成功标志的ushort数据</returns>
  373. public OperateResult<ushort> ReadUInt16( string address )
  374. {
  375. return GetUInt16ResultFromBytes( Read( address, 1 ) );
  376. }
  377. /// <summary>
  378. /// 读取指定地址的int数据
  379. /// </summary>
  380. /// <param name="address">起始地址,格式为"1234"</param>
  381. /// <returns>带有成功标志的int数据</returns>
  382. public OperateResult<int> ReadInt32( string address )
  383. {
  384. return GetInt32ResultFromBytes( Read( address, 2 ) );
  385. }
  386. /// <summary>
  387. /// 读取指定地址的uint数据
  388. /// </summary>
  389. /// <param name="address">起始地址,格式为"1234"</param>
  390. /// <returns>带有成功标志的uint数据</returns>
  391. public OperateResult<uint> ReadUInt32( string address )
  392. {
  393. return GetUInt32ResultFromBytes( Read( address, 2 ) );
  394. }
  395. /// <summary>
  396. /// 读取指定地址的float数据
  397. /// </summary>
  398. /// <param name="address">起始地址,格式为"1234"</param>
  399. /// <returns>带有成功标志的float数据</returns>
  400. public OperateResult<float> ReadFloat( string address )
  401. {
  402. return GetSingleResultFromBytes( Read( address, 2 ) );
  403. }
  404. /// <summary>
  405. /// 读取指定地址的long数据
  406. /// </summary>
  407. /// <param name="address">起始地址,格式为"1234"</param>
  408. /// <returns>带有成功标志的long数据</returns>
  409. public OperateResult<long> ReadInt64( string address )
  410. {
  411. return GetInt64ResultFromBytes( Read( address, 4 ) );
  412. }
  413. /// <summary>
  414. /// 读取指定地址的ulong数据
  415. /// </summary>
  416. /// <param name="address">起始地址,格式为"1234"</param>
  417. /// <returns>带有成功标志的ulong数据</returns>
  418. public OperateResult<ulong> ReadUInt64( string address )
  419. {
  420. return GetUInt64ResultFromBytes( Read( address, 4 ) );
  421. }
  422. /// <summary>
  423. /// 读取指定地址的double数据
  424. /// </summary>
  425. /// <param name="address">起始地址,格式为"1234"</param>
  426. /// <returns>带有成功标志的double数据</returns>
  427. public OperateResult<double> ReadDouble( string address )
  428. {
  429. return GetDoubleResultFromBytes( Read( address, 4 ) );
  430. }
  431. /// <summary>
  432. /// 读取地址地址的String数据,字符串编码为ASCII
  433. /// </summary>
  434. /// <param name="address">起始地址,格式为"1234"</param>
  435. /// <param name="length">字符串长度</param>
  436. /// <returns>带有成功标志的string数据</returns>
  437. public OperateResult<string> ReadString( string address, ushort length )
  438. {
  439. return GetStringResultFromBytes( Read( address, length ) );
  440. }
  441. #endregion
  442. #region Write One Register
  443. /// <summary>
  444. /// 写一个寄存器数据
  445. /// </summary>
  446. /// <param name="address">起始地址</param>
  447. /// <param name="high">高位</param>
  448. /// <param name="low">地位</param>
  449. /// <returns>返回写入结果</returns>
  450. public OperateResult WriteOneRegister( string address, byte high, byte low )
  451. {
  452. OperateResult<byte[]> command = BuildWriteOneRegisterCommand( address, new byte[] { high, low } );
  453. if (!command.IsSuccess)
  454. {
  455. return command;
  456. }
  457. return CheckModbusTcpResponse( command.Content );
  458. }
  459. /// <summary>
  460. /// 写一个寄存器数据
  461. /// </summary>
  462. /// <param name="address">起始地址</param>
  463. /// <param name="value">写入值</param>
  464. /// <returns>返回写入结果</returns>
  465. public OperateResult WriteOneRegister( string address, short value )
  466. {
  467. byte[] buffer = BitConverter.GetBytes( value );
  468. return WriteOneRegister( address, buffer[1], buffer[0] );
  469. }
  470. /// <summary>
  471. /// 写一个寄存器数据
  472. /// </summary>
  473. /// <param name="address">起始地址</param>
  474. /// <param name="value">写入值</param>
  475. /// <returns>返回写入结果</returns>
  476. public OperateResult WriteOneRegister( string address, ushort value )
  477. {
  478. byte[] buffer = BitConverter.GetBytes( value );
  479. return WriteOneRegister( address, buffer[1], buffer[0] );
  480. }
  481. #endregion
  482. #region Write Base
  483. /// <summary>
  484. /// 将数据写入到Modbus的寄存器上去,需要指定起始地址和数据内容
  485. /// </summary>
  486. /// <param name="address">起始地址,格式为"1234"</param>
  487. /// <param name="value">写入的数据,长度根据data的长度来指示</param>
  488. /// <returns>返回写入结果</returns>
  489. public OperateResult Write( string address, byte[] value )
  490. {
  491. OperateResult<byte[]> command = BuildWriteRegisterCommand( address, value );
  492. if (!command.IsSuccess)
  493. {
  494. return command;
  495. }
  496. return CheckModbusTcpResponse( command.Content );
  497. }
  498. #endregion
  499. #region Write Coil
  500. /// <summary>
  501. /// 写一个线圈信息,指定是否通断
  502. /// </summary>
  503. /// <param name="address">起始地址</param>
  504. /// <param name="value">写入值</param>
  505. /// <returns>返回写入结果</returns>
  506. public OperateResult WriteCoil( string address, bool value )
  507. {
  508. OperateResult<byte[]> command = BuildWriteOneCoilCommand( address, value );
  509. if (!command.IsSuccess)
  510. {
  511. return command;
  512. }
  513. return CheckModbusTcpResponse( command.Content );
  514. }
  515. /// <summary>
  516. ///
  517. /// </summary>
  518. /// <param name="address">起始地址</param>
  519. /// <param name="values">写入值</param>
  520. /// <returns>返回写入结果</returns>
  521. public OperateResult WriteCoil( string address, bool[] values )
  522. {
  523. OperateResult<byte[]> command = BuildWriteCoilCommand( address, values );
  524. if (!command.IsSuccess)
  525. {
  526. return command;
  527. }
  528. return CheckModbusTcpResponse( command.Content );
  529. }
  530. #endregion
  531. #region Write String
  532. /// <summary>
  533. /// 向寄存器中写入字符串,编码格式为ASCII
  534. /// </summary>
  535. /// <param name="address">要写入的数据地址</param>
  536. /// <param name="value">要写入的实际数据</param>
  537. /// <returns>返回写入结果</returns>
  538. public OperateResult Write( string address, string value )
  539. {
  540. byte[] temp = Encoding.ASCII.GetBytes( value );
  541. return Write( address, temp );
  542. }
  543. /// <summary>
  544. /// 向寄存器中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII
  545. /// </summary>
  546. /// <param name="address">要写入的数据地址</param>
  547. /// <param name="value">要写入的实际数据</param>
  548. /// <param name="length">指定的字符串长度,必须大于0</param>
  549. /// <returns>返回写入结果</returns>
  550. public OperateResult Write( string address, string value, int length )
  551. {
  552. byte[] temp = Encoding.ASCII.GetBytes( value );
  553. temp = BasicFramework.SoftBasic.ArrayExpandToLength( temp, length );
  554. return Write( address, temp );
  555. }
  556. /// <summary>
  557. /// 向寄存器中写入字符串,编码格式为Unicode
  558. /// </summary>
  559. /// <param name="address">要写入的数据地址</param>
  560. /// <param name="value">要写入的实际数据</param>
  561. /// <returns>返回写入结果</returns>
  562. public OperateResult WriteUnicodeString( string address, string value )
  563. {
  564. byte[] temp = Encoding.Unicode.GetBytes( value );
  565. return Write( address, temp );
  566. }
  567. /// <summary>
  568. /// 向寄存器中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode
  569. /// </summary>
  570. /// <param name="address">要写入的数据地址</param>
  571. /// <param name="value">要写入的实际数据</param>
  572. /// <param name="length">指定的字符串长度,必须大于0</param>
  573. /// <returns>返回写入结果</returns>
  574. public OperateResult WriteUnicodeString( string address, string value, int length )
  575. {
  576. byte[] temp = Encoding.Unicode.GetBytes( value );
  577. temp = SoftBasic.ArrayExpandToLength( temp, length * 2 );
  578. return Write( address, temp );
  579. }
  580. #endregion
  581. #region Write bool[]
  582. /// <summary>
  583. /// 向寄存器中写入bool数组,返回值说明,比如你写入M100,那么data[0]对应M100.0
  584. /// </summary>
  585. /// <param name="address">要写入的数据地址</param>
  586. /// <param name="values">要写入的实际数据,长度为8的倍数</param>
  587. /// <returns>返回写入结果</returns>
  588. public OperateResult Write( string address, bool[] values )
  589. {
  590. return Write( address, BasicFramework.SoftBasic.BoolArrayToByte( values ) );
  591. }
  592. #endregion
  593. #region Write Short
  594. /// <summary>
  595. /// 向寄存器中写入short数组,返回值说明
  596. /// </summary>
  597. /// <param name="address">要写入的数据地址</param>
  598. /// <param name="values">要写入的实际数据</param>
  599. /// <returns>返回写入结果</returns>
  600. public OperateResult Write( string address, short[] values )
  601. {
  602. return Write( address, ByteTransform.TransByte( values ) );
  603. }
  604. /// <summary>
  605. /// 向寄存器中写入short数据,返回值说明
  606. /// </summary>
  607. /// <param name="address">要写入的数据地址</param>
  608. /// <param name="value">要写入的实际数据</param>
  609. /// <returns>返回写入结果</returns>
  610. public OperateResult Write( string address, short value )
  611. {
  612. return Write( address, new short[] { value } );
  613. }
  614. #endregion
  615. #region Write UShort
  616. /// <summary>
  617. /// 向寄存器中写入ushort数组,返回值说明
  618. /// </summary>
  619. /// <param name="address">要写入的数据地址</param>
  620. /// <param name="values">要写入的实际数据</param>
  621. /// <returns>返回写入结果</returns>
  622. public OperateResult Write( string address, ushort[] values )
  623. {
  624. return Write( address, ByteTransform.TransByte( values ) );
  625. }
  626. /// <summary>
  627. /// 向寄存器中写入ushort数据,返回值说明
  628. /// </summary>
  629. /// <param name="address">要写入的数据地址</param>
  630. /// <param name="value">要写入的实际数据</param>
  631. /// <returns>返回写入结果</returns>
  632. public OperateResult Write( string address, ushort value )
  633. {
  634. return Write( address, new ushort[] { value } );
  635. }
  636. #endregion
  637. #region Write Int
  638. /// <summary>
  639. /// 向寄存器中写入int数组,返回值说明
  640. /// </summary>
  641. /// <param name="address">要写入的数据地址</param>
  642. /// <param name="values">要写入的实际数据</param>
  643. /// <returns>返回写入结果</returns>
  644. public OperateResult Write( string address, int[] values )
  645. {
  646. return Write( address, ByteTransform.TransByte( values ) );
  647. }
  648. /// <summary>
  649. /// 向寄存器中写入int数据,返回值说明
  650. /// </summary>
  651. /// <param name="address">要写入的数据地址</param>
  652. /// <param name="value">要写入的实际数据</param>
  653. /// <returns>返回写入结果</returns>
  654. public OperateResult Write( string address, int value )
  655. {
  656. return Write( address, new int[] { value } );
  657. }
  658. #endregion
  659. #region Write UInt
  660. /// <summary>
  661. /// 向寄存器中写入uint数组,返回值说明
  662. /// </summary>
  663. /// <param name="address">要写入的数据地址</param>
  664. /// <param name="values">要写入的实际数据</param>
  665. /// <returns>返回写入结果</returns>
  666. public OperateResult Write( string address, uint[] values )
  667. {
  668. return Write( address, ByteTransform.TransByte( values ) );
  669. }
  670. /// <summary>
  671. /// 向寄存器中写入uint数据,返回值说明
  672. /// </summary>
  673. /// <param name="address">要写入的数据地址</param>
  674. /// <param name="value">要写入的实际数据</param>
  675. /// <returns>返回写入结果</returns>
  676. public OperateResult Write( string address, uint value )
  677. {
  678. return Write( address, new uint[] { value } );
  679. }
  680. #endregion
  681. #region Write Float
  682. /// <summary>
  683. /// 向寄存器中写入float数组,返回值说明
  684. /// </summary>
  685. /// <param name="address">要写入的数据地址</param>
  686. /// <param name="values">要写入的实际数据</param>
  687. /// <returns>返回写入结果</returns>
  688. public OperateResult Write( string address, float[] values )
  689. {
  690. return Write( address, ByteTransform.TransByte( values ) );
  691. }
  692. /// <summary>
  693. /// 向寄存器中写入float数据,返回值说明
  694. /// </summary>
  695. /// <param name="address">要写入的数据地址</param>
  696. /// <param name="value">要写入的实际数据</param>
  697. /// <returns>返回写入结果</returns>
  698. public OperateResult Write( string address, float value )
  699. {
  700. return Write( address, new float[] { value } );
  701. }
  702. #endregion
  703. #region Write Long
  704. /// <summary>
  705. /// 向寄存器中写入long数组,返回值说明
  706. /// </summary>
  707. /// <param name="address">要写入的数据地址</param>
  708. /// <param name="values">要写入的实际数据</param>
  709. /// <returns>返回写入结果</returns>
  710. public OperateResult Write( string address, long[] values )
  711. {
  712. return Write( address, ByteTransform.TransByte( values ) );
  713. }
  714. /// <summary>
  715. /// 向寄存器中写入long数据,返回值说明
  716. /// </summary>
  717. /// <param name="address">要写入的数据地址</param>
  718. /// <param name="value">要写入的实际数据</param>
  719. /// <returns>返回写入结果</returns>
  720. public OperateResult Write( string address, long value )
  721. {
  722. return Write( address, new long[] { value } );
  723. }
  724. #endregion
  725. #region Write ULong
  726. /// <summary>
  727. /// 向寄存器中写入ulong数组,返回值说明
  728. /// </summary>
  729. /// <param name="address">要写入的数据地址</param>
  730. /// <param name="values">要写入的实际数据</param>
  731. /// <returns>返回写入结果</returns>
  732. public OperateResult Write( string address, ulong[] values )
  733. {
  734. return Write( address, ByteTransform.TransByte( values ) );
  735. }
  736. /// <summary>
  737. /// 向寄存器中写入ulong数据,返回值说明
  738. /// </summary>
  739. /// <param name="address">要写入的数据地址</param>
  740. /// <param name="value">要写入的实际数据</param>
  741. /// <returns>返回写入结果</returns>
  742. public OperateResult Write( string address, ulong value )
  743. {
  744. return Write( address, new ulong[] { value } );
  745. }
  746. #endregion
  747. #region Write Double
  748. /// <summary>
  749. /// 向寄存器中写入double数组,返回值说明
  750. /// </summary>
  751. /// <param name="address">要写入的数据地址</param>
  752. /// <param name="values">要写入的实际数据</param>
  753. /// <returns>返回写入结果</returns>
  754. public OperateResult Write( string address, double[] values )
  755. {
  756. return Write( address, ByteTransform.TransByte( values ) );
  757. }
  758. /// <summary>
  759. /// 向寄存器中写入double数据,返回值说明
  760. /// </summary>
  761. /// <param name="address">要写入的数据地址</param>
  762. /// <param name="value">要写入的实际数据</param>
  763. /// <returns>返回写入结果</returns>
  764. public OperateResult Write( string address, double value )
  765. {
  766. return Write( address, new double[] { value } );
  767. }
  768. #endregion
  769. #region Object Override
  770. /// <summary>
  771. /// 获取当前对象的字符串标识形式
  772. /// </summary>
  773. /// <returns>字符串信息</returns>
  774. public override string ToString( )
  775. {
  776. return "ModbusTcpNet";
  777. }
  778. #endregion
  779. }
  780. }