using DefaultEdit.Core; using DefaultEdit.Log4xml; using Sharp7; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Prism.Mvvm; using TouchSocket.Sockets; using System.Xml; using NextTreatMesDemo.Utils; using System.Data; namespace DefaultEdit.Communication { public class S7PlcCommunicate : BindableBase { private S7Client client = new S7Client(); private bool _IsConnected=false; private string IP; public S7Client Client { get => client; set => client = value; } public bool IsConnected { get => _IsConnected; set { SetProperty(ref _IsConnected, value); } } public event Action ConnectedEvent; public event Action DisconnectedEvent; public event Action ReceivedEvent; public event Action SendEvent; public S7PlcCommunicate(string ip) { IP = ip; } public async Task OpenPlc() { var res = Client.ConnectTo(IP, 0, 1);//连接PLC的IP地址 if ( res == 0 ) { ConnectedEvent += S7PlcCommunicate_ConnectedEvent; DisconnectedEvent += S7PlcCommunicate_DisconnectedEvent; ReceivedEvent += S7PlcCommunicate_ReceivedEvent; IsConnected = true; LogHelper.Info($"Plc {IP}:连接成功"); } else { IsConnected = false; LogHelper.Info($"Plc{IP}:连接失败"); } } public async Task ReconnectedPlc() { while ( !Client.Connected ) { try { var res = Client.ConnectTo(IP, 0, 1);//连接PLC的IP地址 if ( res == 0 ) { LogHelper.Info($"Plc {IP}:重连成功"); break; } else { LogHelper.Info($"Plc {IP}:重连失败"); } } catch ( Exception ex ) { LogHelper.Error("重连plc出错" + ex.Message); } Thread.Sleep(200); } IsConnected = true; } public void StopPlc() { Client.Disconnect(); } private void S7PlcCommunicate_ReceivedEvent(string arg2) { } private void S7PlcCommunicate_DisconnectedEvent(string arg2) { IsConnected = false; ReconnectedPlc(); } private void S7PlcCommunicate_ConnectedEvent(string arg2) { LogHelper.Info("PLC已连接"); } public bool ReadBool(int ReadONDBNumber, int ReadStart,int bitStart) { try { if ( client.Connected ) { byte[]buffs=new byte[1]; Client.DBRead(ReadONDBNumber, ReadStart, 1, buffs); return buffs.GetBitAt(0, bitStart); } } catch ( Exception e ) { LogHelper.Error("plc读取bool异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } public byte[] ReadByte(int ReadONDBNumber, int ReadStart, int byteSize) { try { if ( client.Connected ) { byte[]buffs=new byte[byteSize]; Client.DBRead(ReadONDBNumber, ReadStart, byteSize, buffs); return buffs; } } catch ( Exception e ) { LogHelper.Error("plc读取bool异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } public bool[] ReadBools(int ReadONDBNumber, int ReadStart,int bitStart,int bitSize) { try { if ( client.Connected ) { int bytesToRead = CalculateBytesToRead(ReadStart, bitStart, bitSize); // 返回3 byte[]buffs=new byte[bytesToRead]; Client.DBRead(ReadONDBNumber, ReadStart, bytesToRead, buffs); return ParseBoolArray(buffs, bitStart, bitSize); } } catch ( Exception e ) { LogHelper.Error("plc读取bool数组异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } /// /// 两位 /// /// /// /// /// /// public short Readshort(int ReadONDBNumber, int ReadStart) { try { if ( client.Connected ) { byte[]buffs=new byte[2]; Client.DBRead(ReadONDBNumber, ReadStart, 2, buffs); return buffs.GetIntAt(0); } } catch ( Exception e ) { LogHelper.Error("plc读取Ushort异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } /// /// 四位 /// /// /// /// /// /// public int ReadInt(int ReadONDBNumber, int ReadStart) { try { if ( client.Connected ) { byte[]buffs=new byte[4]; Client.DBRead(ReadONDBNumber, ReadStart, 4, buffs); return buffs.GetDIntAt(0); } } catch ( Exception e ) { LogHelper.Error("plc读取Ushort异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } public float Readfloat(int ReadONDBNumber, int ReadStart) { try { if ( client.Connected ) { byte[]buffs=new byte[4]; Client.DBRead(ReadONDBNumber, ReadStart, 4, buffs); return buffs.GetRealAt(0); } } catch ( Exception e ) { LogHelper.Error("plc读取Float异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } public TimeSpan ReadTime(int ReadONDBNumber, int ReadStart) { try { if ( client.Connected ) { byte[]buffs=new byte[4]; Client.DBRead(ReadONDBNumber, ReadStart, 4, buffs); return buffs.GetS7TimespanAt(0); } } catch ( Exception e ) { LogHelper.Error("plc读取Float异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } throw new InvalidOperationException‌("PLC未连接"); } public string ReadString(int ReadONDBNumber, int ReadStart, int ReadSize = 1) { try { if ( client.Connected ) { byte []buffs = new byte[ReadSize]; //读取数据 Client.DBRead(ReadONDBNumber, ReadStart, ReadSize, buffs); byte[] buffsT = new byte[ buffs[ 1 ] ]; Array.Copy(buffs, 2, buffsT, 0, buffs[ 1 ]); string str=(Encoding.ASCII.GetString(buffsT)).Trim().TrimEnd('\0') ; return str; } } catch ( Exception e ) { LogHelper.Error("plc读取String异常" + e.Message); } return null; } public void WriteBool(int WriteONDBNumber, int WriteStart,int bitStart, bool value) { try { if ( client.Connected ) { byte[] res = new byte[1]; client.DBRead(WriteONDBNumber, WriteStart, 1, res); res.SetBitAt(0, bitStart, value); client.DBWrite(WriteONDBNumber, WriteStart, 1, res); } } catch ( Exception e ) { LogHelper.Error("plc写入bool异常" + e.Message); } } public void Writeshort(int WriteONDBNumber, int WriteStart, short value) { try { if ( client.Connected ) { byte[] res = new byte[2]; res.SetIntAt(0, value); client.DBWrite(WriteONDBNumber, WriteStart, 2, res); } } catch ( Exception e ) { LogHelper.Error("plc写入Ushort异常" + e.Message); } } public void Writefloat(int WriteONDBNumber, int WriteStart, float value) { try { if ( client.Connected ) { byte[] res = new byte[4]; res.SetRealAt(0, value); client.DBWrite(WriteONDBNumber, WriteStart, 4, res); } } catch ( Exception e ) { LogHelper.Error("plc写入Float异常" + e.Message); } } public void WriteTime(int WriteONDBNumber, int WriteStart, TimeSpan value) { try { if ( client.Connected ) { byte[] res = new byte[4]; res.SetS7TimespanAt(0, value); client.DBWrite(WriteONDBNumber, WriteStart, 4, res); } } catch ( Exception e ) { LogHelper.Error("plc写入Float异常" + e.Message); } } public bool GetBitAt(byte[] buffs, int byteStart, int bitStart) { try { return buffs.GetBitAt(byteStart, bitStart); } catch ( Exception e ) { LogHelper.Error("提取bool异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } } public float GetRealAt(byte[] buffs, int byteStart) { try { return buffs.GetRealAt(byteStart); } catch ( Exception e ) { LogHelper.Error("提取float异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } } public short GetShortAt(byte[] buffs, int byteStart) { try { return buffs.GetIntAt(byteStart); } catch ( Exception e ) { LogHelper.Error("提取short异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } } public string GetStringAt(byte[] buffs, int byteStart) { try { return buffs.GetStringAt(byteStart); } catch ( Exception e ) { LogHelper.Error("提取float异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } } public TimeSpan GetTimeSpanAt(byte[] buffs, int byteStart) { try { return buffs.GetS7TimespanAt(byteStart); } catch ( Exception e ) { LogHelper.Error("提取TimeSpan异常" + e.Message); throw new TimeoutException‌("PLC读取异常"); } } // 参数说明:startByte-起始字节, startBit-起始位(0-7), bitCount-读取位数 int CalculateBytesToRead(int startByte, int startBit, int bitCount) { int totalBits = startByte * 8 + startBit + bitCount; // 全局结束位索引 int endByte = (totalBits - 1) / 8; // 结束字节索引(整数除法) return endByte - startByte + 1; // 需要读取的字节数 } bool[] ParseBoolArray(byte[] buffer, int startBit, int bitCount) { bool[] results = new bool[bitCount]; for ( int i = 0; i < bitCount; i++ ) { int globalBit = startBit + i; // 目标位全局偏移 int byteIndex = globalBit / 8; // 字节在buffer中的索引 int bitIndex = globalBit % 8; // 位在字节中的索引 results[ i ] = S7.GetBitAt(buffer, byteIndex, bitIndex); // 提取位值 } return results; } } }