概述
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。

