ModbusClientHelper.cs 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. /**
  2. *┌──────────────────────────────────────────────────────────────┐
  3. *│ 描 述:ModbusClient的工具类
  4. *│ 作 者:执笔小白
  5. *│ 版 本:1.3
  6. *│ 创建时间:2023-11-24 12:40:56
  7. *└──────────────────────────────────────────────────────────────┘
  8. *┌──────────────────────────────────────────────────────────────┐
  9. *│ 命名空间: Util.NetworkProtocolHelpers
  10. *│ 类 名:ModbusClientHelper
  11. *└──────────────────────────────────────────────────────────────┘
  12. */
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Diagnostics;
  16. using System.IO.Ports;
  17. using System.Linq;
  18. using System.Net;
  19. using System.Net.NetworkInformation;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Threading.Tasks;
  23. using System.Web.Services.Description;
  24. using System.Windows;
  25. using static EasyModbus.ModbusClient;
  26. using ModbusClient = EasyModbus.ModbusClient;
  27. namespace ModBusClientSimple.Util
  28. {
  29. /// <summary>
  30. /// ModbusTcpClient帮助类
  31. /// </summary>
  32. public class ModbusClientHelper
  33. {
  34. #region 变量
  35. /// <summary>
  36. /// ModbusClient对象
  37. /// </summary>
  38. private ModbusClient _modbusClient;
  39. /// <summary>
  40. /// 是否是TCP
  41. /// true为TCP;
  42. /// </summary>
  43. private ModbusClientConnType _modbusClientConnType = ModbusClientConnType.TCP;
  44. #endregion 变量
  45. /// <summary>
  46. /// 创建ModbusTCP Client
  47. /// </summary>
  48. /// <param name="ipStr">IP</param>
  49. /// <param name="portStr">端口</param>
  50. /// <param name="connected_Register">检测 是否连接成功 用的寄存器地址(value=1说明连接成功);默认为-1(不推荐),-1代表使用ping IP的形式</param>
  51. /// <param name="isConn">是否开始连接</param>
  52. public ModbusClientHelper(string ipAddress = "127.0.0.1", int port = 502, int connected_Register = -1, bool isConn = false)
  53. {
  54. _modbusClientConnType = ModbusClientConnType.TCP;
  55. _connected_Register = connected_Register;
  56. _modbusClient = new ModbusClient(ipAddress, port);
  57. if (isConn)
  58. {
  59. Connect();
  60. }
  61. }
  62. /// <summary>
  63. /// 创建ModbusRTU Client
  64. /// </summary>
  65. /// <param name="serialPort">COM串口(COM1~COM99)</param>
  66. /// <param name="unitIdentifier"> Slave ID(默认值0)</param>
  67. /// <param name="baudrate">波特率(默认值9600)</param>
  68. /// <param name="stopBits">停止位(可以为Parity.Even)</param>
  69. /// <param name="parity">校验位(可以为StopBits.OnePointFive)</param>
  70. public ModbusClientHelper(string serialPort, byte unitIdentifier, int baudrate, StopBits stopBits, Parity parity)
  71. {
  72. _modbusClientConnType = ModbusClientConnType.SerialPort;
  73. _modbusClient = new ModbusClient();
  74. _modbusClient.SerialPort = serialPort; // COM串口(COM1~COM99)
  75. _modbusClient.UnitIdentifier = unitIdentifier; // Slave ID(默认值0)
  76. _modbusClient.Baudrate = baudrate; // 波特率(默认值9600)
  77. _modbusClient.StopBits = stopBits; // 停止位(可以为Parity.Even)
  78. _modbusClient.Parity = parity; // 校验位(可以为StopBits.OnePointFive)
  79. }
  80. #region 连接与断开连接
  81. /// <summary>
  82. /// 连接-可持续断线重连机制
  83. /// </summary>
  84. /// <param name="isKeep">断线重连</param>
  85. /// <param name="reconnSpace">断线重连间隔 1000ms</param>
  86. //public void Connect(bool isKeep = false, int isKeep_reconnSpace = 1000)
  87. public void Connect()
  88. {
  89. //if (isKeep_reconnSpace != 0)
  90. // _reconnSpace = isKeep_reconnSpace;
  91. //if (isKeep)
  92. //{
  93. // 以下方案不可用
  94. //_modbusClient.ConnectedChanged += new EasyModbus.ModbusClient.ConnectedChangedHandler(UpdateConnectedChanged); // 重连机制
  95. //Task.Run(() =>
  96. //{
  97. // UpdateConnectedChanged();
  98. //});
  99. //}
  100. _modbusClient.Connect();
  101. }
  102. /// <summary>
  103. /// 断开连接
  104. /// </summary>
  105. public void Disconnect()
  106. {
  107. if (_modbusClient != null)
  108. _modbusClient.Disconnect();
  109. }
  110. /// <summary>
  111. /// 重连
  112. /// </summary>
  113. public void ReConnect()
  114. {
  115. try
  116. {
  117. if (_modbusClient != null)
  118. {
  119. switch (_modbusClientConnType)
  120. {
  121. case ModbusClientConnType.TCP:
  122. string ip = IPAddress;
  123. int port = Port;
  124. _modbusClient.Disconnect();
  125. _modbusClient = new ModbusClient(ip, port);
  126. _modbusClient.Connect();
  127. break;
  128. case ModbusClientConnType.SerialPort:
  129. string serialPort = _modbusClient.SerialPort;
  130. byte unitIdentifier = _modbusClient.UnitIdentifier;
  131. int baudrate = _modbusClient.Baudrate;
  132. StopBits stopBits = _modbusClient.StopBits;
  133. Parity parity = _modbusClient.Parity;
  134. _modbusClient.Disconnect();
  135. _modbusClient = new ModbusClient();
  136. _modbusClient.SerialPort = serialPort; // COM串口(COM1~COM99)
  137. _modbusClient.UnitIdentifier = unitIdentifier; // Slave ID(默认值0)
  138. _modbusClient.Baudrate = baudrate; // 波特率(默认值9600)
  139. _modbusClient.StopBits = stopBits; // 停止位(可以为Parity.Even)
  140. _modbusClient.Parity = parity; // 校验位(可以为StopBits.OnePointFive)
  141. _modbusClient.Connect();
  142. break;
  143. }
  144. }
  145. }
  146. catch (Exception ex)
  147. {
  148. Debug.Write(ex.Message.ToString());
  149. }
  150. }
  151. #region 重连机制
  152. /// <summary>
  153. /// 断线重连间隔,默认为1000ms
  154. /// </summary>
  155. private int _reconnSpace = 1000;
  156. /// <summary>
  157. /// 重连写法一_上次重连时间
  158. /// </summary>
  159. public DateTime lastReconnTime;
  160. /// <summary>
  161. /// 重连等待锁
  162. /// </summary>
  163. object threadlock = new object(); // 资源锁
  164. /// <summary>
  165. /// 重连机制
  166. /// </summary>
  167. /// <returns></returns>
  168. /// <param name = "reconnSpace" > 断线重连间隔 1000ms</param>
  169. //private void UpdateConnectedChanged(object sender)
  170. private void UpdateConnectedChanged()
  171. {
  172. #region 重连写法一
  173. //while (true)
  174. //{
  175. // if (!_modbusClient.Connected)
  176. // {
  177. // if (lastReconnTime < DateTime.Now.AddMilliseconds(-reconnSpace))
  178. // {
  179. // lastReconnTime= DateTime.Now;
  180. // // 保护机制
  181. // lock (threadlock)
  182. // {
  183. // Monitor.Wait(threadlock, _reconnSpace);
  184. // }
  185. // if (!_modbusClient.Connected)
  186. // {
  187. // _modbusClient.Disconnect();
  188. // _modbusClient.Connect();
  189. // }
  190. // }
  191. // else
  192. // {
  193. // lock (threadlock)
  194. // {
  195. // Monitor.Wait(threadlock, 1000); // 等待1s
  196. // }
  197. // }
  198. // }
  199. // else
  200. // {
  201. // break;
  202. // }
  203. //}
  204. #endregion 重连写法一
  205. #region 重连写法二
  206. //if (!_modbusClient.Connected)
  207. //{
  208. // lock (threadlock)
  209. // {
  210. // Monitor.Wait(threadlock, _reconnSpace);
  211. // }
  212. // //_modbusClient.Disconnect();
  213. // _modbusClient.Connect();
  214. //}
  215. #endregion 重连写法二
  216. #region 重连写法三
  217. while (true)
  218. {
  219. if (!IsConnected)
  220. {
  221. lock (threadlock)
  222. {
  223. Monitor.Wait(threadlock, _reconnSpace);
  224. }
  225. //_modbusClient.Disconnect();
  226. try
  227. {
  228. _modbusClient.Connect();
  229. }
  230. catch { }
  231. }
  232. }
  233. #endregion 重连写法三
  234. }
  235. #endregion 重连机制
  236. #endregion 连接与断开连接
  237. #region 常用属性
  238. /// <summary>
  239. /// 检查是否连接到Modbus TCP Server
  240. /// </summary>
  241. //public bool Connected => _modbusClient.Connected;// 经测试,_modbusClient.Connected无效
  242. /// <summary>
  243. /// 检测ModbusClient连接状态
  244. /// </summary>
  245. private int _connected_Register = -1;
  246. /// <summary>
  247. /// Modbus TCP Server状态
  248. /// </summary>
  249. private bool connected = false;
  250. /// <summary>
  251. /// 检查是否连接到Modbus TCP Server
  252. /// </summary>
  253. public bool IsConnected
  254. {
  255. get
  256. {
  257. if (_modbusClientConnType == ModbusClientConnType.SerialPort)
  258. {
  259. return _modbusClient.Connected;
  260. }
  261. else // TCP
  262. {
  263. if (_connected_Register == -1) // 默认为ping IP的形式;不推荐
  264. {
  265. try
  266. {
  267. Ping p = new Ping();
  268. PingReply r = p.Send(_modbusClient.IPAddress, 3000);
  269. connected = r.Status == IPStatus.Success ? true : false;
  270. }
  271. catch { connected = false; }
  272. }
  273. else
  274. {
  275. try
  276. {
  277. var values = _modbusClient.ReadHoldingRegisters(_connected_Register, 1).FirstOrDefault();
  278. connected = values == 1;
  279. }
  280. catch { connected = false; }
  281. }
  282. return connected;
  283. }
  284. }
  285. set
  286. {
  287. connected = value;
  288. }
  289. }
  290. /// <summary>
  291. /// 获取 Modbus-TCP Server的IP-Address
  292. /// </summary>
  293. public string IPAddress => _modbusClient.IPAddress;
  294. /// <summary>
  295. /// 获取 Modbus-TCP Server的Port (默认是 502).
  296. /// </summary>
  297. public int Port => _modbusClient.Port;
  298. #endregion 常用属性
  299. #region 常用方法
  300. #region 读写值的方法
  301. #region 1、线圈(Coils)
  302. /// <summary>
  303. /// 读线圈(Coils) (FC1)
  304. /// </summary>
  305. /// <param name="startingAddress">第一个要读取的 线圈的地址</param>
  306. /// <param name="quantity">要读取的 线圈数量</param>
  307. /// <returns>线圈值的布尔数组</returns>
  308. public bool[] ReadCoils(int startingAddress, int quantity) => _modbusClient.ReadCoils(startingAddress, quantity);
  309. /// <summary>
  310. /// 写线圈(Coils)_单个 (FC5)
  311. /// </summary>
  312. /// <param name="startingAddress">线圈的地址</param>
  313. /// <param name="value">线圈值</param>
  314. public void WriteSingleCoil(int startingAddress, bool value) => _modbusClient.WriteSingleCoil(startingAddress, value);
  315. /// <summary>
  316. /// 写线圈(Coils)_多个 (FC15)
  317. /// </summary>
  318. /// <param name="startingAddress">第一个要写的线圈的地址</param>
  319. /// <param name="values">线圈值的布尔数组</param>
  320. public void WriteMultipleCoils(int startingAddress, bool[] values) => _modbusClient.WriteMultipleCoils(startingAddress, values);
  321. #endregion 1、线圈(Coils)
  322. #region 2、离散输入(Discrete Inputs)
  323. /// <summary>
  324. /// 读 离散输入(Discrete Inputs)(FC2)
  325. /// </summary>
  326. /// <param name="startingAddress">要读取的第一个 离散输入的地址</param>
  327. /// <param name="quantity">要读取的 离散输入数量</param>
  328. /// <returns>离散输入的布尔数组</returns>
  329. public bool[] ReadDiscreteInputs(int startingAddress, int quantity) => _modbusClient.ReadDiscreteInputs(startingAddress, quantity);
  330. #endregion 2、离散输入(Discrete Inputs)
  331. // 3、浮点寄存器(Modbus协议可能不支持)
  332. #region 4、输入寄存器(Input Registers)-只读
  333. /// <summary>
  334. /// 读 输入寄存器(Input Registers) (FC4)
  335. /// </summary>
  336. /// <param name="startingAddress">第一个要读取的 输入寄存器 的地址</param>
  337. /// <param name="quantity">要读取的 输入寄存器 数量</param>
  338. /// <returns></returns>
  339. public int[] ReadInputRegisters(int startingAddress, int quantity) => _modbusClient.ReadInputRegisters(startingAddress, quantity);
  340. /// <summary>
  341. /// 读 整数类型的输入寄存器(Input Registers)_单个整数/小数(FC4)- 泛型
  342. /// </summary>
  343. /// <typeparam name="T"></typeparam>
  344. /// <param name="startingAddress">第一个要读取的 输入寄存器 的地址</param>
  345. /// <param name="quantity">要读取的 输入寄存器 数量</param>
  346. /// <param name="registerOrder">Registers数据的读取顺序(默认为LowHigh)</param>
  347. /// <returns>返回的值(数字型的值类型为0;其他:时间类型的值类型为default,引用类型默认为null)</returns>
  348. public T ReadInputRegisters<T>(int startingAddress, int quantity, RegisterOrder registerOrder = RegisterOrder.LowHigh) where T : struct
  349. {
  350. T result = default;
  351. int[] registers;
  352. // 解析数据流
  353. string type = typeof(T).ToString();
  354. switch (type)
  355. {
  356. case "System.Int32": // Int整数
  357. registers = _modbusClient.ReadInputRegisters(startingAddress, 2); // 读取数据流
  358. int int1 = ModbusClient.ConvertRegistersToInt(registers, registerOrder);
  359. result = (T)Convert.ChangeType(int1, typeof(T));
  360. break;
  361. case "System.Single": // Float单精度小数
  362. registers = _modbusClient.ReadInputRegisters(startingAddress, 2); // 读取数据流
  363. float float1 = ModbusClient.ConvertRegistersToFloat(registers, registerOrder);
  364. result = (T)Convert.ChangeType(float1, typeof(T));
  365. break;
  366. case "System.Int64": // Long长整数
  367. registers = _modbusClient.ReadInputRegisters(startingAddress, 4); // 读取数据流
  368. long long1 = ModbusClient.ConvertRegistersToLong(registers, registerOrder);
  369. result = (T)Convert.ChangeType(long1, typeof(T));
  370. break;
  371. case "System.Double": // Double双精度小数
  372. registers = _modbusClient.ReadInputRegisters(startingAddress, 4); // 读取数据流
  373. double double1 = ModbusClient.ConvertRegistersToDouble(registers, registerOrder);
  374. result = (T)Convert.ChangeType(double1, typeof(T));
  375. break;
  376. //case "System.String": // String字符串
  377. // ModbusClient.ConvertRegistersToString(registers, offset, stringLength);
  378. // break;
  379. default:
  380. break;
  381. }
  382. return result;
  383. }
  384. /// <summary>
  385. /// 读 字符串类型的输入寄存器(Input Registers)_单个字符串(FC4)
  386. /// </summary>
  387. /// <typeparam name="T"></typeparam>
  388. /// <param name="startingAddress">第一个要读取的 输入寄存器 的地址</param>
  389. /// <param name="quantity">要读取的 输入寄存器 数量</param>
  390. /// <param name="stringLength">字符串中的字符数(必须为偶数)</param>
  391. /// <param name="offset">偏移量(偏移几个Register;默认为0)</param>
  392. /// <returns>返回的值(引用类型默认为null;其他:数字型的值类型为0,时间类型的值类型为default)</returns>
  393. public string ReadInputRegisters(int startingAddress, int quantity, int stringLength, int offset)
  394. {
  395. // 读取数据流
  396. int[] registers = _modbusClient.ReadInputRegisters(startingAddress, quantity);
  397. // 解析数据流
  398. return ModbusClient.ConvertRegistersToString(registers, offset, stringLength);
  399. }
  400. #endregion 4、输入寄存器(Input Registers)-只读
  401. #region 5、保持寄存器(Holding Registers)-常用
  402. /// <summary>
  403. /// 读 保持寄存器(Holding Registers) (FC3)
  404. /// </summary>
  405. /// <param name="startingAddress">第一个要读取的 保持寄存器的地址</param>
  406. /// <param name="quantity">要读取的 保持寄存器 数量</param>
  407. /// <returns></returns>
  408. public int[] ReadHoldingRegisters(int startingAddress, int quantity) => _modbusClient.ReadHoldingRegisters(startingAddress, quantity);
  409. /// <summary>
  410. /// 读 整数类型的保持寄存器(Holding Registers)_单个整数/小数(FC3)- 泛型
  411. /// </summary>
  412. /// <typeparam name="T"></typeparam>
  413. /// <param name="startingAddress">第一个要读取的 保持寄存器 的地址</param>
  414. /// <param name="registerOrder">Registers数据的读取顺序(默认为LowHigh)</param>
  415. /// <returns>返回的值(数字型的值类型为0;其他:时间类型的值类型为default,引用类型默认为null)</returns>
  416. public T ReadHoldingRegisters<T>(int startingAddress, RegisterOrder registerOrder = RegisterOrder.LowHigh) where T : struct
  417. {
  418. T result = default;
  419. int[] registers;
  420. // 解析数据流
  421. string type = typeof(T).ToString();
  422. switch (type)
  423. {
  424. case "System.Int16": // Int整数
  425. registers = _modbusClient.ReadHoldingRegisters(startingAddress, 1); // 读取数据流
  426. int int16 = registers.FirstOrDefault();
  427. result = (T)Convert.ChangeType(int16, typeof(T));
  428. break;
  429. case "System.Int32": // Int整数
  430. registers = _modbusClient.ReadHoldingRegisters(startingAddress, 2); // 读取数据流
  431. int int32 = ModbusClient.ConvertRegistersToInt(registers, registerOrder);
  432. result = (T)Convert.ChangeType(int32, typeof(T));
  433. break;
  434. case "System.Single": // Float单精度小数
  435. registers = _modbusClient.ReadHoldingRegisters(startingAddress, 2); // 读取数据流
  436. float float1 = ModbusClient.ConvertRegistersToFloat(registers, registerOrder);
  437. result = (T)Convert.ChangeType(float1, typeof(T));
  438. break;
  439. case "System.Int64": // Long长整数
  440. registers = _modbusClient.ReadHoldingRegisters(startingAddress, 4); // 读取数据流
  441. long long1 = ModbusClient.ConvertRegistersToLong(registers, registerOrder);
  442. result = (T)Convert.ChangeType(long1, typeof(T));
  443. break;
  444. case "System.Double": // Double双精度小数
  445. registers = _modbusClient.ReadHoldingRegisters(startingAddress, 4); // 读取数据流
  446. double double1 = ModbusClient.ConvertRegistersToDouble(registers, registerOrder);
  447. result = (T)Convert.ChangeType(double1, typeof(T));
  448. break;
  449. //case "System.String": // String字符串
  450. // ModbusClient.ConvertRegistersToString(registers, offset, stringLength);
  451. // break;
  452. default:
  453. break;
  454. }
  455. return result;
  456. }
  457. /// <summary>
  458. /// 读 字符串类型的保持寄存器(Holding Registers)_单个字符串(FC3)
  459. /// </summary>
  460. /// <typeparam name="T"></typeparam>
  461. /// <param name="startingAddress">第一个要读取的 保持寄存器 的地址</param>
  462. /// <param name="quantity">要读取的 保持寄存器 数量</param>
  463. /// <param name="stringLength">字符串中的字符数(必须为偶数)</param>
  464. /// <param name="offset">偏移量(偏移几个Register;默认为0)</param>
  465. /// <returns>返回的值(引用类型默认为null;其他:数字型的值类型为0,时间类型的值类型为default)</returns>
  466. public string ReadHoldingRegisters(int startingAddress, int quantity, int stringLength, int offset = 0)
  467. {
  468. // 读取数据流
  469. int[] registers = _modbusClient.ReadHoldingRegisters(startingAddress, quantity);
  470. // 解析数据流
  471. return ModbusClient.ConvertRegistersToString(registers, offset, stringLength);
  472. }
  473. /// <summary>
  474. /// 写 保持寄存器(Holding Registers)_单个Register (FC6)
  475. /// </summary>
  476. /// <param name="startingAddress">要写入的 保持寄存器的地址</param>
  477. /// <param name="value">保持寄存器的值</param>
  478. public void WriteSingleRegister(int startingAddress, int value) => _modbusClient.WriteSingleRegister(startingAddress, value);
  479. /// <summary>
  480. /// 写 保持寄存器(Holding Registers)_多个 (FC16)
  481. /// </summary>
  482. /// <param name="startingAddress">要写入的第一个 保持寄存器的地址</param>
  483. /// <param name="values">保持寄存器的值的int数组</param>
  484. public void WriteMultipleRegisters(int startingAddress, int[] values) => _modbusClient.WriteMultipleRegisters(startingAddress, values);
  485. /// <summary>
  486. /// 写 保持寄存器(Holding Registers)_单个整数/小数/字符串 (FC16)
  487. /// </summary>
  488. /// <param name="startingAddress">要写入的第一个 保持寄存器的地址</param>
  489. /// <param name="values">写入的值</param>
  490. /// <param name="quantity">寄存器个数限制(字符串专用)</param>
  491. /// <param name="registerOrder">读写顺序(默认LowHigh)</param>
  492. public void WriteMultipleRegisters<T>(int startingAddress, object value, int quantity = 0, RegisterOrder registerOrder = RegisterOrder.LowHigh)
  493. {
  494. // 转化为数据流
  495. int[] datas; // 存储数据
  496. string type = typeof(T).ToString();
  497. switch (type)
  498. {
  499. case "System.Int16": // Int16整数
  500. datas = new int[] { Convert.ToInt16(value) };
  501. break;
  502. case "System.Int32": // Int32整数
  503. datas = ModbusClient.ConvertIntToRegisters(Convert.ToInt32(value), registerOrder);
  504. break;
  505. case "System.Single": // Float单精度小数
  506. datas = ModbusClient.ConvertFloatToRegisters(Convert.ToSingle(value), registerOrder);
  507. break;
  508. case "System.Int64": // Long长整数
  509. datas = ModbusClient.ConvertLongToRegisters(Convert.ToInt64(value), registerOrder);
  510. break;
  511. case "System.Double": // Double双精度小数
  512. datas = ModbusClient.ConvertDoubleToRegisters(Convert.ToDouble(value), registerOrder);
  513. break;
  514. case "System.String": // String字符串
  515. datas = ModbusClient.ConvertStringToRegisters(Convert.ToString(value));
  516. // 限制占用的寄存器个数
  517. if (quantity != 0 && datas.Count() > quantity)
  518. {
  519. Array.Resize(ref datas, quantity);
  520. }
  521. _modbusClient.WriteMultipleRegisters(startingAddress, new int[quantity]); // 先清除旧数据
  522. break;
  523. default:
  524. datas = new int[] { };
  525. break;
  526. }
  527. if (datas == null || datas.Length == 0) // 未转化成功的不进行写入
  528. {
  529. string returnStr = "ModbusTcp协议,地址:" + startingAddress + "值:" + value + "写入失败!类型转化失败...";
  530. Console.WriteLine(returnStr);
  531. throw new Exception(returnStr);
  532. }
  533. _modbusClient.WriteMultipleRegisters(startingAddress, datas);
  534. }
  535. /// <summary>
  536. /// 读取+写入保持寄存器(Holding Registers)_多个(FC23)
  537. /// </summary>
  538. /// <param name="startingAddressRead">第一个要读取的 保持寄存器的地址</param>
  539. /// <param name="quantityRead">要读取的 保持寄存器 数量</param>
  540. /// <param name="startingAddressWrite">要写入的第一个 保持寄存器的地址</param>
  541. /// <param name="values">保持寄存器的值的int数组</param>
  542. /// <returns></returns>
  543. public int[] ReadWriteMultipleRegisters(int startingAddressRead, int quantityRead, int startingAddressWrite, int[] values)
  544. => _modbusClient.ReadWriteMultipleRegisters(startingAddressRead, quantityRead, startingAddressWrite, values);
  545. #endregion 5、保持寄存器(Holding Registers)-常用
  546. // 6、ASCII字符(Modbus协议可能不支持)
  547. #endregion 读写值的方法
  548. #region 检查状态-略
  549. /// <summary>
  550. /// 检查是否连接到Modbus TCP Server
  551. /// </summary>
  552. public bool Connected() => IsConnected;
  553. // 1、ping IP地址
  554. // 2、在外面检查DB块状态
  555. #endregion 检查状态-略
  556. #endregion 常用方法
  557. }
  558. /// <summary>
  559. /// ModbusClient的通讯类型
  560. /// </summary>
  561. public enum ModbusClientConnType
  562. {
  563. TCP,
  564. SerialPort
  565. }
  566. #region 示例
  567. /// <summary>
  568. /// 使用示例
  569. /// </summary>
  570. public class UseClass
  571. {
  572. /// <summary>
  573. /// 定义一个字典,存plc对象(通讯)
  574. /// </summary>
  575. Dictionary<int, ModbusClientHelper> Funs = new Dictionary<int, ModbusClientHelper>();
  576. public void main1()
  577. {
  578. Funs.Add(1, new ModbusClientHelper("", 502, 499)); // 壳体上料
  579. var dd = new Task(() => { ReadStation_S2(1); });
  580. }
  581. /// <summary>
  582. /// 电性能测试
  583. /// </summary>
  584. /// <param name="no">PLC编号</param>
  585. private async void ReadStation_S2(int no)
  586. {
  587. // [S1]装胶圈
  588. // [S2]电性能测试
  589. // [S3]导通性测试
  590. // [S4]气密测试
  591. // [S5]激光标记
  592. // [S6]CCD检测
  593. string stationName = "[S2]电性能测试";
  594. ManualResetEvent MreReadPLC = new ManualResetEvent(false);
  595. while (!MreReadPLC.WaitOne(300)) // 运行间隔300ms
  596. {
  597. try
  598. {
  599. if (Funs[no].IsConnected) // 检查PLC是否已连接上
  600. {
  601. #region 电性能测试-加工数据
  602. try
  603. {
  604. int iPLC_Flag = Funs[no].ReadHoldingRegisters(908, 1).FirstOrDefault(); // PLC_Flag
  605. int iMES_Flag = Funs[no].ReadHoldingRegisters(909, 1).FirstOrDefault(); // MES_Flag
  606. bool pLC_Flag = iPLC_Flag == 1 ? true : false; // PLC_Flag
  607. bool mES_Flag = iMES_Flag == 1 ? true : false; // MES_Flag
  608. if (pLC_Flag && !mES_Flag) // 1 0
  609. {
  610. //AddMessage(LogType.Info, Head + stationName + Body);
  611. await Task.Run(() => { DoProcessData_电性能测试(no); });
  612. //AddMessage(LogType.Info, stationName + Body + Tail);
  613. }
  614. else if (!pLC_Flag && mES_Flag) // 0 1
  615. {
  616. // 清空写给PLC的数据
  617. // 清空MES_RESULT
  618. Funs[no].WriteMultipleRegisters<int>(910, 0); // MES_RESULT
  619. // MES_Flag重置为0
  620. Funs[no].WriteSingleRegister(909, 0); // MES_Flag
  621. }
  622. }
  623. catch (Exception ex)
  624. {
  625. Funs[no].WriteMultipleRegisters<int>(910, 2); // MES_RESULT 为2上位机报错
  626. Funs[no].WriteSingleRegister(909, 1); // MES_Flag
  627. //AddMessage(LogType.Error, $"PLC{no}_{stationName}上传加工运行出错!错误信息:" + ex.Message.ToString());
  628. }
  629. #endregion 电性能测试-加工数据
  630. #region 电性能测试-点检数据
  631. try
  632. {
  633. int iPLC_Flag = Funs[no].ReadHoldingRegisters(1100, 1).FirstOrDefault(); // PLC_Flag
  634. int iMES_Flag = Funs[no].ReadHoldingRegisters(1101, 1).FirstOrDefault(); // MES_Flag
  635. bool pLC_Flag = iPLC_Flag == 1 ? true : false; // PLC_Flag
  636. bool mES_Flag = iMES_Flag == 1 ? true : false; // MES_Flag
  637. if (pLC_Flag && !mES_Flag) // 1 0
  638. {
  639. //AddMessage(LogType.Info, Head + stationName + Body);
  640. await Task.Run(() => { DoOneCheckData_电性能测试(no); });
  641. //AddMessage(LogType.Info, stationName + Body + Tail);
  642. }
  643. else if (!pLC_Flag && mES_Flag) // 0 1
  644. {
  645. // 清空写给PLC的数据
  646. // 清空MES_RESULT
  647. Funs[no].WriteMultipleRegisters<int>(1102, 0); // MES_RESULT
  648. // MES_Flag重置为0
  649. Funs[no].WriteSingleRegister(1101, 0); // MES_Flag
  650. }
  651. }
  652. catch (Exception ex)
  653. {
  654. Funs[no].WriteMultipleRegisters<int>(1102, 2); // MES_RESULT 为2上位机报错
  655. Funs[no].WriteSingleRegister(1101, 1); // MES_Flag
  656. //AddMessage(LogType.Error, $"PLC{no}_{stationName}点检运行出错!错误信息:" + ex.Message.ToString());
  657. }
  658. #endregion 电性能测试-点检数据
  659. //UpdatePLCMonitor(no, 1); // 更新PLC状态的UI // 更新PLC状态的UI
  660. }
  661. else
  662. {
  663. //UpdatePLCMonitor(no, 0); // 更新PLC状态的UI
  664. //WritePLCLog(LogType.Info, "PLC" + no.ToString() + "_" + stationName + "连接失败!");
  665. Funs[no].Connect();
  666. }
  667. }
  668. catch (Exception ex)
  669. {
  670. //UpdatePLCMonitor(no, 0); // 更新PLC状态的UI
  671. //AddMessage(LogType.Error, $"PLC{no}_{stationName}运行出错!错误信息:" + ex.Message.ToString());
  672. }
  673. }
  674. }
  675. // 上传加工数据_电性能测试
  676. private void DoProcessData_电性能测试(int no)
  677. {
  678. string equipmentCode = "LineCode" + "-S2"; // 设备编号
  679. string processItem = "电性能测试"; // 测试项目
  680. try
  681. {
  682. string workorder_code = Funs[no].ReadHoldingRegisters(944, 32, 32); // 车间订单号
  683. workorder_code = string.IsNullOrEmpty(workorder_code) ? "" : workorder_code.Replace("\0", "").Trim();
  684. string batch_num = Funs[no].ReadHoldingRegisters(976, 32, 32); // 批次号
  685. batch_num = string.IsNullOrEmpty(batch_num) ? "" : batch_num.Replace("\0", "").Trim();
  686. string mtltmrk = Funs[no].ReadHoldingRegisters(912, 32, 32); // 产品型号
  687. mtltmrk = string.IsNullOrEmpty(mtltmrk) ? "" : mtltmrk.Replace("\0", "").Trim();
  688. string plcDate_Y = Funs[no].ReadHoldingRegisters(1040, 1).FirstOrDefault().ToString("0000"); // 产品序列号的 当前日期_年
  689. string plcDate_M = Funs[no].ReadHoldingRegisters(1041, 1).FirstOrDefault().ToString("00"); // 产品序列号的 当前日期_月
  690. string plcDate_D = Funs[no].ReadHoldingRegisters(1042, 1).FirstOrDefault().ToString("00"); // 产品序列号的 当前日期_日
  691. string plcDate_YMD = string.Concat(plcDate_Y, plcDate_M, plcDate_D); // 产品序列号的 当前日期
  692. string supplierCode = Funs[no].ReadHoldingRegisters(1008, 32, 32); // 供应商代码
  693. supplierCode = string.IsNullOrEmpty(supplierCode) ? "" : supplierCode.Replace("\0", "").Trim();
  694. int sn_Number = Funs[no].ReadHoldingRegisters<int>(1048); // 产品序列号的 数字序列部分
  695. string sn = mtltmrk + batch_num + plcDate_YMD + supplierCode; // 产品序列号
  696. //List<TestItem> items = new List<TestItem>()
  697. //{
  698. // new TestItem(){
  699. // Parameter_name = "结果判定",
  700. // Parameter_value = Funs[no].ReadHoldingRegisters(1050,1).FirstOrDefault()==1?"OK":"NG",
  701. // Parameter_unit = ""
  702. // },
  703. // new TestItem(){
  704. // Parameter_name = "绝缘电阻测试压设定值",
  705. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1051).ToString(),
  706. // Parameter_unit = "V"
  707. // },
  708. // new TestItem(){
  709. // Parameter_name = "绝缘电阻测试时间设定值",
  710. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1055).ToString(),
  711. // Parameter_unit = "s"
  712. // },
  713. // new TestItem(){
  714. // Parameter_name = "绝缘电阻电阻设定值",
  715. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1057).ToString(),
  716. // Parameter_unit = "Ω"
  717. // },
  718. // new TestItem(){
  719. // Parameter_name = "耐电压测试压设定值",
  720. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1061).ToString(),
  721. // Parameter_unit = "V"
  722. // },
  723. // new TestItem(){
  724. // Parameter_name = "耐电压测试时间设定值",
  725. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1065).ToString(),
  726. // Parameter_unit = "s"
  727. // },
  728. // new TestItem(){
  729. // Parameter_name = "漏电流设定上限值",
  730. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1067).ToString(),
  731. // Parameter_unit = "mA"
  732. // },
  733. // new TestItem(){
  734. // Parameter_name = "漏电流设定下限值",
  735. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1071).ToString(),
  736. // Parameter_unit = "mA"
  737. // },
  738. // new TestItem(){
  739. // Parameter_name = "绝缘电阻测试压实际值",
  740. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1075).ToString(),
  741. // Parameter_unit = "V"
  742. // },
  743. // new TestItem(){
  744. // Parameter_name = "绝缘电阻测试时间实际值",
  745. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1079).ToString(),
  746. // Parameter_unit = "s"
  747. // },
  748. // new TestItem(){
  749. // Parameter_name = "绝缘电阻电阻实际值",
  750. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1081).ToString(),
  751. // Parameter_unit = "Ω"
  752. // },
  753. // new TestItem(){
  754. // Parameter_name = "耐电压测试压实际值",
  755. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1085).ToString(),
  756. // Parameter_unit = "V"
  757. // },
  758. // new TestItem(){
  759. // Parameter_name = "耐电压测试时间实际值",
  760. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1089).ToString(),
  761. // Parameter_unit = "s"
  762. // },
  763. // new TestItem(){
  764. // Parameter_name = "漏电流实际值",
  765. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1091).ToString(),
  766. // Parameter_unit = "mA"
  767. // },
  768. // new TestItem(){
  769. // Parameter_name = "产品结果",
  770. // Parameter_value = Funs[no].ReadHoldingRegisters(1095, 1).FirstOrDefault()==1?"OK":"NG",
  771. // Parameter_unit = ""
  772. // }
  773. //};
  774. int result1 = 1; // 取最后一次的结果
  775. for (int i = 0; i < 4; i++)
  776. {
  777. string newsn = string.Concat(sn, (sn_Number + i).ToString());
  778. //result1 = SwitctProcessData(items, equipmentCode, processItem
  779. //, workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, newsn); // 上传数据
  780. }
  781. int result = result1 == 1 ? 1 : ("是否上传数据" == "" ? 4 : 1);
  782. Funs[no].WriteMultipleRegisters<int>(910, result); // MES_RESULT 为4MES报错
  783. Funs[no].WriteSingleRegister(909, 1); // MES_Flag
  784. //WritePLCLog(LogType.Debug, $"PLC{no}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  785. }
  786. catch (Exception ex)
  787. {
  788. Funs[no].WriteMultipleRegisters<int>(910, 2); // MES_RESULT 为2上位机报错
  789. Funs[no].WriteSingleRegister(909, 1); // MES_Flag
  790. //AddMessage(LogType.Error, $"PLC{no}_[{equipmentCode}]{processItem}上传加工报错!错误信息:" + ex.Message.ToString());
  791. }
  792. }
  793. // 上传点检数据_电性能测试
  794. private void DoOneCheckData_电性能测试(int no)
  795. {
  796. string equipmentCode = "LineCode" + "-S2"; // 设备编号
  797. string processItem = "电性能测试"; // 测试项目
  798. try
  799. {
  800. string workorder_code = Funs[no].ReadHoldingRegisters(1104, 32, 32); // 车间订单号
  801. workorder_code = string.IsNullOrEmpty(workorder_code) ? "" : workorder_code.Replace("\0", "").Trim();
  802. //string accno = Funs[no].ReadHoldingRegisters(1136, 32, 32); // 工序编号
  803. //accno = string.IsNullOrEmpty(accno) ? "" : accno.Replace("\0", "").Trim();
  804. string accno = "2"; // 工序编号
  805. int dxncs = Funs[no].ReadHoldingRegisters<int>(1168); // 电性能测试OK点检
  806. int dxncsTD1 = Funs[no].ReadHoldingRegisters<int>(1170); // 电性能测试通道1NG点检
  807. int dxncsTD2 = Funs[no].ReadHoldingRegisters<int>(1172); // 电性能测试通道2NG点检
  808. int dxncsTD3 = Funs[no].ReadHoldingRegisters<int>(1174); // 电性能测试通道3NG点检
  809. int dxncsTD4 = Funs[no].ReadHoldingRegisters<int>(1176); // 电性能测试通道4NG点检
  810. // 测试参数
  811. //List<TestItem> items = new List<TestItem>()
  812. //{
  813. // new TestItem(){
  814. // Parameter_name = "绝缘电阻测试压设定值",
  815. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1051).ToString(),
  816. // Parameter_unit = "V"
  817. // },
  818. // new TestItem(){
  819. // Parameter_name = "绝缘电阻测试时间设定值",
  820. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1055).ToString(),
  821. // Parameter_unit = "s"
  822. // },
  823. // new TestItem(){
  824. // Parameter_name = "绝缘电阻电阻设定值",
  825. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1057).ToString(),
  826. // Parameter_unit = "Ω"
  827. // },
  828. // new TestItem(){
  829. // Parameter_name = "耐电压测试压设定值",
  830. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1061).ToString(),
  831. // Parameter_unit = "V"
  832. // },
  833. // new TestItem(){
  834. // Parameter_name = "耐电压测试时间设定值",
  835. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1065).ToString(),
  836. // Parameter_unit = "s"
  837. // },
  838. // new TestItem(){
  839. // Parameter_name = "漏电流设定上限值",
  840. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1067).ToString(),
  841. // Parameter_unit = "mA"
  842. // },
  843. // new TestItem(){
  844. // Parameter_name = "漏电流设定下限值",
  845. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1071).ToString(),
  846. // Parameter_unit = "mA"
  847. // },
  848. // new TestItem(){
  849. // Parameter_name = "绝缘电阻测试压实际值",
  850. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1075).ToString(),
  851. // Parameter_unit = "V"
  852. // },
  853. // new TestItem(){
  854. // Parameter_name = "绝缘电阻测试时间实际值",
  855. // Parameter_value = Funs[no].ReadHoldingRegisters<int>(1079).ToString(),
  856. // Parameter_unit = "s"
  857. // },
  858. // new TestItem(){
  859. // Parameter_name = "绝缘电阻电阻实际值",
  860. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1081).ToString(),
  861. // Parameter_unit = "Ω"
  862. // },
  863. // new TestItem(){
  864. // Parameter_name = "耐电压测试压实际值",
  865. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1085).ToString(),
  866. // Parameter_unit = "V"
  867. // },
  868. // new TestItem(){
  869. // Parameter_name = "耐电压测试时间实际值",
  870. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1089).ToString(),
  871. // Parameter_unit = "s"
  872. // },
  873. // new TestItem(){
  874. // Parameter_name = "漏电流实际值",
  875. // Parameter_value = Funs[no].ReadHoldingRegisters<float>(1091).ToString(),
  876. // Parameter_unit = "mA"
  877. // }
  878. //};
  879. string itemsStr = string.Empty;
  880. //itemsStr =JsonConvert.SerializeObject(items);
  881. #region 上传数据
  882. //List<OneCheckItem> cheItems = new List<OneCheckItem>();
  883. //// 每次只上传一项点检内容;8为不上传
  884. //if (dxncs != 8 && dxncsTD1 == 8 && dxncsTD2 == 8 && dxncsTD3 == 8 && dxncsTD4 == 8) // 电性能测试OK点检
  885. //{
  886. // cheItems.Add(new OneCheckItem()
  887. // {
  888. // Onecheck_name = "电性能测试OK点检",
  889. // Onecheck_content = "OK件点检结果为OK",
  890. // Onecheck_result = (OneCheckRD.OneCheckResultDetails.Keys.Contains(dxncs) ? OneCheckRD.OneCheckResultDetails[dxncs] : OneCheckRD.OneCheckResultDetails[9])
  891. // + ";" + itemsStr
  892. // });
  893. //}
  894. //else if (dxncs == 8 && dxncsTD1 != 8 && dxncsTD2 == 8 && dxncsTD3 == 8 && dxncsTD4 == 8) // 电性能测试通道1NG点检
  895. //{
  896. // cheItems.Add(new OneCheckItem()
  897. // {
  898. // Onecheck_name = "电性能测试通道1NG点检",
  899. // Onecheck_content = "NG样件点检结果为NG",
  900. // Onecheck_result = (OneCheckRD.OneCheckResultDetails.Keys.Contains(dxncsTD1) ? OneCheckRD.OneCheckResultDetails[dxncsTD1] : OneCheckRD.OneCheckResultDetails[9])
  901. // + ";" + itemsStr
  902. // });
  903. //}
  904. //else if (dxncs == 8 && dxncsTD1 == 8 && dxncsTD2 != 8 && dxncsTD3 == 8 && dxncsTD4 == 8) // 电性能测试通道2NG点检
  905. //{
  906. // cheItems.Add(new OneCheckItem()
  907. // {
  908. // Onecheck_name = "电性能测试通道2NG点检",
  909. // Onecheck_content = "NG样件点检结果为NG",
  910. // Onecheck_result = (OneCheckRD.OneCheckResultDetails.Keys.Contains(dxncsTD2) ? OneCheckRD.OneCheckResultDetails[dxncsTD2] : OneCheckRD.OneCheckResultDetails[9])
  911. // + ";" + itemsStr
  912. // });
  913. //}
  914. //else if (dxncs == 8 && dxncsTD1 == 8 && dxncsTD2 == 8 && dxncsTD3 != 8 && dxncsTD4 == 8) // 电性能测试通道3NG点检
  915. //{
  916. // cheItems.Add(new OneCheckItem()
  917. // {
  918. // Onecheck_name = "电性能测试通道3NG点检",
  919. // Onecheck_content = "NG样件点检结果为NG",
  920. // Onecheck_result = (OneCheckRD.OneCheckResultDetails.Keys.Contains(dxncsTD3) ? OneCheckRD.OneCheckResultDetails[dxncsTD3] : OneCheckRD.OneCheckResultDetails[9])
  921. // + ";" + itemsStr
  922. // });
  923. //}
  924. //else if (dxncs == 8 && dxncsTD1 == 8 && dxncsTD2 == 8 && dxncsTD3 == 8 && dxncsTD4 != 8) // 电性能测试通道4NG点检
  925. //{
  926. // cheItems.Add(new OneCheckItem()
  927. // {
  928. // Onecheck_name = "电性能测试通道4NG点检",
  929. // Onecheck_content = "NG样件点检结果为NG",
  930. // Onecheck_result = (OneCheckRD.OneCheckResultDetails.Keys.Contains(dxncsTD4) ? OneCheckRD.OneCheckResultDetails[dxncsTD4] : OneCheckRD.OneCheckResultDetails[9])
  931. // + ";" + itemsStr
  932. // });
  933. //}
  934. //else // 不上传
  935. //{
  936. // Funs[no].WriteMultipleRegisters<int>(1102, 6); // MES_RESULT 为“6未找到唯一点检项”
  937. // Funs[no].WriteSingleRegister(1101, 1); // MES_Flag
  938. // AddMessage(LogType.Error, $"PLC{no}_[{equipmentCode}]{processItem}点检报错!未找到唯一的点检项目");
  939. //}
  940. int result1 = 1;
  941. //OneCheckData oneCheckData = new OneCheckData()
  942. //{
  943. // Line_code = GlobalContext.LineCode,
  944. // Line_name = GlobalContext.LineName,
  945. // Equipment_code = equipmentCode,
  946. // Equipment_name = equipmentCode,
  947. // Workorder_code = workorder_code,
  948. // Procedure_code = accno,
  949. // Procedure_name = processItem,
  950. // Oneckeck_values = cheItems,
  951. // Onecheck_empcode = "",
  952. // Onecheck_empname = "",
  953. // Onecheck_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
  954. //};
  955. //result1 = SwitctOneCheckData(oneCheckData, equipmentCode, processItem);
  956. #endregion 上传数据
  957. int result = result1 == 1 ? 1 : ("上传点检数据" == "" ? 4 : 1);
  958. Funs[no].WriteMultipleRegisters<int>(1102, result); // MES_RESULT 为4MES报错
  959. Funs[no].WriteSingleRegister(1101, 1); // MES_Flag
  960. //WritePLCLog(LogType.Debug, $"PLC{no}_[{equipmentCode}]{processItem}-Write" + (result == 1 ? "成功!" : "失败!"));
  961. }
  962. catch (Exception ex)
  963. {
  964. Funs[no].WriteMultipleRegisters<int>(1102, 2); // MES_RESULT 为2上位机报错
  965. Funs[no].WriteSingleRegister(1101, 1); // MES_Flag
  966. //AddMessage(LogType.Error, $"PLC{no}_[{equipmentCode}]{processItem}点检报错!错误信息:" + ex.Message.ToString());
  967. }
  968. }
  969. }
  970. #endregion
  971. }