SiemensS7Net.cs 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using HslCommunication.Core;
  7. using HslCommunication.Core.IMessage;
  8. using HslCommunication.Core.Net;
  9. /********************************************************************************
  10. *
  11. * 说明:西门子通讯类,使用S7消息解析规格,和反字节转换规格来实现的
  12. *
  13. * 继承自统一的自定义方法
  14. *
  15. *
  16. *********************************************************************************/
  17. namespace HslCommunication.Profinet.Siemens
  18. {
  19. /// <summary>
  20. /// 一个西门子的客户端类,使用S7协议来进行数据交互
  21. /// </summary>
  22. public class SiemensS7Net : NetworkDoubleBase<S7Message, ReverseBytesTransform>, IReadWriteNet
  23. {
  24. #region Constructor
  25. /// <summary>
  26. /// 实例化一个西门子的S7协议的通讯对象
  27. /// </summary>
  28. /// <param name="siemens">指定西门子的型号</param>
  29. public SiemensS7Net(SiemensPLCS siemens)
  30. {
  31. Initialization( siemens, string.Empty );
  32. }
  33. /// <summary>
  34. /// 实例化一个西门子的S7协议的通讯对象并指定Ip地址
  35. /// </summary>
  36. /// <param name="siemens">指定西门子的型号</param>
  37. /// <param name="ipAddress">Ip地址</param>
  38. public SiemensS7Net(SiemensPLCS siemens,string ipAddress)
  39. {
  40. Initialization( siemens, ipAddress );
  41. }
  42. /// <summary>
  43. /// 初始化方法
  44. /// </summary>
  45. /// <param name="siemens"></param>
  46. /// <param name="ipAddress"></param>
  47. private void Initialization(SiemensPLCS siemens, string ipAddress)
  48. {
  49. IpAddress = ipAddress;
  50. Port = 102;
  51. CurrentPlc = siemens;
  52. switch (siemens)
  53. {
  54. case SiemensPLCS.S1200: plcHead1[21] = 0; break;
  55. case SiemensPLCS.S300: plcHead1[21] = 2; break;
  56. case SiemensPLCS.S1500: plcHead1[21] = 0; break;
  57. case SiemensPLCS.S200Smart:
  58. {
  59. plcHead1 = plcHead1_200smart;
  60. plcHead2 = plcHead2_200smart;
  61. break;
  62. }
  63. default: plcHead1[18] = 0; break;
  64. }
  65. }
  66. #endregion
  67. #region NetworkDoubleBase Override
  68. /// <summary>
  69. /// 在客户端连接上服务器后,所做的一些初始化操作
  70. /// </summary>
  71. /// <param name="socket"></param>
  72. /// <returns></returns>
  73. protected override OperateResult InitilizationOnConnect(Socket socket)
  74. {
  75. // 第一层通信的初始化
  76. OperateResult<byte[], byte[]> read_first = ReadFromCoreServerBase( socket, plcHead1 );
  77. if (!read_first.IsSuccess)
  78. {
  79. return read_first;
  80. }
  81. // 第二层通信的初始化
  82. OperateResult<byte[], byte[]> read_second = ReadFromCoreServerBase( socket, plcHead2 );
  83. if (!read_second.IsSuccess)
  84. {
  85. return read_second;
  86. }
  87. // 返回成功的信号
  88. return OperateResult.CreateSuccessResult( );
  89. }
  90. #endregion
  91. #region Address Analysis
  92. /// <summary>
  93. /// 计算特殊的地址信息
  94. /// </summary>
  95. /// <param name="address">字符串信息</param>
  96. /// <returns>实际值</returns>
  97. private int CalculateAddressStarted(string address)
  98. {
  99. if (address.IndexOf( '.' ) < 0)
  100. {
  101. return Convert.ToInt32( address ) * 8;
  102. }
  103. else
  104. {
  105. string[] temp = address.Split( '.' );
  106. return Convert.ToInt32( temp[0] ) * 8 + Convert.ToInt32( temp[1] );
  107. }
  108. }
  109. /// <summary>
  110. /// 解析数据地址,解析出地址类型,起始地址,DB块的地址
  111. /// </summary>
  112. /// <param name="address">数据地址</param>
  113. /// <returns>解析出地址类型,起始地址,DB块的地址</returns>
  114. private OperateResult<byte, int, ushort> AnalysisAddress(string address)
  115. {
  116. var result = new OperateResult<byte, int, ushort>( );
  117. try
  118. {
  119. result.Content3 = 0;
  120. if (address[0] == 'I')
  121. {
  122. result.Content1 = 0x81;
  123. result.Content2 = CalculateAddressStarted( address.Substring( 1 ) );
  124. }
  125. else if (address[0] == 'Q')
  126. {
  127. result.Content1 = 0x82;
  128. result.Content2 = CalculateAddressStarted( address.Substring( 1 ) );
  129. }
  130. else if (address[0] == 'M')
  131. {
  132. result.Content1 = 0x83;
  133. result.Content2 = CalculateAddressStarted( address.Substring( 1 ) );
  134. }
  135. else if (address[0] == 'D' || address.Substring( 0, 2 ) == "DB")
  136. {
  137. result.Content1 = 0x84;
  138. string[] adds = address.Split( '.' );
  139. if (address[1] == 'B')
  140. {
  141. result.Content3 = Convert.ToUInt16( adds[0].Substring( 2 ) );
  142. }
  143. else
  144. {
  145. result.Content3 = Convert.ToUInt16( adds[0].Substring( 1 ) );
  146. }
  147. result.Content2 = CalculateAddressStarted( address.Substring( address.IndexOf( '.' ) + 1 ) );
  148. }
  149. else if (address[0] == 'T')
  150. {
  151. result.Content1 = 0x1D;
  152. result.Content2 = CalculateAddressStarted( address.Substring( 1 ) );
  153. }
  154. else if (address[0] == 'C')
  155. {
  156. result.Content1 = 0x1C;
  157. result.Content2 = CalculateAddressStarted( address.Substring( 1 ) );
  158. }
  159. else
  160. {
  161. result.Message = "不支持的数据类型";
  162. result.Content1 = 0;
  163. result.Content2 = 0;
  164. result.Content3 = 0;
  165. return result;
  166. }
  167. }
  168. catch (Exception ex)
  169. {
  170. result.Message = ex.Message;
  171. return result;
  172. }
  173. result.IsSuccess = true;
  174. return result;
  175. }
  176. #endregion
  177. #region Build Command
  178. /// <summary>
  179. /// 生成一个读取字数据指令头的通用方法
  180. /// </summary>
  181. /// <param name="address">解析后的地址</param>
  182. /// <param name="length">每个地址的读取长度</param>
  183. /// <returns>携带有命令字节</returns>
  184. private OperateResult<byte[]> BuildReadCommand( OperateResult<byte, int, ushort>[] address, ushort[] length)
  185. {
  186. if (address == null) throw new NullReferenceException( "address" );
  187. if (length == null) throw new NullReferenceException( "count" );
  188. if (address.Length != length.Length) throw new Exception( "两个参数的个数不统一" );
  189. if (length.Length > 255) throw new Exception( "读取的数组数量不允许大于255" );
  190. var result = new OperateResult<byte[]>( );
  191. int readCount = length.Length;
  192. byte[] _PLCCommand = new byte[19 + readCount * 12];
  193. // ======================================================================================
  194. // Header
  195. // 报文头
  196. _PLCCommand[0] = 0x03;
  197. _PLCCommand[1] = 0x00;
  198. // 长度
  199. _PLCCommand[2] = (byte)(_PLCCommand.Length / 256);
  200. _PLCCommand[3] = (byte)(_PLCCommand.Length % 256);
  201. // 固定
  202. _PLCCommand[4] = 0x02;
  203. _PLCCommand[5] = 0xF0;
  204. _PLCCommand[6] = 0x80;
  205. // 协议标识
  206. _PLCCommand[7] = 0x32;
  207. // 命令:发
  208. _PLCCommand[8] = 0x01;
  209. // redundancy identification (reserved): 0x0000;
  210. _PLCCommand[9] = 0x00;
  211. _PLCCommand[10] = 0x00;
  212. // protocol data unit reference; it’s increased by request event;
  213. _PLCCommand[11] = 0x00;
  214. _PLCCommand[12] = 0x01;
  215. // 参数命令数据总长度
  216. _PLCCommand[13] = (byte)((_PLCCommand.Length - 17) / 256);
  217. _PLCCommand[14] = (byte)((_PLCCommand.Length - 17) % 256);
  218. // 读取内部数据时为00,读取CPU型号为Data数据长度
  219. _PLCCommand[15] = 0x00;
  220. _PLCCommand[16] = 0x00;
  221. // ======================================================================================
  222. // Parameter
  223. // 读写指令,04读,05写
  224. _PLCCommand[17] = 0x04;
  225. // 读取数据块个数
  226. _PLCCommand[18] = (byte)readCount;
  227. for (int ii = 0; ii < readCount; ii++)
  228. {
  229. //===========================================================================================
  230. // 指定有效值类型
  231. _PLCCommand[19 + ii * 12] = 0x12;
  232. // 接下来本次地址访问长度
  233. _PLCCommand[20 + ii * 12] = 0x0A;
  234. // 语法标记,ANY
  235. _PLCCommand[21 + ii * 12] = 0x10;
  236. // 按字为单位
  237. _PLCCommand[22 + ii * 12] = 0x02;
  238. // 访问数据的个数
  239. _PLCCommand[23 + ii * 12] = (byte)(length[ii] / 256);
  240. _PLCCommand[24 + ii * 12] = (byte)(length[ii] % 256);
  241. // DB块编号,如果访问的是DB块的话
  242. _PLCCommand[25 + ii * 12] = (byte)(address[ii].Content3 / 256);
  243. _PLCCommand[26 + ii * 12] = (byte)(address[ii].Content3 % 256);
  244. // 访问数据类型
  245. _PLCCommand[27 + ii * 12] = address[ii].Content1;
  246. // 偏移位置
  247. _PLCCommand[28 + ii * 12] = (byte)(address[ii].Content2 / 256 / 256 % 256);
  248. _PLCCommand[29 + ii * 12] = (byte)(address[ii].Content2 / 256 % 256);
  249. _PLCCommand[30 + ii * 12] = (byte)(address[ii].Content2 % 256);
  250. }
  251. result.Content = _PLCCommand;
  252. result.IsSuccess = true;
  253. return result;
  254. }
  255. /// <summary>
  256. /// 生成一个位读取数据指令头的通用方法
  257. /// </summary>
  258. /// <param name="address"></param>
  259. /// <returns></returns>
  260. private OperateResult<byte[]> BuildBitReadCommand(string address)
  261. {
  262. var result = new OperateResult<byte[]>( );
  263. byte[] _PLCCommand = new byte[31];
  264. // 报文头
  265. _PLCCommand[0] = 0x03;
  266. _PLCCommand[1] = 0x00;
  267. // 长度
  268. _PLCCommand[2] = (byte)(_PLCCommand.Length / 256);
  269. _PLCCommand[3] = (byte)(_PLCCommand.Length % 256);
  270. // 固定
  271. _PLCCommand[4] = 0x02;
  272. _PLCCommand[5] = 0xF0;
  273. _PLCCommand[6] = 0x80;
  274. _PLCCommand[7] = 0x32;
  275. // 命令:发
  276. _PLCCommand[8] = 0x01;
  277. // 标识序列号
  278. _PLCCommand[9] = 0x00;
  279. _PLCCommand[10] = 0x00;
  280. _PLCCommand[11] = 0x00;
  281. _PLCCommand[12] = 0x01;
  282. // 命令数据总长度
  283. _PLCCommand[13] = (byte)((_PLCCommand.Length - 17) / 256);
  284. _PLCCommand[14] = (byte)((_PLCCommand.Length - 17) % 256);
  285. _PLCCommand[15] = 0x00;
  286. _PLCCommand[16] = 0x00;
  287. // 命令起始符
  288. _PLCCommand[17] = 0x04;
  289. // 读取数据块个数
  290. _PLCCommand[18] = 0x01;
  291. // 填充数据
  292. OperateResult<byte, int, ushort> analysis = AnalysisAddress( address );
  293. if (!analysis.IsSuccess)
  294. {
  295. result.CopyErrorFromOther( analysis );
  296. return result;
  297. }
  298. //===========================================================================================
  299. // 读取地址的前缀
  300. _PLCCommand[19] = 0x12;
  301. _PLCCommand[20] = 0x0A;
  302. _PLCCommand[21] = 0x10;
  303. // 读取的数据时位
  304. _PLCCommand[22] = 0x01;
  305. // 访问数据的个数
  306. _PLCCommand[23] = 0x00;
  307. _PLCCommand[24] = 0x01;
  308. // DB块编号,如果访问的是DB块的话
  309. _PLCCommand[25] = (byte)(analysis.Content3 / 256);
  310. _PLCCommand[26] = (byte)(analysis.Content3 % 256);
  311. // 访问数据类型
  312. _PLCCommand[27] = analysis.Content1;
  313. // 偏移位置
  314. _PLCCommand[28] = (byte)(analysis.Content2 / 256 / 256 % 256);
  315. _PLCCommand[29] = (byte)(analysis.Content2 / 256 % 256);
  316. _PLCCommand[30] = (byte)(analysis.Content2 % 256);
  317. result.Content = _PLCCommand;
  318. result.IsSuccess = true;
  319. return result;
  320. }
  321. /// <summary>
  322. /// 生成一个写入字节数据的指令
  323. /// </summary>
  324. /// <param name="address"></param>
  325. /// <param name="data"></param>
  326. /// <returns></returns>
  327. private OperateResult<byte[]> BuildWriteByteCommand(string address, byte[] data)
  328. {
  329. if (data == null) data = new byte[0];
  330. var result = new OperateResult<byte[]>( );
  331. OperateResult<byte, int, ushort> analysis = AnalysisAddress( address );
  332. if (!analysis.IsSuccess)
  333. {
  334. result.CopyErrorFromOther( analysis );
  335. return result;
  336. }
  337. byte[] _PLCCommand = new byte[35 + data.Length];
  338. _PLCCommand[0] = 0x03;
  339. _PLCCommand[1] = 0x00;
  340. // 长度
  341. _PLCCommand[2] = (byte)((35 + data.Length) / 256);
  342. _PLCCommand[3] = (byte)((35 + data.Length) % 256);
  343. // 固定
  344. _PLCCommand[4] = 0x02;
  345. _PLCCommand[5] = 0xF0;
  346. _PLCCommand[6] = 0x80;
  347. _PLCCommand[7] = 0x32;
  348. // 命令 发
  349. _PLCCommand[8] = 0x01;
  350. // 标识序列号
  351. _PLCCommand[9] = 0x00;
  352. _PLCCommand[10] = 0x00;
  353. _PLCCommand[11] = 0x00;
  354. _PLCCommand[12] = 0x01;
  355. // 固定
  356. _PLCCommand[13] = 0x00;
  357. _PLCCommand[14] = 0x0E;
  358. // 写入长度+4
  359. _PLCCommand[15] = (byte)((4 + data.Length) / 256);
  360. _PLCCommand[16] = (byte)((4 + data.Length) % 256);
  361. // 读写指令
  362. _PLCCommand[17] = 0x05;
  363. // 写入数据块个数
  364. _PLCCommand[18] = 0x01;
  365. // 固定,返回数据长度
  366. _PLCCommand[19] = 0x12;
  367. _PLCCommand[20] = 0x0A;
  368. _PLCCommand[21] = 0x10;
  369. // 写入方式,1是按位,2是按字
  370. _PLCCommand[22] = 0x02;
  371. // 写入数据的个数
  372. _PLCCommand[23] = (byte)(data.Length / 256);
  373. _PLCCommand[24] = (byte)(data.Length % 256);
  374. // DB块编号,如果访问的是DB块的话
  375. _PLCCommand[25] = (byte)(analysis.Content3 / 256);
  376. _PLCCommand[26] = (byte)(analysis.Content3 % 256);
  377. // 写入数据的类型
  378. _PLCCommand[27] = analysis.Content1;
  379. // 偏移位置
  380. _PLCCommand[28] = (byte)(analysis.Content2 / 256 / 256 % 256); ;
  381. _PLCCommand[29] = (byte)(analysis.Content2 / 256 % 256);
  382. _PLCCommand[30] = (byte)(analysis.Content2 % 256);
  383. // 按字写入
  384. _PLCCommand[31] = 0x00;
  385. _PLCCommand[32] = 0x04;
  386. // 按位计算的长度
  387. _PLCCommand[33] = (byte)(data.Length * 8 / 256);
  388. _PLCCommand[34] = (byte)(data.Length * 8 % 256);
  389. data.CopyTo( _PLCCommand, 35 );
  390. result.Content = _PLCCommand;
  391. result.IsSuccess = true;
  392. return result;
  393. }
  394. /// <summary>
  395. /// 生成一个写入位数据的指令
  396. /// </summary>
  397. /// <param name="address"></param>
  398. /// <param name="data"></param>
  399. /// <returns></returns>
  400. private OperateResult<byte[]> BuildWriteBitCommand(string address, bool data)
  401. {
  402. var result = new OperateResult<byte[]>( );
  403. OperateResult<byte, int, ushort> analysis = AnalysisAddress( address );
  404. if (!analysis.IsSuccess)
  405. {
  406. result.CopyErrorFromOther( analysis );
  407. return result;
  408. }
  409. byte[] buffer = new byte[1];
  410. buffer[0] = data ? (byte)0x01 : (byte)0x00;
  411. byte[] _PLCCommand = new byte[35 + buffer.Length];
  412. _PLCCommand[0] = 0x03;
  413. _PLCCommand[1] = 0x00;
  414. // 长度
  415. _PLCCommand[2] = (byte)((35 + buffer.Length) / 256);
  416. _PLCCommand[3] = (byte)((35 + buffer.Length) % 256);
  417. // 固定
  418. _PLCCommand[4] = 0x02;
  419. _PLCCommand[5] = 0xF0;
  420. _PLCCommand[6] = 0x80;
  421. _PLCCommand[7] = 0x32;
  422. // 命令 发
  423. _PLCCommand[8] = 0x01;
  424. // 标识序列号
  425. _PLCCommand[9] = 0x00;
  426. _PLCCommand[10] = 0x00;
  427. _PLCCommand[11] = 0x00;
  428. _PLCCommand[12] = 0x01;
  429. // 固定
  430. _PLCCommand[13] = 0x00;
  431. _PLCCommand[14] = 0x0E;
  432. // 写入长度+4
  433. _PLCCommand[15] = (byte)((4 + buffer.Length) / 256);
  434. _PLCCommand[16] = (byte)((4 + buffer.Length) % 256);
  435. // 命令起始符
  436. _PLCCommand[17] = 0x05;
  437. // 写入数据块个数
  438. _PLCCommand[18] = 0x01;
  439. _PLCCommand[19] = 0x12;
  440. _PLCCommand[20] = 0x0A;
  441. _PLCCommand[21] = 0x10;
  442. // 写入方式,1是按位,2是按字
  443. _PLCCommand[22] = 0x01;
  444. // 写入数据的个数
  445. _PLCCommand[23] = (byte)(buffer.Length / 256);
  446. _PLCCommand[24] = (byte)(buffer.Length % 256);
  447. // DB块编号,如果访问的是DB块的话
  448. _PLCCommand[25] = (byte)(analysis.Content3 / 256);
  449. _PLCCommand[26] = (byte)(analysis.Content3 % 256);
  450. // 写入数据的类型
  451. _PLCCommand[27] = analysis.Content1;
  452. // 偏移位置
  453. _PLCCommand[28] = (byte)(analysis.Content2 / 256 / 256);
  454. _PLCCommand[29] = (byte)(analysis.Content2 / 256);
  455. _PLCCommand[30] = (byte)(analysis.Content2 % 256);
  456. // 按位写入
  457. _PLCCommand[31] = 0x00;
  458. _PLCCommand[32] = 0x03;
  459. // 按位计算的长度
  460. _PLCCommand[33] = (byte)(buffer.Length / 256);
  461. _PLCCommand[34] = (byte)(buffer.Length % 256);
  462. buffer.CopyTo( _PLCCommand, 35 );
  463. result.Content = _PLCCommand;
  464. result.IsSuccess = true;
  465. return result;
  466. }
  467. #endregion
  468. #region Read OrderNumber
  469. /// <summary>
  470. /// 从PLC读取订货号信息
  471. /// </summary>
  472. /// <returns></returns>
  473. public OperateResult<string> ReadOrderNumber()
  474. {
  475. OperateResult<string> result = new OperateResult<string>( );
  476. OperateResult<byte[]> read = ReadFromCoreServer( plcOrderNumber );
  477. if (read.IsSuccess)
  478. {
  479. if (read.Content.Length > 100)
  480. {
  481. result.IsSuccess = true;
  482. result.Content = Encoding.ASCII.GetString( read.Content, 71, 20 );
  483. }
  484. }
  485. if (!result.IsSuccess)
  486. {
  487. result.CopyErrorFromOther( read );
  488. }
  489. return result;
  490. }
  491. #endregion
  492. #region Customer Support
  493. /// <summary>
  494. /// 读取自定义的数据类型,只要规定了写入和解析规则
  495. /// </summary>
  496. /// <typeparam name="T">类型名称</typeparam>
  497. /// <param name="address">起始地址</param>
  498. /// <returns></returns>
  499. public OperateResult<T> ReadCustomer<T>(string address) where T : IDataTransfer, new()
  500. {
  501. OperateResult<T> result = new OperateResult<T>( );
  502. T Content = new T( );
  503. OperateResult<byte[]> read = Read( address, Content.ReadCount );
  504. if (read.IsSuccess)
  505. {
  506. Content.ParseSource( read.Content );
  507. result.Content = Content;
  508. result.IsSuccess = true;
  509. }
  510. else
  511. {
  512. result.ErrorCode = read.ErrorCode;
  513. result.Message = read.Message;
  514. }
  515. return result;
  516. }
  517. /// <summary>
  518. /// 写入自定义的数据类型到PLC去,只要规定了生成字节的方法即可
  519. /// </summary>
  520. /// <typeparam name="T">自定义类型</typeparam>
  521. /// <param name="address">起始地址</param>
  522. /// <param name="data">实例对象</param>
  523. /// <returns></returns>
  524. public OperateResult WriteCustomer<T>(string address, T data) where T : IDataTransfer, new()
  525. {
  526. return Write( address, data.ToSource( ) );
  527. }
  528. #endregion
  529. #region Read Support
  530. /// <summary>
  531. /// 从PLC读取数据,地址格式为I100,Q100,DB20.100,M100,T100,C100以字节为单位
  532. /// </summary>
  533. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  534. /// <param name="length">读取的数量,以字节为单位</param>
  535. /// <returns></returns>
  536. public OperateResult<byte[]> Read(string address, ushort length)
  537. {
  538. OperateResult<byte, int, ushort> addressResult = AnalysisAddress( address );
  539. if (!addressResult.IsSuccess)
  540. {
  541. return new OperateResult<byte[]>( )
  542. {
  543. Message = addressResult.Message
  544. };
  545. }
  546. List<byte[]> bytesContent = new List<byte[]>( );
  547. ushort alreadyFinished = 0;
  548. while (alreadyFinished < length)
  549. {
  550. ushort readLength = (ushort)Math.Min( length - alreadyFinished, 200 );
  551. OperateResult<byte[]> read = Read( new OperateResult<byte, int, ushort>[] { addressResult }, new ushort[] { readLength } );
  552. if(read.IsSuccess)
  553. {
  554. bytesContent.Add( read.Content );
  555. }
  556. else
  557. {
  558. return read;
  559. }
  560. alreadyFinished += readLength;
  561. addressResult.Content2 += readLength * 8;
  562. }
  563. byte[] buffer = new byte[bytesContent.Sum( m => m.Length )];
  564. int current = 0;
  565. for (int i = 0; i < bytesContent.Count; i++)
  566. {
  567. bytesContent[i].CopyTo( buffer, current );
  568. current += bytesContent[i].Length;
  569. }
  570. return OperateResult.CreateSuccessResult( buffer );
  571. }
  572. /// <summary>
  573. /// 从PLC读取数据,地址格式为I100,Q100,DB20.100,M100,以位为单位
  574. /// </summary>
  575. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  576. /// <returns></returns>
  577. private OperateResult<byte[]> ReadBitFromPLC(string address)
  578. {
  579. OperateResult<byte[]> result = new OperateResult<byte[]>( );
  580. OperateResult<byte[]> command = BuildBitReadCommand( address );
  581. if (!command.IsSuccess)
  582. {
  583. result.CopyErrorFromOther( command );
  584. return result;
  585. }
  586. OperateResult<byte[]> read = ReadFromCoreServer( command.Content );
  587. if (read.IsSuccess)
  588. {
  589. int receiveCount = 1;
  590. if (read.Content.Length >= 21 && read.Content[20] == 1)
  591. {
  592. // 分析结果
  593. byte[] buffer = new byte[receiveCount];
  594. if (22 < read.Content.Length)
  595. {
  596. if (read.Content[21] == 0xFF &&
  597. read.Content[22] == 0x03)
  598. {
  599. // 有数据
  600. buffer[0] = read.Content[25];
  601. }
  602. }
  603. result.Content = buffer;
  604. result.IsSuccess = true;
  605. }
  606. else
  607. {
  608. result.ErrorCode = read.ErrorCode;
  609. result.Message = "数据块长度校验失败";
  610. }
  611. }
  612. else
  613. {
  614. result.ErrorCode = read.ErrorCode;
  615. result.Message = read.Message;
  616. }
  617. return result;
  618. }
  619. /// <summary>
  620. /// 一次性从PLC获取所有的数据,按照先后顺序返回一个统一的Buffer,需要按照顺序处理,两个数组长度必须一致
  621. /// </summary>
  622. /// <param name="address">起始地址数组</param>
  623. /// <param name="length">数据长度数组</param>
  624. /// <returns></returns>
  625. /// <exception cref="NullReferenceException"></exception>
  626. public OperateResult<byte[]> Read(string[] address, ushort[] length)
  627. {
  628. OperateResult<byte[]> result = new OperateResult<byte[]>( );
  629. OperateResult<byte, int, ushort>[] addressResult = new OperateResult<byte, int, ushort>[address.Length];
  630. for (int i = 0; i < address.Length; i++)
  631. {
  632. OperateResult<byte, int, ushort> tmp = AnalysisAddress( address[i] );
  633. if(!tmp.IsSuccess)
  634. {
  635. result.CopyErrorFromOther( tmp );
  636. return result;
  637. }
  638. addressResult[i] = tmp;
  639. }
  640. return Read( addressResult, length );
  641. }
  642. private OperateResult<byte[]> Read( OperateResult<byte, int, ushort>[] address, ushort[] length )
  643. {
  644. OperateResult<byte[]> result = new OperateResult<byte[]>( );
  645. OperateResult<byte[]> command = BuildReadCommand( address, length );
  646. if (!command.IsSuccess)
  647. {
  648. result.CopyErrorFromOther( command );
  649. return result;
  650. }
  651. OperateResult<byte[]> read = ReadFromCoreServer( command.Content );
  652. if (read.IsSuccess)
  653. {
  654. int receiveCount = 0;
  655. for (int i = 0; i < length.Length; i++)
  656. {
  657. receiveCount += length[i];
  658. }
  659. if (read.Content.Length >= 21 && read.Content[20] == length.Length)
  660. {
  661. // 分析结果
  662. byte[] buffer = new byte[receiveCount];
  663. int kk = 0;
  664. int ll = 0;
  665. for (int ii = 21; ii < read.Content.Length; ii++)
  666. {
  667. if ((ii + 1) < read.Content.Length)
  668. {
  669. if (read.Content[ii] == 0xFF &&
  670. read.Content[ii + 1] == 0x04)
  671. {
  672. // 有数据
  673. Array.Copy( read.Content, ii + 4, buffer, ll, length[kk] );
  674. ii += length[kk] + 3;
  675. ll += length[kk];
  676. kk++;
  677. }
  678. }
  679. }
  680. result.Content = buffer;
  681. result.IsSuccess = true;
  682. }
  683. else
  684. {
  685. result.ErrorCode = read.ErrorCode;
  686. result.Message = "数据块长度校验失败";
  687. }
  688. }
  689. else
  690. {
  691. result.ErrorCode = read.ErrorCode;
  692. result.Message = read.Message;
  693. }
  694. return result;
  695. }
  696. /// <summary>
  697. /// 读取指定地址的bool数据
  698. /// </summary>
  699. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  700. /// <returns></returns>
  701. public OperateResult<bool> ReadBool(string address)
  702. {
  703. return GetBoolResultFromBytes( ReadBitFromPLC( address ) );
  704. }
  705. /// <summary>
  706. /// 读取指定地址的byte数据
  707. /// </summary>
  708. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  709. /// <returns></returns>
  710. public OperateResult<byte> ReadByte(string address)
  711. {
  712. return GetByteResultFromBytes( Read( address, 1 ) );
  713. }
  714. /// <summary>
  715. /// 读取指定地址的short数据
  716. /// </summary>
  717. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  718. /// <returns></returns>
  719. public OperateResult<short> ReadInt16(string address)
  720. {
  721. return GetInt16ResultFromBytes( Read( address, 2 ) );
  722. }
  723. /// <summary>
  724. /// 读取指定地址的ushort数据
  725. /// </summary>
  726. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  727. /// <returns></returns>
  728. public OperateResult<ushort> ReadUInt16(string address)
  729. {
  730. return GetUInt16ResultFromBytes( Read( address, 2 ) );
  731. }
  732. /// <summary>
  733. /// 读取指定地址的int数据
  734. /// </summary>
  735. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  736. /// <returns></returns>
  737. public OperateResult<int> ReadInt32(string address)
  738. {
  739. return GetInt32ResultFromBytes( Read( address, 4 ) );
  740. }
  741. /// <summary>
  742. /// 读取指定地址的uint数据
  743. /// </summary>
  744. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  745. /// <returns></returns>
  746. public OperateResult<uint> ReadUInt32(string address)
  747. {
  748. return GetUInt32ResultFromBytes( Read( address, 4 ) );
  749. }
  750. /// <summary>
  751. /// 读取指定地址的float数据
  752. /// </summary>
  753. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  754. /// <returns></returns>
  755. public OperateResult<float> ReadFloat(string address)
  756. {
  757. return GetSingleResultFromBytes( Read( address, 4 ) );
  758. }
  759. /// <summary>
  760. /// 读取指定地址的long数据
  761. /// </summary>
  762. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  763. /// <returns></returns>
  764. public OperateResult<long> ReadInt64(string address)
  765. {
  766. return GetInt64ResultFromBytes( Read( address, 8 ) );
  767. }
  768. /// <summary>
  769. /// 读取指定地址的ulong数据
  770. /// </summary>
  771. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  772. /// <returns></returns>
  773. public OperateResult<ulong> ReadUInt64(string address)
  774. {
  775. return GetUInt64ResultFromBytes( Read( address, 8 ) );
  776. }
  777. /// <summary>
  778. /// 读取指定地址的double数据
  779. /// </summary>
  780. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  781. /// <returns></returns>
  782. public OperateResult<double> ReadDouble(string address)
  783. {
  784. return GetDoubleResultFromBytes( Read( address, 8 ) );
  785. }
  786. /// <summary>
  787. /// 读取地址地址的String数据
  788. /// </summary>
  789. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  790. /// <param name="length">字符串长度</param>
  791. /// <returns></returns>
  792. public OperateResult<string> ReadString(string address, ushort length)
  793. {
  794. return GetStringResultFromBytes( Read( address, length ) );
  795. }
  796. #endregion
  797. #region Write Base
  798. /// <summary>
  799. /// 将数据写入到PLC数据,地址格式为I100,Q100,DB20.100,M100,以字节为单位
  800. /// </summary>
  801. /// <param name="address">起始地址,格式为I100,M100,Q100,DB20.100</param>
  802. /// <param name="value">写入的数据,长度根据data的长度来指示</param>
  803. /// <returns></returns>
  804. public OperateResult Write(string address, byte[] value)
  805. {
  806. OperateResult result = new OperateResult( );
  807. OperateResult<byte[]> command = BuildWriteByteCommand( address, value );
  808. if (!command.IsSuccess)
  809. {
  810. result.CopyErrorFromOther( command );
  811. return result;
  812. }
  813. OperateResult<byte[]> write = ReadFromCoreServer( command.Content );
  814. if (write.IsSuccess)
  815. {
  816. if (write.Content[write.Content.Length - 1] != 0xFF)
  817. {
  818. // 写入异常
  819. result.Message = "写入数据异常,代号为:" + write.Content[write.Content.Length - 1].ToString( );
  820. }
  821. else
  822. {
  823. result.IsSuccess = true; // 写入成功
  824. }
  825. }
  826. else
  827. {
  828. result.ErrorCode = write.ErrorCode;
  829. result.Message = write.Message;
  830. }
  831. return result;
  832. }
  833. /// <summary>
  834. /// 写入PLC的一个位,例如"M100.6","I100.7","Q100.0","DB20.100.0",如果只写了"M100"默认为"M100.0
  835. /// </summary>
  836. /// <param name="address"></param>
  837. /// <param name="value"></param>
  838. /// <returns></returns>
  839. public OperateResult Write(string address, bool value)
  840. {
  841. OperateResult result = new OperateResult( );
  842. // 生成指令
  843. OperateResult<byte[]> command = BuildWriteBitCommand( address, value );
  844. if (!command.IsSuccess)
  845. {
  846. result.CopyErrorFromOther( command );
  847. return result;
  848. }
  849. OperateResult<byte[]> write = ReadFromCoreServer( command.Content );
  850. if (write.IsSuccess)
  851. {
  852. if (write.Content[write.Content.Length - 1] != 0xFF)
  853. {
  854. // 写入异常
  855. result.Message = "写入数据异常,代号为:" + write.Content[write.Content.Length - 1].ToString( );
  856. }
  857. else
  858. {
  859. result.IsSuccess = true; // 写入成功
  860. }
  861. }
  862. else
  863. {
  864. result.ErrorCode = write.ErrorCode;
  865. result.Message = write.Message;
  866. }
  867. return result;
  868. }
  869. #endregion
  870. #region Write String
  871. /// <summary>
  872. /// 向PLC中写入字符串,编码格式为ASCII
  873. /// </summary>
  874. /// <param name="address">要写入的数据地址</param>
  875. /// <param name="value">要写入的实际数据</param>
  876. /// <returns>返回读取结果</returns>
  877. public OperateResult Write(string address, string value)
  878. {
  879. byte[] temp = Encoding.ASCII.GetBytes( value );
  880. return Write( address, temp );
  881. }
  882. /// <summary>
  883. /// 向PLC中写入指定长度的字符串,超出截断,不够补0,编码格式为ASCII
  884. /// </summary>
  885. /// <param name="address">要写入的数据地址</param>
  886. /// <param name="value">要写入的实际数据</param>
  887. /// <param name="length">指定的字符串长度,必须大于0</param>
  888. /// <returns>返回读取结果</returns>
  889. public OperateResult Write(string address, string value, int length)
  890. {
  891. byte[] temp = Encoding.ASCII.GetBytes( value );
  892. temp = BasicFramework.SoftBasic.ArrayExpandToLength( temp, length );
  893. return Write( address, temp );
  894. }
  895. /// <summary>
  896. /// 向PLC中写入字符串,编码格式为Unicode
  897. /// </summary>
  898. /// <param name="address">要写入的数据地址</param>
  899. /// <param name="value">要写入的实际数据</param>
  900. /// <returns>返回读取结果</returns>
  901. public OperateResult WriteUnicodeString(string address, string value)
  902. {
  903. byte[] temp = Encoding.Unicode.GetBytes( value );
  904. return Write( address, temp );
  905. }
  906. /// <summary>
  907. /// 向PLC中写入指定长度的字符串,超出截断,不够补0,编码格式为Unicode
  908. /// </summary>
  909. /// <param name="address">要写入的数据地址</param>
  910. /// <param name="value">要写入的实际数据</param>
  911. /// <param name="length">指定的字符串长度,必须大于0</param>
  912. /// <returns>返回读取结果</returns>
  913. public OperateResult WriteUnicodeString(string address, string value, int length)
  914. {
  915. byte[] temp = Encoding.Unicode.GetBytes( value );
  916. temp = BasicFramework.SoftBasic.ArrayExpandToLength( temp, length * 2 );
  917. return Write( address, temp );
  918. }
  919. #endregion
  920. #region Write bool[]
  921. /// <summary>
  922. /// 向PLC中写入bool数组,返回值说明,比如你写入M100,那么data[0]对应M100.0
  923. /// </summary>
  924. /// <param name="address">要写入的数据地址</param>
  925. /// <param name="values">要写入的实际数据,长度为8的倍数</param>
  926. /// <returns>返回写入结果</returns>
  927. public OperateResult Write(string address, bool[] values)
  928. {
  929. return Write( address, BasicFramework.SoftBasic.BoolArrayToByte( values ) );
  930. }
  931. #endregion
  932. #region Write Byte
  933. /// <summary>
  934. /// 向PLC中写入byte数据,返回值说明
  935. /// </summary>
  936. /// <param name="address">要写入的数据地址</param>
  937. /// <param name="value">要写入的实际数据</param>
  938. /// <returns></returns>
  939. public OperateResult Write(string address, byte value)
  940. {
  941. return Write( address, new byte[] { value } );
  942. }
  943. #endregion
  944. #region Write Short
  945. /// <summary>
  946. /// 向PLC中写入short数组,返回值说明
  947. /// </summary>
  948. /// <param name="address">要写入的数据地址</param>
  949. /// <param name="values">要写入的实际数据</param>
  950. /// <returns>返回写入结果</returns>
  951. public OperateResult Write(string address, short[] values)
  952. {
  953. return Write( address, ByteTransform.TransByte( values ) );
  954. }
  955. /// <summary>
  956. /// 向PLC中写入short数据,返回值说明
  957. /// </summary>
  958. /// <param name="address">要写入的数据地址</param>
  959. /// <param name="value">要写入的实际数据</param>
  960. /// <returns>返回写入结果</returns>
  961. public OperateResult Write(string address, short value)
  962. {
  963. return Write( address, new short[] { value } );
  964. }
  965. #endregion
  966. #region Write UShort
  967. /// <summary>
  968. /// 向PLC中写入ushort数组,返回值说明
  969. /// </summary>
  970. /// <param name="address">要写入的数据地址</param>
  971. /// <param name="values">要写入的实际数据</param>
  972. /// <returns>返回写入结果</returns>
  973. public OperateResult Write(string address, ushort[] values)
  974. {
  975. return Write( address, ByteTransform.TransByte( values ) );
  976. }
  977. /// <summary>
  978. /// 向PLC中写入ushort数据,返回值说明
  979. /// </summary>
  980. /// <param name="address">要写入的数据地址</param>
  981. /// <param name="value">要写入的实际数据</param>
  982. /// <returns>返回写入结果</returns>
  983. public OperateResult Write(string address, ushort value)
  984. {
  985. return Write( address, new ushort[] { value } );
  986. }
  987. #endregion
  988. #region Write Int
  989. /// <summary>
  990. /// 向PLC中写入int数组,返回值说明
  991. /// </summary>
  992. /// <param name="address">要写入的数据地址</param>
  993. /// <param name="values">要写入的实际数据</param>
  994. /// <returns>返回写入结果</returns>
  995. public OperateResult Write(string address, int[] values)
  996. {
  997. return Write( address, ByteTransform.TransByte( values ) );
  998. }
  999. /// <summary>
  1000. /// 向PLC中写入int数据,返回值说明
  1001. /// </summary>
  1002. /// <param name="address">要写入的数据地址</param>
  1003. /// <param name="value">要写入的实际数据</param>
  1004. /// <returns>返回写入结果</returns>
  1005. public OperateResult Write(string address, int value)
  1006. {
  1007. return Write( address, new int[] { value } );
  1008. }
  1009. #endregion
  1010. #region Write UInt
  1011. /// <summary>
  1012. /// 向PLC中写入uint数组,返回值说明
  1013. /// </summary>
  1014. /// <param name="address">要写入的数据地址</param>
  1015. /// <param name="values">要写入的实际数据</param>
  1016. /// <returns>返回写入结果</returns>
  1017. public OperateResult Write(string address, uint[] values)
  1018. {
  1019. return Write( address, ByteTransform.TransByte( values ) );
  1020. }
  1021. /// <summary>
  1022. /// 向PLC中写入uint数据,返回值说明
  1023. /// </summary>
  1024. /// <param name="address">要写入的数据地址</param>
  1025. /// <param name="data">要写入的实际数据</param>
  1026. /// <returns>返回写入结果</returns>
  1027. public OperateResult Write(string address, uint data)
  1028. {
  1029. return Write( address, new uint[] { data } );
  1030. }
  1031. #endregion
  1032. #region Write Float
  1033. /// <summary>
  1034. /// 向PLC中写入float数组,返回值说明
  1035. /// </summary>
  1036. /// <param name="address">要写入的数据地址</param>
  1037. /// <param name="values">要写入的实际数据</param>
  1038. /// <returns>返回写入结果</returns>
  1039. public OperateResult Write(string address, float[] values)
  1040. {
  1041. return Write( address, ByteTransform.TransByte( values ) );
  1042. }
  1043. /// <summary>
  1044. /// 向PLC中写入float数据,返回值说明
  1045. /// </summary>
  1046. /// <param name="address">要写入的数据地址</param>
  1047. /// <param name="value">要写入的实际数据</param>
  1048. /// <returns>返回写入结果</returns>
  1049. public OperateResult Write(string address, float value)
  1050. {
  1051. return Write( address, new float[] { value } );
  1052. }
  1053. #endregion
  1054. #region Write Long
  1055. /// <summary>
  1056. /// 向PLC中写入long数组,返回值说明
  1057. /// </summary>
  1058. /// <param name="address">要写入的数据地址</param>
  1059. /// <param name="values">要写入的实际数据</param>
  1060. /// <returns>返回写入结果</returns>
  1061. public OperateResult Write(string address, long[] values)
  1062. {
  1063. return Write( address, ByteTransform.TransByte( values ) );
  1064. }
  1065. /// <summary>
  1066. /// 向PLC中写入long数据,返回值说明
  1067. /// </summary>
  1068. /// <param name="address">要写入的数据地址</param>
  1069. /// <param name="data">要写入的实际数据</param>
  1070. /// <returns>返回写入结果</returns>
  1071. public OperateResult Write(string address, long data)
  1072. {
  1073. return Write( address, new long[] { data } );
  1074. }
  1075. #endregion
  1076. #region Write ULong
  1077. /// <summary>
  1078. /// 向PLC中写入ulong数组,返回值说明
  1079. /// </summary>
  1080. /// <param name="address">要写入的数据地址</param>
  1081. /// <param name="values">要写入的实际数据</param>
  1082. /// <returns>返回写入结果</returns>
  1083. public OperateResult Write(string address, ulong[] values)
  1084. {
  1085. return Write( address, ByteTransform.TransByte( values ) );
  1086. }
  1087. /// <summary>
  1088. /// 向PLC中写入ulong数据,返回值说明
  1089. /// </summary>
  1090. /// <param name="address">要写入的数据地址</param>
  1091. /// <param name="value">要写入的实际数据</param>
  1092. /// <returns>返回写入结果</returns>
  1093. public OperateResult Write(string address, ulong value)
  1094. {
  1095. return Write( address, new ulong[] { value } );
  1096. }
  1097. #endregion
  1098. #region Write Double
  1099. /// <summary>
  1100. /// 向PLC中写入double数组,返回值说明
  1101. /// </summary>
  1102. /// <param name="address">要写入的数据地址</param>
  1103. /// <param name="values">要写入的实际数据</param>
  1104. /// <returns>返回写入结果</returns>
  1105. public OperateResult Write(string address, double[] values)
  1106. {
  1107. return Write( address, ByteTransform.TransByte( values ) );
  1108. }
  1109. /// <summary>
  1110. /// 向PLC中写入double数据,返回值说明
  1111. /// </summary>
  1112. /// <param name="address">要写入的数据地址</param>
  1113. /// <param name="value">要写入的实际数据</param>
  1114. /// <returns>返回写入结果</returns>
  1115. public OperateResult Write(string address, double value)
  1116. {
  1117. return Write( address, new double[] { value } );
  1118. }
  1119. #endregion
  1120. #region Head Codes
  1121. private byte[] plcHead1 = new byte[22]
  1122. {
  1123. 0x03, // 01 RFC1006 Header
  1124. 0x00, // 02 通常为 0
  1125. 0x00, // 03 数据长度,高位
  1126. 0x16, // 04 数据长度,地位
  1127. 0x11, // 05 连接类型0x11:tcp 0x12 ISO-on-TCP
  1128. 0xE0, // 06 主动建立连接
  1129. 0x00, // 07 本地接口ID
  1130. 0x00, // 08 主动连接时为0
  1131. 0x00, // 09 该参数未使用
  1132. 0x01, // 10
  1133. 0x00, // 11
  1134. 0xC0, // 12
  1135. 0x01, // 13
  1136. 0x0A, // 14
  1137. 0xC1, // 15
  1138. 0x02, // 16
  1139. 0x01, // 17
  1140. 0x00, // 18
  1141. 0xC2, // 19 指示cpu
  1142. 0x02, // 20
  1143. 0x01, // 21
  1144. 0x00 // 22
  1145. };
  1146. private byte[] plcHead2 = new byte[25]
  1147. {
  1148. 0x03,
  1149. 0x00,
  1150. 0x00,
  1151. 0x19,
  1152. 0x02,
  1153. 0xF0,
  1154. 0x80,
  1155. 0x32,
  1156. 0x01,
  1157. 0x00,
  1158. 0x00,
  1159. 0x04,
  1160. 0x00,
  1161. 0x00,
  1162. 0x08,
  1163. 0x00,
  1164. 0x00,
  1165. 0xF0, // 设置通讯
  1166. 0x00,
  1167. 0x00,
  1168. 0x01,
  1169. 0x00,
  1170. 0x01,
  1171. 0x01,
  1172. 0xE0
  1173. };
  1174. private byte[] plcOrderNumber = new byte[]
  1175. {
  1176. 0x03,
  1177. 0x00,
  1178. 0x00,
  1179. 0x21,
  1180. 0x02,
  1181. 0xF0,
  1182. 0x80,
  1183. 0x32,
  1184. 0x07,
  1185. 0x00,
  1186. 0x00,
  1187. 0x00,
  1188. 0x01,
  1189. 0x00,
  1190. 0x08,
  1191. 0x00,
  1192. 0x08,
  1193. 0x00,
  1194. 0x01,
  1195. 0x12,
  1196. 0x04,
  1197. 0x11,
  1198. 0x44,
  1199. 0x01,
  1200. 0x00,
  1201. 0xFF,
  1202. 0x09,
  1203. 0x00,
  1204. 0x04,
  1205. 0x00,
  1206. 0x11,
  1207. 0x00,
  1208. 0x00
  1209. };
  1210. private SiemensPLCS CurrentPlc = SiemensPLCS.S1200;
  1211. private byte[] plcHead1_200smart = new byte[22]
  1212. {
  1213. 0x03, // 01 RFC1006 Header
  1214. 0x00, // 02 通常为 0
  1215. 0x00, // 03 数据长度,高位
  1216. 0x16, // 04 数据长度,地位
  1217. 0x11, // 05 连接类型0x11:tcp 0x12 ISO-on-TCP
  1218. 0xE0, // 06 主动建立连接
  1219. 0x00, // 07 本地接口ID
  1220. 0x00, // 08 主动连接时为0
  1221. 0x00, // 09 该参数未使用
  1222. 0x01, // 10
  1223. 0x00, // 11
  1224. 0xC1, // 12
  1225. 0x02, // 13
  1226. 0x10, // 14
  1227. 0x00, // 15
  1228. 0xC2, // 16
  1229. 0x02, // 17
  1230. 0x03, // 18
  1231. 0x00, // 19 指示cpu
  1232. 0xC0, // 20
  1233. 0x01, // 21
  1234. 0x0A // 22
  1235. };
  1236. private byte[] plcHead2_200smart = new byte[25]
  1237. {
  1238. 0x03,
  1239. 0x00,
  1240. 0x00,
  1241. 0x19,
  1242. 0x02,
  1243. 0xF0,
  1244. 0x80,
  1245. 0x32,
  1246. 0x01,
  1247. 0x00,
  1248. 0x00,
  1249. 0xCC,
  1250. 0xC1,
  1251. 0x00,
  1252. 0x08,
  1253. 0x00,
  1254. 0x00,
  1255. 0xF0, // 设置通讯
  1256. 0x00,
  1257. 0x00,
  1258. 0x01,
  1259. 0x00,
  1260. 0x01,
  1261. 0x03,
  1262. 0xC0
  1263. };
  1264. #endregion
  1265. #region Object Override
  1266. /// <summary>
  1267. /// 获取当前对象的字符串标识形式
  1268. /// </summary>
  1269. /// <returns>字符串信息</returns>
  1270. public override string ToString()
  1271. {
  1272. return "SiemensS7Net";
  1273. }
  1274. #endregion
  1275. }
  1276. }