TIA博途(V19)ModbusTCP仿真与S7NetPlus库的基本使用心得(二)

1,406 阅读6分钟

S7NetPlus库的基本使用

在使用库之前,还需要在博途V19中,添加一个新的DB块,再定义几个常用类型的数据,并设定好初始值,方便后续的使用;完成之后,还要在新的DB块上右键“属性”,取消勾选“优化块的访问”,之后再点击“编译”按钮,才能显示“偏移量”。(每次启动博途V19后,DB块中的偏移量都不显示,所以启动后还需要手动勾选“优化块的访问”,再取消勾选,才会显示)

TIA DB3.png

首先肯定是实例化一个PLC的类,在实例化的时候,需要几个参数:CpuType选择1500,IP地址就是仿真PLC中接口上的地址,后两个就默认0和1;之后就可以用实例中的Open()开启连接,实例中的属性IsConnected可以判断当前连接的状态是否为True,而Close()方法则是关闭连接:

Plc plcObj = new Plc(CpuType.S71500,"192.168.1.8",0,1);

try{
    plcObj.Open();
    if(plc.IsConnected){console.WriteLine("连接成功")}
    //
    //...
    //
}
catch(Exception ex){
    console.WriteLine("错误信息"+ ex.Message);
}
finally{
    plcObj.Close();
}
  • 对单个数据的读写

TIA数据.png

plcObj.Read()方法的重载提供了以字符串的形式写地址即可读出数据的方法,比如这里想要读取DB3中一个数据类型为Word中的数据: plcObj.Read("DB3.DBW2");

65535.png

这种方法虽然方便,但能访问的类型有限(只有bit,Byte,Worsd,DWord),面对WString或Real类型以及带符号的int类型则不能直接读取。

plcObj.Read()另一个重载方法,提供了更多类型选择的读取方法: plcObj.Read(DataType.DataBlock,3,10,VarType.DInt,1); (最后还有一个参数是位地址,默认BitAdr = 0)

DataType是个枚举类型,存储在DB块的数据可以选择DataType.DataBlock,当然还可以选择DataType.Input/DataType.Output/DataType.Memory,只是在选择Input/Output/Memory时,第二个参数DB块的序号填0即可,参数四VarType是个枚举类型,对应要读取的数据类型:

-420000.png

  • 多个数据的读写

S7NetPlus库还提供了一次读取多个数据的方法plcObj.ReadMultipleVars(); 这个方法只有参数是一个DataItem类型的List,具体使用方法是需要先声明DataItem类型的实例,实例有相应的属性(包括,DataType/DB/VarType/StartByteAdr/Count/BitAdr/Value),读取几个数据,就要实例化几个DataItem,并配置好相应的属性,之后用List.Add()方法将所有的DataItem实例添加进去,最后通过.ReadMultipleVars()方法可以将数据传递给DataItem属性中的Value值中:

List<DataItem> dataItems = new List<DataItem>();

DataItem DI00 = new DataItem(){
    DataType = DataType.DataBlock,
    DB = 3,
    VarType = VarType.LReal,
    StartByteAdr = 786,
    Count =1,
    Value = new Object()
};

DataItem DI01 = new DataItem(){
    DataType = DataType.DataBlock,
    DB = 3,
    VarType = VarType.DWord,
    StartByteAdr = 4,
    Count =1,
    Value = new Object()
};

DataItem DI02 = new DataItem(){
    DataType = DataType.DataBlock,
    DB = 3,
    VarType = VarType.Bit,
    StartByteAdr = 0,
    BitAdr = 0,
    Count =1,
    Value = new Object()
};

dataItems.Add(DI00);
dataItems.Add(DI01);
dataItems.Add(DI02);

plcObj.ReadMultipleVars(dataItems);

//最后可以通过DataItems[索引].Value 的方式得到读取的数据

读取多个.png

.Read();方法同样可以读取多个连续的同类型数值,比如PLC中的Word数组:

读数组.png

  • 写入单个数据

plcObj.Write();方法提供了两个重载既可以对单个也可以对多个数据进行写入操作,以字符串的形式直接写数据地址(如DB1.DBW100);第二个重载,则是在前一个基础上提供了更具体的操作plcObj.Write(DataType.DataBlock,3,782,value,-1)最后一个参数为BitAdr 默认为 -1,参数3为Object类型的Value,需要提前声明好与PLC中对应的数据类型,才可以正确写入:

单个写入.png

  • 写入多个数据

.WriteMultipleVars()方法,需要一个DataItem类型的数组,将每个DataItem实例成员中的Value属性赋值,这里要用到S7NetPlus库中的数据类型转换,使Value的类型与PLC中的类型对应(C#中,没办法直接将变量类型转换成PLC中的数据类型,需要将变量转换成字节数据):

TIA 写多个.png (PS:1,对于PLC数据类型Bit,在DataItem的属性Value中直接赋值true或false; 2,虽然西门子PLC中的数据类型几乎都能在C#中找到想对应的数据类型,不过为了转换的安全,且.Write()/.WriteMultipleVars()方法中的参数value的类型是Object,所以可以转换成PLC中的类型(字节数组)再赋值给value,例如:value = DWord.ToByteArray(uintData);

  • S7String与S7WString数据的处理

在读取PLC中string或Wstring数据时,不管是用单个读取方法或多个读取方法都需要事先知道字符串的实际字符数量,然后在读取时把实际字符数量写在Count参数中,否则是读不出来的。而实际字符数量在西门子PLC S7-1500里,存储在第一个Word的低8位中,先使用plcObj.Read()方法,参数VarType设置为Word,之后进行简单的位运算,就可以拿到字符串的实际字符数量(而S7WString类型,则是存储在第一个DWord的低16位的低8位中):
// 读S7String类型:
ushort firstWord = (ushort)plcObj.Read(DataType.DataBlock,3,14,VarType.Word,1);
byte strLength = (byte)(firstWord & 0XFF);
//或者不进行位运算,直接强转 (byte)firstWord;

plcObj.Read(DataType.DataBlock,3,14,VarType.S7String,strLength);


// 读S7WString类型:
uint firstDW = (uint)plcObj.Read(DataType.DataBlock,3,270,VarType.DWord,1);
byte wsLength = (byte)(firstDW & 0XFF);
//或者不进行位运算,直接强转 (byte)firstDW;
plcObj.Read(DataType.DataBlock,3,270,VarType.S7WString,wsLength);

TIA字符串.png

在读取多个数据时,操作对象是S7String或S7WString,仍然需要先获得实际字符数量,再赋值到DataItem实例的Count属性中。(PS:其实不想获得“实际字符数量”,直接Count = 254,不怕浪费空间的话这么写也不是不行。)

对西门子PLC中的字符串数据类型(String/WString)写入操作时,需要将C#中字符串类型转换成西门子PLC中对应的String/WString类型,进行转换时,仍然需要知道要写入的字符串长度,在PLC与C#交互时,String通常被理解为使用ASCII编码的字符序列,而WString则是Unicode编码的字符序列,所以在获取写入字符串长度时,也要注意二者的区别:
//往PLC中写入S7string类型数据
string str = "testS7String!";
int StrLen = Encoding.ASCII.GetByteCount(str);

var s7strArray = S7String.ToByteArray(str,StrLen);
plcObj.Write(DataType.DataBlock,3,14,s7strArray);

//往PLC中写入S7WString类型数据
string wstr = "这是一条测试数据";
int wstrLen = Encoding.Unicode.GetByteCount(wstr);

var ws7strArray = S7WString.ToByteArray(wstr,wstrLen);
plcObj.Write(DataType.DataBlock,3,270,ws7strArray);

写入string.png


Tips:前面提到在读取string/Wstring类型时,可以图省事不先取“字符串实际长度”,直接将Count属性(或参数)设置为254,抛开浪费空间不说,因为.ReadMultipleVars();方法一次性读取的最大字节长度为960(string类型一个字占2 Byte,Wstring类型一个字占4 Byte),所以在读多个string/Wstring类型时,要么压根避免这种情况,要么还是老老实实的把“字符串实际长度”求出来。

  • 本节完

第一部分【TIA博途V19 ModbusTCP仿真】

第三部分【S7NetPlus库的基本使用心得(三)】