在C#中使用s7Netplus实现与西门子PLC的数据通信

在C#中使用s7Netplus实现与西门子PLC的数据通信

S7.Net Plus(简称s7Netplus)是一个开源的西门子PLC驱动程序,专为通过以太网连接与西门子PLC进行通信而设计。它完全用C#编写,使得开发者能够在不处理本地DLL的情况下轻松地进行调试。s7Netplus支持多种西门子PLC型号,包括S7-200、S7-300、S7-400、S7-1200和S7-1500。

如何获取s7Netplus

s7Netplus的官方代码库托管在GitHub上,地址为:

https://github.com/killnine/s7netplus。你也可以直接通过NuGet包管理器下载库:https://www.nuget.org/packages/S7netplus/。

s7Netplus的基本概念

在使用s7Netplus之前,你需要了解一些基本概念,包括CPU类型、IP地址、机架号和插槽号。这些概念将帮助你创建PLC实例并与之通信。

CPU类型(CpuType)

s7Netplus支持多种CPU类型,定义在一个名为CpuType的枚举中:

public enum CpuType
{
    S7200 = 0,
    Logo0BA8 = 1,
    S7200Smart = 2,
    S7300 = 10,
    S7400 = 20,
    S71200 = 30,
    S71500 = 40,
}

IP地址、机架号和插槽号

IP地址:PLC或外部以太网卡的IP地址。

机架号:PLC的机架号,可以在Step7的硬件配置中找到。

插槽号:CPU的插槽号,也可以在Step7的硬件配置中找到。

开始使用s7Netplus

  1. 创建PLC实例

要创建PLC实例,首先需要使用以下构造函数:

public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot)

例如,以下代码创建了一个连接到本地主机(IP地址为127.0.0.1)上机架0插槽2的S7-300 PLC的实例:

Plc plc = new Plc(CpuType.S7300, "127.0.0.1", 0, 2);
  1. 连接和断开PLC

连接到PLC使用Open方法,断开连接使用Close方法:

plc.Open();
// 执行操作...
plc.Close();
  1. 错误处理

Open方法返回一个ErrorCode枚举,用于检查操作是否成功。你应该始终检查它是否返回ErrorCode.NoError。

if (plc.Open() == ErrorCode.NoError)
{
	// 连接成功
}
else
{
	// 处理错误
}
  1. 读取和写入数据

s7Netplus提供了多种读取变量的方法。最基本的方法是ReadBytes和WriteBytes。

  1. 读取和写入字节
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)

例如,以下代码读取DB1的前200个字节:

var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 200);
  1. 读取和解码

如果你想要读取并直接得到解码后的结果,可以使用Read和Write方法。

public object Read(DataType dataType, int db, int startByteAdr, VarType varType, int count)
public ErrorCode Write(DataType dataType, int db, int startByteAdr, object value)

例如,以下代码读取DB1的前20个双字(DWords):

var dwords = plc.Read(DataType.DataBlock, 1, 0, VarType.DWord, 20);
  1. 读取和写入结构体

如果你想要读取或写入整个结构体,可以使用ReadStruct和WriteStruct方法。

public object ReadStruct(Type structType, int db, int startByteAdr = 0)
public ErrorCode WriteStruct(object structValue, int db, int startByteAdr = 0)

例如,假设你在PLC中定义了一个数据块,然后在.NET应用程序中添加了一个与之类似的结构体:

public struct TestStruct
{
	public bool varBool0;
// ... 其他字段 ...
}
// 从DataBlock 1读取结构体
TestStruct test = (TestStruct)plc.ReadStruct(typeof(TestStruct), 1);
  1. 读取和写入类

类似地,你可以使用ReadClass和WriteClass方法来读取和写入类。

public void ReadClass(object sourceClass, int db, int startByteAdr = 0)
public ErrorCode WriteClass(object classValue, int db, int startByteAdr = 0)

例如,假设你在PLC中定义了一个数据块,然后在.NET应用程序中添加了一个与之类似的类:

public class TestClass
{
	public bool varBool0 { get; set; }
	// ... 其他属性 ...
}
// 从DataBlock 1读取类
TestClass testClass = new TestClass();
plc.ReadClass(testClass, 1);
  1. 值转换

s7Netplus提供了一些辅助方法来转换C#和S7 PLC之间的值。

读取S7 Word:

ushort result = (ushort)plc.Read("DB1.DBW0");

写入S7 Word:

ushort val = 40000;
plc.Write("DB1.DBW0", val);

读取S7 DWord:

uint result = (uint)plc.Read("DB1.DBD40");

写入S7 DWord:

uint val = 1000;
plc.Write("DB1.DBD40", val);

下面是一个简单的C#示例,演示如何使用S7.Net与S7-300 PLC进行通信,使用之前,确保已经通过NuGet安装了S7netplus包。

using S7.Net;
using System;
class Program
{
    static void Main(string[] args)
    {
        Plc plc = new Plc(CpuType.S7300, "192.168.0.1", 0, 2);
        
        try
        {
            plc.Open();
            
            byte[] bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 200);
            
            ushort result = (ushort)plc.Read("DB1.DBW0");
            
            plc.Write("DB1.DBW0", (ushort)500);
            
            plc.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }
}

这个示例首先创建一个Plc对象,然后打开连接,读取DB1的前200个字节,读取DB1.DBW0变量,并将其写入DB1.DBW0,最后关闭连接。通过S7.Net库,可以轻松地实现与西门子PLC的以太网通信,无需了解底层的S7协议细节。

S7-1200/1500的注意事项

对于S7-1200/1500,外部设备只能使用S7 "base"协议访问CPU,且仅限于基本数据传输。所有其他PG操作(控制/目录等)必须遵循扩展协议,目前s7Netplus尚未支持。

结论

s7Netplus是一个功能强大的库,它使得与西门子PLC的通信变得简单而高效。通过上述示例,你可以在C#应用程序中轻松地实现与PLC的通信,无论是读取和写入单个变量,还是整个结构体或类的读写。s7Netplus的易用性和灵活性使其成为处理西门子PLC通信的优选工具。