C#实现与西门子S7-1200/1500 PLC通信

C#实现与西门子S7-1200/1500 PLC通信,三种主流通信方式(S7协议、Modbus TCP、OPC UA)


一、S7协议通信(推荐)

1. 使用Sharp7库

// NuGet安装:Install-Package Sharp7
using Sharp7;

public class S7CommSharp7 {
    private S7Client _client = new S7Client();
    
    // 连接PLC
    public bool Connect(string ip, int rack=0, int slot=1) {
        int result = _client.ConnectTo(ip, rack, slot);
        return result == 0; // 返回连接状态
    }

    // 读取DB块数据(如DB1中前10字节)
    public byte[] ReadDB(int dbNumber, int start, int size) {
        byte[] buffer = new byte[size];
        int result = _client.DBRead(dbNumber, start, size, buffer);
        if (result != 0) throw new Exception($"读取失败,错误码:{result}");
        return buffer;
    }

    // 写入Int类型数据到DB块
    public void WriteInt(int dbNumber, int offset, int value) {
        byte[] buffer = new byte[2];
        S7.SetIntAt(buffer, 0, value);
        _client.DBWrite(dbNumber, offset, 2, buffer);
    }
}

关键配置


二、Modbus TCP通信

1. PLC配置

2. C#客户端实现

// NuGet安装:Install-Package NModbus4
using NModbus;

public class ModbusComm {
    private IModbusMaster _master;
    
    public void Connect(string ip, int port=502) {
        TcpClient tcpClient = new TcpClient(ip, port);
        _master = Modbus.Transport.CreateIp(tcpClient);
    }

    // 读取保持寄存器(如地址40001对应DB1.DBW0)
    public ushort[] ReadRegisters(byte slaveId, ushort startAddr, ushort count) {
        return _master.ReadHoldingRegisters(slaveId, startAddr, count);
    }

    // 写入浮点数(需转换为两个ushort)
    public void WriteFloat(byte slaveId, ushort startAddr, float value) {
        ushort[] data = BitConverter.GetBytes(value).ToUshortArray();
        _master.WriteMultipleRegisters(slaveId, startAddr, data);
    }
}

地址转换规则


三、OPC UA通信(跨平台推荐)

1. PLC端配置

  1. TIA Portal中启用OPC UA服务器:

    • PLC属性 → OPC UA → 激活服务器功能。
    • 配置安全策略(如用户名/密码)。
    • 发布变量(选择DB块中的Tag)。
  2. 记录PLC的OPC UA端点地址:opc.tcp://192.168.0.1:4840

2. C#客户端代码

// NuGet安装:Install-Package Opc.Ua.Client
using Opc.Ua.Client;

public class OpcUaComm {
    private Session _session;
    
    public void Connect(string endpointUrl) {
        ApplicationConfiguration config = new ApplicationConfiguration();
        var endpoint = new ConfiguredEndpoint(null, new EndpointDescription(endpointUrl));
        _session = Session.Create(config, endpoint).GetAwaiter().GetResult();
    }

    // 读取浮点数变量
    public float ReadFloat(string nodeId) {
        DataValue value = _session.ReadValue(nodeId);
        return (float)value.Value;
    }

    // 写入布尔值
    public void WriteBool(string nodeId, bool state) {
        _session.WriteValue(nodeId, state);
    }
}

节点ID示例


四、性能优化与错误处理

1. 异步读写(避免阻塞UI)

// Sharp7异步读取示例
public async Task<byte[]> ReadDBAsync(int dbNumber, int start, int size) {
    return await Task.Run(() => ReadDB(dbNumber, start, size));
}

2. 异常处理模板

try {
    plc.WriteInt(1, 0, 100);
} catch (Exception ex) {
    // 网络中断重连
    if (ex.Message.Contains("Connection refused")) {
        plc.Reconnect();
        plc.WriteInt(1, 0, 100); // 重试
    }
    // 记录日志
    Logger.Log($"写入失败:{ex.Message}");
}

3. 心跳监测

// 定时检查连接状态
Timer _heartbeatTimer = new Timer(_ => {
    if (!plc.IsConnected) plc.Connect();
}, null, 0, 5000); // 每5秒检测一次

参考代码 PC与西门子S7-1200 1500 C#通讯例程 www.youwenfan.com/contentalc/111882.html

总结

 

专注于matlab/simulink,电子电路,编程