using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; using System.Threading.Tasks; using HighWayIot.Log4net; using HslCommunication; using HslCommunication.Profinet.Melsec; using System.Diagnostics; using System.Linq; namespace HighWayIot.Plc { public class PlcConnect { //private static readonly Lazy lazy = new Lazy(() => new PlcConnect()); //public static PlcConnect Instance //{ // get // { // return lazy.Value; // } //} private static LogHelper logHelper = LogHelper.Instance; /// /// 静态懒加载MelsecMcNet2 读取 CPU /// public static readonly MelsecMcNet MelsecInstance1 = CreateAb("192.168.0.10", 2001); /// /// 静态懒加载MelsecMcNet2 写入 CPU /// public static readonly MelsecMcNet MelsecInstance2 = CreateAb("192.168.0.10", 2002); /// /// 锁对象写 /// private static readonly object lockerWrite = new object(); /// /// 锁对象读 /// private static readonly object lockerRead = new object(); private PlcConnect() { } /// /// 初始化三菱的服务器 /// /// private static MelsecMcNet CreateAb(string ip, int port) { //string Ip = ; MelsecMcNet plc = new MelsecMcNet(); try { plc.CommunicationPipe = new HslCommunication.Core.Pipe.PipeTcpNet(ip, port) { ConnectTimeOut = 3000, // 连接超时时间,单位毫秒 ReceiveTimeOut = 2000, // 接收超时时间,单位毫秒 SleepTime = 0, SocketKeepAliveTime = -1, IsPersistentConnection = true, }; OperateResult result; result = plc.ConnectServer(); logHelper.Info($"Plc连接 信息:[{result.Message}] 错误代码:[{result.ErrorCode}]"); } catch (Exception ex) { logHelper.Error("初始化PLC服务器发生错误!", ex); } return plc; } /// /// PLC2写入数据 /// /// 地址 /// 值 /// 数据类型 /// public static OperateResult PlcWrite2(string address, object value, DataTypeEnum type) { var result = new OperateResult() { IsSuccess = false }; try { lock (lockerWrite) { //Stopwatch swWrite = new Stopwatch(); //swWrite.Start(); switch (type) { case DataTypeEnum.Bool: result = MelsecInstance1.Write(address, Convert.ToBoolean(value)); break; case DataTypeEnum.Byte: result = MelsecInstance1.Write(address, Convert.ToByte(value)); break; //case DataTypeEnum.Bytes: // result = MelsecInstance1.Write(address, ObjectToBytes(value)); // break; case DataTypeEnum.Int16: result = MelsecInstance1.Write(address, Convert.ToInt16(value)); break; case DataTypeEnum.UInt16: result = MelsecInstance1.Write(address, Convert.ToUInt16(value)); break; case DataTypeEnum.Int32: result = MelsecInstance1.Write(address, Convert.ToInt32(value)); break; case DataTypeEnum.UInt32: result = MelsecInstance1.Write(address, Convert.ToUInt32(value)); break; case DataTypeEnum.Int64: result = MelsecInstance1.Write(address, Convert.ToInt64(value)); break; case DataTypeEnum.UInt64: result = MelsecInstance1.Write(address, Convert.ToUInt64(value)); break; case DataTypeEnum.Float: result = MelsecInstance1.Write(address, Convert.ToSingle(value)); break; case DataTypeEnum.Double: result = MelsecInstance1.Write(address, Convert.ToDouble(value)); break; case DataTypeEnum.String: result = MelsecInstance1.Write(address, Convert.ToString(value)); break; default: throw new ArgumentException($"Unsupported data type: {type}"); } //swWrite.Stop(); //logHelper.Info($"Write address:[{address}] value:[{value}] result:[{result.IsSuccess}] time:[{swWrite.ElapsedMilliseconds}]"); } } catch (Exception ex) { logHelper.Error("PLC写入数据发生错误!", ex); } return result; } /// /// 写入byte数组 /// /// /// /// public static OperateResult PlcWriteBytes2(string address, byte[] data) { OperateResult result = new OperateResult(); try { lock (lockerWrite) { result = MelsecInstance2.Write(address, data); } } catch (Exception ex) { logHelper.Error($"PLC2写入Bytes发生错误!address:[{address}]", ex); return default; } return result; } // 将对象序列化为 byte 数组 public static byte[] ObjectToBytes(object obj) { using (MemoryStream ms = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); return ms.ToArray(); } } // 将 byte 数组反序列化为对象 public static object BytesToObject(byte[] bytes) { using (MemoryStream ms = new MemoryStream(bytes)) { IFormatter formatter = new BinaryFormatter(); return formatter.Deserialize(ms); } } /// /// 字符串读取2 /// /// /// /// public static OperateResult ReadString2(string address, ushort length) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadString(address, length); } } catch (Exception ex) { logHelper.Error($"PLC2读取String发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取字节数组 /// /// /// /// public static OperateResult ReadByte2(string address, ushort length) { OperateResult result = new OperateResult(); try { lock (lockerRead) { //Stopwatch swRead = new Stopwatch(); //swRead.Start(); result = MelsecInstance2.Read(address, length); //swRead.Stop(); //logHelper.Info($"Read address:[{address}] length:[{length}] result:[{result.IsSuccess}] time:[{swRead.ElapsedMilliseconds}]"); } } catch (Exception ex) { logHelper.Error($"PLC2读取bytes发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取bool /// /// /// public static OperateResult ReadBool2(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadBool(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Bool发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取Int16 /// /// /// public static OperateResult ReadInt162(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadInt16(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取UInt16 /// /// /// public static OperateResult ReadUInt162(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadUInt16(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取Int32 /// /// /// public static OperateResult ReadInt322(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadInt32(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取UInt32 /// /// /// public static OperateResult ReadUInt322(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadUInt32(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取Int64 /// /// /// public static OperateResult ReadInt642(string address) { OperateResult result = new OperateResult(); try { lock(lockerRead) { result = MelsecInstance2.ReadInt64(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取UInt64 /// /// /// public static OperateResult ReadUInt642(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadUInt64(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Int16发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取Float /// /// /// public static OperateResult ReadFloat2(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadFloat(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Float发生错误!address:[{address}]", ex); return default; } return result; } /// /// 读取Double /// /// /// public static OperateResult ReadDouble2(string address) { OperateResult result = new OperateResult(); try { lock (lockerRead) { result = MelsecInstance2.ReadDouble(address); } } catch (Exception ex) { logHelper.Error($"PLC读取Double发生错误!address:[{address}]", ex); return default; } return result; } } }