using HslCommunication; using HslCommunication.Profinet.Melsec; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; using static OpenCvSharp.FileStorage; public class MelsecPLCTCPDriver { private MelsecMcNet melsecMc = new MelsecMcNet(); // private HslCommunication.ModBus.ModbusTcpNet melsecMc = new HslCommunication.ModBus.ModbusTcpNet(); //HslCommunication.Profinet.Melsec.MelsecMcServer melsecMc = new HslCommunication.Profinet.Melsec.MelsecMcServer(); #region PLCBase public List Read(string startAddress, int length) { PLCItem item = new PLCItem(); item.Address = startAddress; item.ItemLength = length; ReadItem(item); //List valueList = new List(); //if (!string.IsNullOrWhiteSpace(item.ItemValue)) //{ // valueList = item.ItemValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList().ConvertAll(s => int.Parse(s)).ToList(); //} return item.ItemValues; } public void ReadItem(PLCItem item) { // item.PLCOpType = PLCOpType.Read; item.ItemValues.Clear(); try { // 读取Int变量 var result = melsecMc.ReadInt32("D" + item.Address, (ushort)item.ItemLength); if (result.IsSuccess) { for (int i = 0; i < result.Content.Length; i++) { item.ItemValues.Add(result.Content[i]); } } else { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + item.Address + ";长度:" + item.ItemLength + ";提示:" + result.Message); } } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage()); } } public int ReadInt(string address) { try { // 读取Int变量 var result = melsecMc.ReadInt32("D" + address); if (result.IsSuccess) { return result.Content; } else { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message); return -1; } } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage()); return -1; } } public void WriteItem(PLCItem item, bool waitForReply = true) { item.PLCOpType = PLCOpType.Write; if (item.ItemValues == null || item.ItemValues.Count < 1) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入值不能为空"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = melsecMc.Write(item.Address, item.ItemValues.First()); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { //LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} WriteItem:{item.GetDisplayText()},写入 {item.ItemValues.First()}完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 /// /// 地址 /// /// public void WriteInt(string address, int writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = melsecMc.Write("D" + address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 string值 /// /// 地址 /// /// public void WriteString(string address, string writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(writeValue)) { // LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = melsecMc.Write(address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms"); } /// /// 写单独地址 float值 /// /// 地址 /// /// public void WriteFloat(string address, float writeValue, bool waitForReply = true) { if (string.IsNullOrEmpty(address)) { //LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!"); return; } int repeatTime = 3; Stopwatch sw = new Stopwatch(); do { try { var result = melsecMc.Write(address, writeValue); if (result.IsSuccess) { repeatTime = 0; } } catch (Exception ex) { if (repeatTime < 0) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}"); } } } while (repeatTime > 0); sw.Stop(); // LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms"); } #endregion #region DeviceBase public void Start() { // IConfig.ip melsecMc = new MelsecMcNet("192.168.3.39", 502); // 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码 // melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 }); //melsecMc = new HslCommunication.ModBus.ModbusTcpNet(); //melsecMc.IpAddress = "192.168.3.39"; //melsecMc.Port = 502; //melsecMc.ConnectTimeOut = 10000; // 连接超时,单位毫秒 //melsecMc.ReceiveTimeOut = 5000; // 接收超时,单位毫秒 //melsecMc.Station = 1; //melsecMc.AddressStartWithZero = true; //melsecMc.IsStringReverse = false; //melsecMc.DataFormat = HslCommunication.Core.DataFormat.CDAB; // melsecMc.ServerStart(6000); // 连接对象 OperateResult connect = melsecMc.ConnectServer(); if (connect.IsSuccess) { Task.Run(() => { HeartbeatMonitor(); }); } else { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}"); } } protected void Stop() { try { // 断开连接 // melsecMc.RemoteStop(); // OmronUDPNet.Stop(); } catch (Exception ex) { // LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}"); } } #endregion #region IMonitor readonly byte[] scanBuffer = new byte[2048]; public List GetMonitorValues(int startAddress, int length) { List res = new List(); // var result = melsecMc.ReadUInt16(startAddress.ToString(), (ushort)length); // var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length); var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length); if (result.IsSuccess) { res = new List(result.Content); } else { //LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:W" + startAddress + ";长度:" + length + ";提示:" + result.Message); } return res; } #endregion int HeartbeatCycle = 2; string HeartbeatAddress = "D800"; bool CurrentState = false; public event Action Heartbeat; public async void HeartbeatMonitor() { if (HeartbeatCycle <= 0) { return; } await Task.Run(async () => { if (!string.IsNullOrEmpty(HeartbeatAddress) && HeartbeatCycle > 0) { while (CurrentState != false) { if (HeartbeatCycle <= 0) { return; } try { await Task.Delay(HeartbeatCycle * 1000); var result = melsecMc.Write(HeartbeatAddress, 1); if (!result.IsSuccess) { Heartbeat?.Invoke(1); //LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败"); } } catch (Exception ex) { } } } }); } }