西门子PLC S7.net中文文档
如何下载s7.Net
官方存储库位于GitHub上(https://github.com/killnine/s7netplus),你也可以下载直接从NuGet获得的库
(https://www.nuget.org/packages/S7netplus/).
什么是S7.Net
S7.Net是一种plc驱动程序,仅适用于西门子plc和以太网连接。
这意味着您的plc必须具有Profinet CPU或Profinet外部卡(CPxxx卡)。
S7.Net完全是用C#编写的,因此您可以轻松地调试它,而无需使用本机DLL。
支持的PLC
S7.Net与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机架,可在第7步的硬件配置中找到
slot:这是CPU的插槽,您可以在步骤7的硬件配置中找到
例子:
此代码为IP地址为127.0.0.1的S7-300 Plc创建一个Plc对象,即本地主机,用于
它位于机架0中,cpu位于硬件配置的插槽2中:
Plc plc = new Plc(CpuType.S7300, "127.0.0.1", 0, 2);
连接到PLC:
public ErrorCode Open()
For example this line of code open the connection:
plc.Open();
断开与PLC的连接
public void Close()
For example this closes the connection:
plc.Close();
错误处理:
Open()方法返回一个错误代码以检查操作是否成功。你应该永远检查它是否返回ErrorCode.NoError。以下是错误的类型:
public enum ErrorCode
{
NoError = 0,
WrongCPU_Type = 1,
ConnectionError = 2,
IPAddressNotAvailable,
WrongVarFormat = 10,
WrongNumberReceivedBytes = 11,
SendData = 20,
ReadData = 30,
WriteData = 50
}
全局错误处理
并非所有方法都返回错误。你可以查一下
public ErrorCode LastErrorCode and public string LastErrorString
在您执行的每个方法上,以便在运行驱动程序时捕获错误。
检查PLC的可用性
要检查plc是否可用,可以使用属性
public bool IsAvailable
当您检查此属性时,驱动程序将向plc发送ping并在plc响应时返回ping true,否则为假。
检查PLC连接
检查plc连接很简单,因为您必须检查PC插座是否已连接,以及PLC仍处于连接状态
在这种情况下,您必须检查的属性如下:
public bool IsConnected
调用方法Open()后,可以检查此属性,以检查连接是否仍处于活动状态。
读字节/写字节
该库提供了几种读取变量的方法。最基本也是最常用的是ReadBytes。
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
这将从您确定的内存位置读取最多200个字节(协议的实际限制)。
dataType:必须使用枚举数据类型指定内存位置
public enum DataType
{
Input = 129,
Output = 130,
Memory = 131,
DataBlock = 132,
Timer = 29,
Counter = 28
}
db:这是数据类型的地址,例如,如果要读取DB1,则此字段为“1”;如果你要读取T45,此字段为45
startByteAdr:这是要读取的第一个字节的地址,例如,如果要读取DB1.DBW200,这是200.
count:这包含要读取的字节数。限制为200字节,如果需要此外,必须使用递归.
Value[]: 要写入plc的字节数组。
例子:
此方法读取DB1的前200个字节:
var bytes = plc.ReadBytes(DataType.DataBlock, 1,0,200);
递归示例:
private List<byte> ReadMultipleBytes(int numBytes, int db, int startByteAdr = 0)
{
List<byte> resultBytes = new List<byte>();
int index = startByteAdr;
while (numBytes > 0)
{
var maxToRead = (int)Math.Min(numBytes, 200);
byte[] bytes = ReadBytes (DataType.DataBlock, db, index, (int)maxToRead);
if (bytes == null)
return new List<byte>();
resultBytes.AddRange(bytes);
numBytes -= maxToRead;
index += maxToRead;
}
return resultBytes;
}
读和解码/写解码
此方法允许根据提供的varType读取和接收已解码的结果。这是如果读取多个相同类型的字段(例如,20个连续DBW),则此选项非常有用。这也仅限于最多200字节。如果指定VarType.Byte,则其功能与ReadBytes相同.
public object Read(DataType dataType, int db, int startByteAdr, VarType varType, int va
rCount)
public ErrorCode Write(DataType dataType, int db, int startByteAdr, object value)
dataType:必须使用枚举数据类型指定内存位置
public enum DataType
{
Input = 129,
Output = 130,
Memory = 131,
DataBlock = 132,
Timer = 29,
Counter = 28
}
db:这是数据类型的地址,例如,如果要读取DB1,则此字段为“1”;如果你要读取T45,此字段为45。
startByteAdr:这是要读取的第一个字节的地址,例如,如果要读取DB1.DBW200,这是200
varType:指定要转换字节的数据。
public enum VarType
{
Bit,
Byte,
Word,
DWord,
Int,
DInt,
Real,
String,
Timer,
Counter
}
Count:这包含要读取的变量数限制为200字节,如果需要更多,必须使用递归。
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 ErrorCode 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 ErrorCode WriteStruct(object structValue, int db, int startByteAdr = 0)
structType:要读取的结构的类型,例如:typeOf(MyStruct))
Db:要读取的数据库的索引
startByteAdr :指定要读取的字节的第一个地址(默认值为零)。
例子:
在plc中定义数据块,如:
然后在.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 double varReal0;
public bool varBool7;
public double varReal1;
public byte varByte2;
public UInt32 varDWord;
}
然后添加代码以读取或写入完整的结构
testStruct test = (testStruct)plc.ReadStruct(typeof(testStruct), 1);
读 class/写class
此方法从指定的DB中读取填充C#中的类所需的所有字节.类作为引用传递,并使用反射指定值
public void ReadClass(object sourceClass, int db, int startByteAdr = 0)
public ErrorCode WriteClass(object classValue, int db, int startByteAdr = 0)
sourceClass:要指定值的类的实例
Db:要读取的数据库的索引
startByteAdr :指定要读取的字节的第一个地址(默认值为零)
例子:在plc中定义数据块,如:
然后在.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 double varReal0 { get; set;}
public bool varBool7 { get; set;}
public double varReal1 { get; set;}
public byte varByte2 { get; set;}
public UInt32 varDWord { get; set;}
}
然后添加代码以读取或写入完整的结构:
TestClass testClass = new TestClass();
plc.ReadClass(testClass, 1);
C#和S7 plc之间的值转换
· Read S7 Word:
ushort result = (ushort)plc.Read("DB1.DBW0");
· Write S7 Word:
ushort val = 40000;
plc.Write("DB1.DBW0", val);
· Read S7 Int / Dec, you need to use the method ConvertToShort():
short result = ((ushort)plc.Read("DB1.DBW0")).ConvertToShort();
· Write S7 Int / Dec, you need to use the method ConvertToUshort():
short value = -100;
plc.Write("DB1.DBW0", value.ConvertToUshort());
· Read S7 DWord:
uint result = (uint)plc.Read("DB1.DBD40");
· Write S7 DWord:
uint val = 1000;
plc.Write("DB1.DBD40", val);
· Read S7 Dint, you need to use ConvertToInt():
int result2 = ((uint)plc.Read("DB1.DBD60")).ConvertToInt();
· Write S7 Dint:
int value = -60000;
plc.Write("DB1.DBD60", value);
· Read S7 Real, you need to use ConvertToDouble():
double result = ((uint)plc.Read("DB1.DBD40")).ConvertToDouble();
· Write S7 Real, you need to use ConvertToInt():
double val = 35.687;
plc.Write("DB1.DBD40", val.ConvertToUInt());
· Read bool from byte
byte myByte = 5; // 0000 0101
myByte.SelectBit(0) // true
myByte.SelectBit(1)
这直接取自Snap7文档:http://snap7.sourceforge.net/
S7 1200/1500 Notes
外部设备可以使用S7“base”访问S71200/1500 CPU协议,仅作为HMI工作,即仅允许基本数据传输。
所有其他PG操作(控制/目录等)必须遵循扩展协议,Snap7尚未(尚未)涵盖。
特别是要访问S71500中的DB,需要一些额外的设置plc侧。
1.只能访问全局数据库
2.必须关闭优化的块访问
3.访问级别必须为“完全”,并且“连接机制”必须允许GET/PUT.
让我们在TIA Portal V12中查看这些设置
DB property
在左窗格中的“程序块”下选择数据库,然后按Alt Enter键(或在上下文菜单中选择“属性…”)
取消选中“优化块访问”,默认情况下,它处于选中状态。
Protection
在左窗格中选择CPU项目,然后按Alt Enter键(或在上下文菜单中)菜单选择“属性…”)
在项目保护中,选择“完全访问”并选中“允许使用PUT/GET访问”..“如图所示。