using S7.Net; using S7.Net.Types; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace SamplePre.Communication { public class S7PlcCommunicatorBack : IDisposable { public Plc _plc; private readonly string _ipAddress; private readonly int _rack; private readonly int _slot; private readonly CpuType _cpuType; /// /// 是否连接 /// public bool IsConnected => _plc?.IsConnected ?? false; /// /// 连接状态变化事件 /// public event Action ConnectionStatusChanged; /// /// 构造函数 /// /// PLC型号 /// IP地址 /// 机架号 /// 插槽号 public S7PlcCommunicatorBack(CpuType cpuType, string ipAddress, int rack = 0, int slot = 1) { _cpuType = cpuType; _ipAddress = ipAddress; _rack = rack; _slot = slot; _plc = new Plc(cpuType, ipAddress, (short)rack, (short)slot); } /// /// 连接PLC /// /// 是否连接成功 public bool Connect() { try { if (IsConnected) { Console.WriteLine("已经处于连接状态"); return true; } // 如果之前的连接对象已释放,创建新的 if (_plc == null) { _plc = new Plc(_cpuType, _ipAddress, (short)_rack, (short)_slot); } _plc.Open(); bool connected = _plc.IsConnected; Console.WriteLine(connected ? "PLC连接成功" : "PLC连接失败"); ConnectionStatusChanged?.Invoke(connected); return connected; } catch (Exception ex) { Console.WriteLine($"连接PLC失败: {ex.Message}"); ConnectionStatusChanged?.Invoke(false); return false; } } /// /// 断开连接 /// public void Disconnect() { try { if (IsConnected) { _plc.Close(); Console.WriteLine("PLC连接已断开"); ConnectionStatusChanged?.Invoke(false); } } catch (Exception ex) { Console.WriteLine($"断开PLC连接失败: {ex.Message}"); } } /// /// 读取数据 /// /// 地址(如"M0.0", "DB1.DBW2") /// 读取的值 public object ReadData(string address) { try { if (!IsConnected && !Connect()) { return null; } object value = _plc.Read(address); Console.WriteLine($"a读取 {address} 成功: {value}"); return value; } catch (Exception ex) { Console.WriteLine($"读取 {address} 失败: {ex.Message}"); return null; } } /// /// 写入数据 /// /// 地址(如"M0.0", "DB1.DBW2") /// 要写入的值 /// 是否写入成功 public bool WriteData(string address, object value) { try { if (!IsConnected && !Connect()) { return false; } _plc.Write(address, value); Console.WriteLine($"写入 {address} 成功: {value}"); return true; } catch (Exception ex) { Console.WriteLine($"写入 {address} 失败: {ex.Message}"); return false; } } /// /// 批量读取数据 /// /// 地址数组 /// 值数组,与地址数组顺序对应 public object[] ReadMultipleData(string[] addresses) { if (addresses == null || addresses.Length == 0) return new object[0]; try { if (!IsConnected && !Connect()) { return null; } var values = new object[addresses.Length]; for (int i = 0; i < addresses.Length; i++) { values[i] = _plc.Read(addresses[i]); } Console.WriteLine($"批量读取 {addresses.Length} 个地址成功"); return values; } catch (Exception ex) { Console.WriteLine($"批量读取失败: {ex.Message}"); return null; } } /// /// 写入数组数据 /// /// /// /// /// public bool WriteArraysBtye(int Dbno, int start, byte[] bytes) { try { if (!IsConnected && !Connect()) { return false; } _plc.WriteBytes(DataType.DataBlock, Dbno, start, bytes); return true; } catch (Exception ex) { Console.WriteLine($"写入数组: {ex.Message}"); return false; } } /// /// 读取数组 /// /// public ushort[] ReadArraysShort(int Dbno,int start,int lenth) { try { if (!IsConnected && !Connect()) { return null; } //public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0) ushort[] datas = _plc.Read(DataType.DataBlock, Dbno, start, VarType.Word, lenth) as ushort[]; return datas; } catch (Exception ex) { Console.WriteLine($"读取数组: {ex.Message}"); return null; } } /// /// 读结构体 /// public T ReadStruct(int dbno, int start) { T t; try { if (!IsConnected && !Connect()) { return default(T); } t = (T)_plc.ReadStruct(typeof(T), dbno, start); return t; } catch (Exception) { Console.WriteLine($"读结构体失败!"); return default(T); } } /// /// 写结构体 /// public bool WriteStruct(T t,int dbno,int start) { try { if (!IsConnected && !Connect()) { return false; } _plc.WriteStruct(t, dbno, start); return true; } catch (Exception) { Console.WriteLine($"写入失败!"); return false; } } /// /// 读取字符串 /// /// /// /// public string ReadString(int DBno, int startNo) { try { if (!IsConnected && !Connect()) { return ""; } int totalLenth = (byte)_plc.Read(S7.Net.DataType.DataBlock, DBno, startNo, VarType.Byte, 1); int len = (byte)_plc.Read(S7.Net.DataType.DataBlock, DBno, startNo + 1, VarType.Byte, 1); byte[] bytes = _plc.ReadBytes(S7.Net.DataType.DataBlock, DBno, startNo + 2, len); string mesg = Encoding.ASCII.GetString(bytes); return mesg; } catch (Exception ex) { Console.WriteLine($"读取字符串失败!"); return ""; } } /// /// 写入字符串 /// /// /// /// /// public bool WriteString(int DBno,int startNo, string contextStr) { try { if (!IsConnected && !Connect()) { return false; } _plc.Write(S7.Net.DataType.DataBlock, DBno, startNo + 1, (byte)contextStr.Length); _plc.Write(S7.Net.DataType.DataBlock, DBno, startNo + 2, contextStr); Console.WriteLine($"写入字符串成功!"); return true; } catch (Exception ex) { Console.WriteLine($"写入字符串失败!"); return false; } } /// /// 写入bool /// /// /// /// /// public bool WriteBoolen(int DBno, int startByteAdr, int bitAdr, bool val) { try { if (!IsConnected && !Connect()) { return false; } _plc.WriteBit(DataType.DataBlock, DBno, startByteAdr, bitAdr, val); Console.WriteLine($"写入成功!"); return true; } catch (Exception ex) { Console.WriteLine($"写入失败!"); return false; } } /// /// 释放资源 /// public void Dispose() { Disconnect(); //_plc?.Dispose(); _plc = null; } } struct TestA { public ushort value1; public ushort value2; } }