概述
S7.Net是一个专为西门子PLC设计的PLC驱动程序,仅支持通过以太网连接。这意味着您的PLC必须具备Profinet CPU或Profinet外部卡(如CPxxx卡)。S7.Net完全使用C#编写,因此您可以轻松地进行调试,而无需处理本地DLL。
支持的PLC型号
S7.Net与以下型号的西门子PLC兼容:S7-200、S7-300、S7-400、S7-1200和S7-1500。
开始使用S7.Net
要开始使用S7.Net,您需要下载并包含S7.Net.dll到您的项目中。您可以通过下载NuGet包或下载源代码并编译来实现。
创建PLC实例、连接与断开
创建驱动程序实例时,您需要使用以下构造函数:
public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot)
cpu
:指定您要连接的CPU类型。支持的CPU类型有:
public enum CpuType { S7200 = 0, S7300 = 10, S7400 = 20, S71200 = 30, S71500 = 40, }
ip
:指定CPU或外部以太网卡的IP地址。rack
:包含PLC的机架号,您可以在Step7的硬件配置中找到。slot
:这是CPU的插槽号,同样可以在Step7的硬件配置中找到。
例如,以下代码为IP地址为127.0.0.1的S7-300 PLC创建了一个PLC对象,PLC位于0号机架,CPU位于2号插槽:
Plc plc = new Plc(CpuType.S7300, "127.0.0.1", 0, 2);
连接到PLC
public void Open()
例如,以下代码行打开连接:
plc.Open();
从PLC断开连接
public void Close()
例如,以下代码关闭连接:
plc.Close();
错误处理
任何方法都可能因为各种错误而引发PlcException
。您应该实现适当的错误处理。PlcException
提供了一个ErrorCode
和一个适当的错误消息。
以下是错误类型的枚举:
public enum ErrorCode { NoError = 0, WrongCPU_Type = 1, ConnectionError = 2, IPAddressNotAvailable, WrongVarFormat = 10, WrongNumberReceivedBytes = 11, SendData = 20, ReadData = 30, WriteData = 50 }
检查PLC可用性
要检查PLC是否可用(打开一个Socket),您可以使用属性:
public bool IsAvailable
当您检查此属性时,驱动程序将尝试连接到PLC,并在能够连接时返回true,否则返回false。
检查PLC连接
检查PLC连接很简单,因为您需要检查PC套接字是否已连接,还要检查PLC是否仍然连接在套接字的另一端。在这种情况下,您需要检查的属性是:
public bool IsConnected
您可以在调用Open()
方法并成功后检查此属性,以查看连接是否仍然活跃。
读取字节/写入字节
该库提供了多种读取变量的方法。最基本且最常用的方法是ReadBytes
。
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count) public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
此方法从给定的内存位置读取您指定的所有字节。如果字节数超过了单次请求可以传输的最大字节数,此方法会自动处理多个请求。
dataType
:您必须使用枚举DataType
指定内存位置:
public enum DataType { Input = 129, Output = 130, Memory = 131, DataBlock = 132, Timer = 29, Counter = 28 }
db
:dataType的地址,例如,如果您想读取DB1,则此字段为“1”;如果您想读取T45,则此字段为45。startByteAdr
:您要读取的第一个字节的地址,例如,如果您想读取DB1.DBW200,则此为200。count
:包含您想要读取的字节数。value[]
:要从PLC读取的字节数组。
示例:此方法读取DB1的前200个字节:
var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 200);
读取和解码/写入已解码
此方法允许您读取并接收基于提供的varType的已解码结果。这在您读取多个相同类型的字段时非常有用(例如20个连续的DBW)。如果您指定VarType.Byte,它与ReadBytes具有相同的功能。
public object Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount) public void Write(DataType dataType, int db, int startByteAdr, object value)
dataType
:您必须使用枚举DataType
指定内存位置。db
:dataType的地址,例如,如果您想读取DB1,则此字段为“1”;如果您想读取T45,则此字段为45。startByteAdr
:您要读取的第一个字节的地址,例如,如果您想读取DB1.DBW200,则此为200。varType
:指定您想要将字节转换为的数据。
public enum VarType { Bit, Byte, Word, DWord, Int, DInt, Real, String, StringEx, Timer, Counter }
count
:包含您想要读取的变量数量。value
:要写入PLC的值数组。它可以是单个值或数组,只是请记住类型是唯一的(例如,double数组,int数组,shorts数组等)。
示例:此方法读取DB1的前20个DWord:
var dwords = plc.Read(DataType.DataBlock, 1, 0, VarType.DWord, 20);
读取单个变量/写入单个变量
此方法通过解析字符串并返回正确的结果,从PLC读取单个变量。虽然这是最简单的入门方法,但由于驱动程序为每个变量发送TCP请求,因此非常低效。
public object Read(string variable) public void Write(string variable, object value)
variable
:通过使用字符串如“DB1.DBW20”,“T45”,“C21”,“DB1.DBD400”等来指定要读取的变量。
示例:这读取变量DB1.DBW0。结果必须转换为ushort以获得C#中正确的16位格式。
ushort result = (ushort)plc.Read("DB1.DBW0");
读取结构体/写入结构体
此方法从指定的DB读取所有字节,以填充C#中的结构体,并返回包含值的结构体。当您想要读取单个数据块中的多个变量时,建议使用它。
“读取结构体”和“写入结构体”方法不支持字符串。
public object ReadStruct(Type structType, int db, int startByteAdr = 0) public void WriteStruct(object structValue, int db, int startByteAdr = 0)
structType
:要读取的结构体类型,例如:typeof(MyStruct)db
:要读取的DB的索引startByteAdr
:指定要读取的字节的第一个地址(默认为零)。
示例:在PLC中定义一个DataBlock,然后在.Net应用程序中添加一个类似于PLC中DB的结构体:
public struct testStruct { public bool varBool0; public bool varBool1; public bool varBool2; public bool varBool3; public bool varBool4; public bool varBool5; public bool varBool6; public byte varByte0; public byte varByte1; public ushort varWord0; public float varReal0; public bool varBool7; public float varReal1; public byte varByte2; public UInt32 varDWord; }
然后添加代码以读取或写入完整的结构体:
// 从起始地址0读取DataBlock 1中的结构体 testStruct myTestStruct = (testStruct) plc.ReadStruct(typeof(testStruct), 1, 0);
**读取类/写
入类**
此方法从指定的DB读取所有字节,以填充C#中的类。类作为引用传递,使用反射分配值。当您想要读取单个数据块中的多个变量时,建议使用它。
“读取类”和“写入类”方法不支持字符串。
public void ReadClass(object sourceClass, int db, int startByteAdr = 0) public void WriteClass(object classValue, int db, int startByteAdr = 0)
sourceClass
:您想要分配值的类的实例db
:要读取的DB的索引startByteAdr
:指定要读取的字节的第一个地址(默认为零)。
示例:在PLC中定义一个DataBlock,然后在.Net应用程序中添加一个类似于PLC中DB的类:
public class TestClass { public bool varBool0 { get; set;} public bool varBool1 { get; set;} public bool varBool2 { get; set;} public bool varBool3 { get; set;} public bool varBool4 { get; set;} public bool varBool5 { get; set;} public bool varBool6 { get; set;} public byte varByte0 { get; set;} public byte varByte1 { get; set;} public ushort varWord0 { get; set;} public float varReal0 { get; set;} public bool varBool7 { get; set;} public float varReal1 { get; set;} public byte varByte2 { get; set;} public UInt32 varDWord { get; set;} }
然后添加代码以读取或写入完整的类:
// 从起始地址0读取DataBlock 1中的类 TestClass myTestClass = new TestClass(); plc.ReadClass(myTestClass, 1, 0);
读取多个变量
此方法在单个请求中读取多个变量。变量可以位于相同或不同的数据块中。
public void Plc.ReadMultibleVars(List<DataItem> dataItems);
List<>
:您必须指定包含所有要读取的数据项的DataItem列表。
示例:此方法从数据块中读取几个变量:
首先定义数据项:
private static DataItem varBit = new DataItem() { DataType = DataType.DataBlock, VarType = VarType.Bit, DB = 83, BitAdr = 0, Count = 1, StartByteAdr = 0, Value = new object() };
…(中间省略了与上文重复的数据项定义)
然后定义一个列表来存储DataItems:
private static List<DataItem> dataItemsRead = new List<DataItem>();
将数据项添加到列表中:
dataItemsRead.Add(varBit); dataItemsRead.Add(varByteArray); dataItemsRead.Add(varInt); dataItemsRead.Add(varReal); dataItemsRead.Add(varString); dataItemsRead.Add(varDateTime);
打开PLC连接并立即读取项目列表:
myPLC.Open(); // 读取变量列表 myPLC.ReadMultipleVars(dataItemsRead); // 关闭连接 myPLC.Close(); // 访问列表的值 Console.WriteLine("Int:" + dataItemsRead[2].Value);
写入多个变量
此方法在单个请求中写入多个变量。
public void Plc.Write(Array[DataItem] dataItems);
Array[]
您必须指定包含所有要写入的项目的DataItem数组。
示例:此方法将多个变量写入一个数据块:
定义数据项:
private static DataItem varWordWrite = new DataItem() { // ... (与上文重复的数据项定义省略) };
…(中间省略了与上文重复的数据项定义)
为数据项分配值。注意使用正确的数据转换,以适应S7数据类型:
varWordWrite.Value = (ushort)67; varIntWrite.Value = (ushort)33; varDWordWrite.Value = (uint)444; varDIntWrite.Value = 6666; varRealWrite.Value = 77.89; varStringWrite.Value = "Writting";
然后定义一个列表来存储数据项,并将创建的项目添加到列表中:
private static List<DataItem> dataItemsWrite = new List<DataItem>(); // 将数据项添加到要写入的数据项列表中 dataItemsWrite.Add(varWordWrite); dataItemsWrite.Add(varIntWrite); dataItemsWrite.Add(varDWordWrite); dataItemsWrite.Add(varDIntWrite); dataItemsWrite.Add(varRealWrite); dataItemsWrite.Add(varStringWrite);
最后,打开PLC连接并一次性写入项目。使用.ToArray()将列表转换为数组:
// 打开连接 myPLC.Open(); // 写入项目 myPLC.Write(dataItemsWrite.ToArray()); // 关闭连接 myPLC.Close();
这篇文章提供了S7.Net软件的详细介绍,包括其功能、如何开始使用、如何创建PLC实例、连接与断开、错误处理、检查PLC的可用性和连接状态、读取和写入字节、读取和写入结构体和类、以及如何一次性读取和写入多个变量。希望这篇文章能帮助您更好地了解S7.Net。