1.Nuget 安装s7 驱动包
2.西门子plc定义一个db块,这个是我们上位机要读写的DB
3. 根据西门子S7 协议文档
3.1 读写类的原理,是通过反射处理的,不过我们并不需要关心它是如何反射的,我们只关心我们要如何使用。
3.2 首先,需要建立一个类,跟西门子 DB块 名称一样的实体类
4. 类建立完成,我们通过接口的方式实现读写数据
4.1 普通接口的实现
4.2 我们知道该方法的传入参数后,接着需要定义接口的方法。
4.3 接下来,调用该接口,就能获取到plc 的值了。
读取到的值跟西门子PLC DB5的值是一样的
5. 以上就是普通接口的实现方式,但如果我们是多个db块,按照常规是不是得写N个实现方法,这样不仅不容易维护,代码量也多。所以我们把接口设计成泛型的实现。
5.1 我们要设定接口约束类型。为什么要这样干,就是我们要让实现这个接口的类,规定它这个T类型,你不能传int 或string等,必须传个类给它。这样就防止,接口实现的时候,你传错参数了。
5.2 接着,我们实现这个泛型接口,那么这个t,我们就可以换成,我们跟Plc定义的数据块,建立的对应实体类了。
实现接口
5.3 调用接口。首先实例化CathodeEntity 实体类,把CathodeEntity传进去,得到的就是对应Db块5的值。如果是其他Db块,就需要建立跟plc db块名称对应的实体类,然后再CathodeEntity 换成要新建读取的类。这样就实现的接口方法复用。
6. 接口调用具体实现。
6.1 Plc 连接类,因为我只需要实例化一次,所以也要把它设计成了单例模式
/// <summary>
/// 正极缓存货架plc
/// </summary>
internal class CathodeBufferRack
{
//定义静态变量保存实例
public static volatile Plc CathodePlc;
//定义一个标识确保线程同步
private static object lockHelper = new object();
//定义私有变量,使外部不能创建该类实例
private CathodeBufferRack()
{
}
public static Plc Instance(string DeviceIp)
{
if(CathodePlc == null)
{
lock (lockHelper)
{
if (CathodePlc == null)
{
CathodePlc = new Plc(CpuType.S71200, DeviceIp, 0,1);
CathodePlc.Open();
if (!CathodePlc.IsConnected)
{
CathodePlc.Close();
CathodePlc = null;
}
}
}
}
return CathodePlc;
}
}
7. 写plc db也同样的道理。
7.1 定义写的接口方法
7.2 实现接口方法
7.3 程序调用
7.4 LeaveAllowed 实体更改成true后,传进去。plc驱动程序自动反射,把对应实体plc db块的值直接更新了。这样就不用通过偏移量来操作读写db块了。
7.5 PLC与C# 常用数据类型转换
PLC | C# |
Bool | Bool |
Word | ushort |
Int | ushort |
Dword | uint32 |
Dint | uint |
byte | byte |
Real |
bouble |
具体使用参考官网
8. 普通接口和泛型接口对比。
8.1 如下例子所示,普通接口固定死传入实体参数后,它就只能规定你传入CathodeEntity实体类对象。
那就先这样吧,理解了点赞收藏啊,防止那天找不到了。