0

0

0

修罗

站点介绍

只有了解事实才能获得真正的自由

C# S7.Net通信库使用

修罗 2023-02-03 782 0条评论 c#

首页 / 正文

S7通信协议是西门子S7系列PLC内部集成的一种通信协议,它是一种运行在传输层之上的(会话层/表示层/应用层)、经过特殊优化的通信协议,其信息传输可以基于MPI网络、PROFIBUS网络或者以太网。

S7.Net 通信库提供了S7协议通信的常用方法:创建、打开、关闭、读写数据。

S7.Net安装:右击项目---管理Nuget程序包----搜索S7.Net,选择S7netplus,安装即可。

创建连接

仿真设备环境:

image-20230203141953072.png

// ip地址 port端口号 rack机架号 0 slot插槽 1 cpuType 型号
string ip = "192.168.80.133";
int port = 102;
short rack = 0;
short slot = 1;

// 不同cpu型号机架号和插槽不一样
CpuType cpuType = CpuType.S71500;
//创建plc实例
plc = new Plc(cpuType, ip, port, rack, slot);

// 打开连接
if(plc != null) {
    plc.Open();
    
    // 读或写操作
    
    // 关闭连接
    plc.Close();
}

读数据

数据块定义的变量:

image-20230203150158561.png

IQM区定义的变量:

image-20230203150302848.png

plc中监控的数据:

image-20230203142619467.png

方式一:字符串地址读取

  • DB2.DBX0.0 按拉访问

DB2:数据块表名称。

访问方式:X(bit) 位,B(byte) 字节,W(word) 字,D(DWord) 双字。

0.0:第一个0是读取的字节的开始位置,偏移量值;第二个0是位的地址。

var val1=  plc.Read("DB2.DBX0.0"); // true
  • DB2.DBW6 按字访问
var val2 = plc.Read("DB2.DBW6"); // 120
  • DB2.DBX1.3 字节中按拉读取
var val3 = plc.Read("DB2.DBX1.3"); // true
  • DB2.DBD2 按双字读取
// 读float数据
var val4 = plc.Read("DB2.DBD2"); // 1104412672
// 转成byte[]
byte[] arrVal4=  BitConverter.GetBytes((uint)val4);
// byte[]转换成float
float f4 = BitConverter.ToSingle(arrVal4, 0); // 26.5
  • IQM区
// I区  I0.0
var val5 = plc.Read("I0.0"); // fale
// Q区  QW1
var val6 = plc.Read("QW1"); // 180
// M区 M0.3
var val7 = plc.Read("M0.3"); // true

方式二:Read(dataType,db,startaddr,count,bitaddr)

  • DB2.DBX0.0 按拉访问
var val9 = plc.Read(
    DataType.DataBlock, // 读取的存储区 db块
    2, // db的地址:db1即1,db2即2
    0, // 读取的字节的开始位置,偏移量值
    VarType.Bit, //读取单位:位  
    1, // 读取的数量
    0 // 如果读取单位是按位读取,位的地址
); // true
  • I0.0
var val10 = plc.Read(
    DataType.Input, // 读取的存储区 I区
    0, // 对于I、Q、M区这里传0
    0, // 读取的字节的开始位置,偏移量值
    VarType.Bit, //读取单位:位  
    1, // 读取的数量
    0  // 如果是按位读取,位的地址
); // false
  • QW1
var val11 = plc.Read(
    DataType.Output, // 读取的存储区 Q区
    0, // 对于I、Q、M区这里传0
    1, // 读取的字节的开始位置,偏移量值
    VarType.Word, //读取单位:字  
    1 // 读取的数量
); // 180
  • 读取数组中的两个值
var val12 = plc.Read(DataType.DataBlock, 2, 8, VarType.DWord, 2); // {0, 88}

字符串读取:

字符串第一个字节存的是总字节数,第二个字节存的是字符串长度

  • 读取:str1的总字节数和字符串长度
// 读取str1,str1在db区设置了默认值:study
// str1总字节数
var totalCount=  plc.Read(DataType.DataBlock, 2, 16, VarType.Byte, 1); // 254
// str1字符串长度
var lengthCount = plc.Read(DataType.DataBlock, 2, 17, VarType.Byte, 1); // 5
int length = Convert.ToInt32(lengthCount); // 转int // 5
  • 读取str1
string stateName = plc.Read(DataType.DataBlock, 2, 18, VarType.String, length).ToString(); // study
  • 读取中文字符串str2

中文字符串,一个占两字节,不能用上面方式读取

// 字符串长度
var lengthCount1 = plc.Read(DataType.DataBlock, 2, 273, VarType.Byte, 1);
int length1 = Convert.ToInt32(lengthCount1);

// ReadBytes
byte[] byteArr = plc.ReadBytes(DataType.DataBlock, 2, 274, length1);
string str02 = Encoding.Default.GetString(byteArr); // 哈哈

方式三:按字节读取

从偏移量528开始获取13个字节

byte[] arrList = plc.ReadBytes(DataType.DataBlock, 2, 528, 13);
  • count
// arrList01的值 [0] 0, [1] 100
byte[] arrList01 = arrList.Take(2).ToArray();

// 如果是数据放在字节数组后面的索引(有的操作系统这样,有的不一样)
if (BitConverter.IsLittleEndian)
    // 翻转再转无符号16位整数 [0] 100, [1] 0
    arrList01 = arrList01.Reverse().ToArray();

ushort count = BitConverter.ToUInt16(arrList01, 0); // 100
  • rcount
// arrList02:[0] 0, [1] 200
byte[] arrList02 = arrList.Skip(2).Take(2).ToArray();

if (BitConverter.IsLittleEndian)
    arrList02 = arrList02.Reverse().ToArray();

ushort rcount = BitConverter.ToUInt16(arrList02, 0); // 200

byte length = arrList[6];
byte[] arrlist03 = arrList.Skip(8).Take(length).ToArray();
string str02 = Encoding.Default.GetString(arrlist03);
  • strstr
byte[] arrlist03 = arrList.Skip(6).Take(5).ToArray();
string str02 = Encoding.Default.GetString(arrlist03); // study

方式四:ReadClass

新建数据模型

public class PlcData {
    // 属性顺序与db中的变量顺序一致
    public ushort Count { get; set; }
    public ushort RCount { get; set; }
}
  • ReadClass (model,db,startAddr)
PlcData data = new PlcData();
plc.ReadClass(data, 2, 524);
// 执行后:
// data.Count = 100,data.Count = 200
  • 或者用:ReadClass<model>(db,startAddr)
PlcData data1 = plc.ReadClass<PlcData>(2, 528);
// 执行后:
// data.Count = 100,data.Count = 200

写数据

方式一:字符串地址

  • Write("地址",value);
// 写bool值
plc.Write("DB2.DBX0.0", false);
plc.Write("I0.0", true);

// ushort 
ushort val = 800;
plc.Write("DB2.DBW528", val);

// uint
plc.Write("DB2.DBD12", 50);

// float 
float f1 = 28.5f;//浮点数
plc.Write("DB2.DBD2", f1);

如下图红框为修改后的值:

image-20230203153845263.png

第二种:Write(DataType,db,startAddr,value,[bitAddr]);

// DB2.DBX0.0
plc.Write(DataType.DataBlock, 2, 0, true, 0);

// QW1
ushort uVal = 280;
plc.Write(DataType.Output, 0, 1, uVal);

image-20230203154213398.png

第三种:Write(DataItem)、Write(DataItem[] )

//  M0.3
DataItem di = new DataItem();
// M区
di.DataType = DataType.Memory;
di.DB = 0;
di.StartByteAdr = 0;
di.BitAdr = 3;
di.Value = false;

// DBD12
int iVal = 88;
DataItem di1 = new DataItem();
di1.DataType = DataType.DataBlock;
di1.DB = 2;
di1.StartByteAdr = 12;
di1.Value = iVal;

// 写入
plc.Write(di, di1);

image-20230203154830813.png

评论(0)


最新评论

  • 1

    1

  • 1

    1

  • -1' OR 2+158-158-1=0+0+0+1 or 'TKCTZnRa'='

    1

  • 1

    1

  • 1

    1

  • 1

    1

  • 1

    1

  • @@5Qa2D

    1

  • 1

    1

  • 1

    1

日历

2025年09月

 123456
78910111213
14151617181920
21222324252627
282930    

文章目录

推荐关键字: Linux webpack js 算法 MongoDB laravel JAVA jquery javase redis