最近因为工作的原因用到了西门子PLC,在使用过程中一直在思考上位机和PLC的通讯问题,后来上网查了一下,找到了一个专门针对S7开发的一个.net库–《S7netPlus》,PLC通讯方法比较多,所以也是在不断地学习中,以下内容如有不足之处,望大神予以指教。

公司设备一直都用的PLC做下端设备的控制,但是目前都没有专职做上位机的,而我之前对PLC又接触的比较少,做起来还是比较难的。。

查找了一堆资料后,终于找到了这个.net库,在大致学习了一下之后,总结了一下,当作自己的学习笔记。

一、开发环境准备

最近因为疫情的影响,只能呆在总公司混日子,手里没有设备,只能用博图的仿真器来测试通讯,需要安装的软件包括:

  • Visual Studio 2015
  • TIA Portal V15
  • S7-PLCSIMV15
  • NetToPLCSIM-S7
    这里先放个下载连接:S7Net.dll、NetToPLCSIM、S7Net使用手册

TIA Protal(博图)&S7-PLCSIM

西门子针对于PLC专门开发的一款编程软件,相信各位肯定比我熟悉这个软件了,这里就不作过多介绍了,同时提供了S7系列的仿真软件S7-PLCSIM,这里我们就用这两个设备仿真PLC设备来测试S7NETPlus库的通讯。

博图V15.1

S7-PLCSIM

NetToPLCSIM

这个软件是用于将西门子的PLCsim映射到网络内,如果之前没有用过这个软件,建议按照后面的操作来,否则很容易出现Start server之后还是连不上仿真器。

二、开发测试

PLC配置

1、在组态好的PLC设备属性中,找到“防护与安全”–>“连接机制”中,勾选“允许来自远程对象的PUT/GET通信访问”;

2、新建DB块,同时将该DB快属性中的“优化块的访问取消”;

3、在新建的DB块中新增一些数据,完成后点击编译计算偏移量。

4、以上步骤完成后,点击开始仿真,将工程下载到仿真器中;

NetToPLCSIM配置

1、打开软件后,点击Add增加设备

2、在弹出的窗口中,Network IP Address中填入本地回环IP“127.0.0.1”(如果你是在两台设备中测试,首先保证两台设备在同一个内网中,该处IP就可以设置为运行仿真环境的IP了)

3、Plcsim IP Address中,点击后面两个点,选择软件自己识别出来的仿真器地址;

4、Plcsim Rack/Slot中Rack为机架号,Slot为插槽号,这两个可以在PLC的设备组态属性->项目信息中找到

配置完成后点击完成,这时候就可以点击Start Server开启服务了。

上面的操作一定要按照以上的步骤一步一步完成,否则很容易出现即使点Start Server显示状态为running,但是实际连接仍然连不上的情况。

另外需要注意的是,可能在打开NetToPLCSim的时候,会弹出“Port 102 is in use!”的警告,如果遇到这个情况,点击是,之后在将PLCSIM关掉重新启动一下就可以了。

创建连接

配置连接

这里使用的是S7-1215的模块,所以CpuType选择S71200,IP地址使用回环地址“127.0.0.1”,机架号和插槽号在PLC工程中查。

using S7.Net;Plc plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1);

配置完成后,使用Open()来打开,在最早的一个版本中,Open有返回值,可以通过返回值获取 ErrorCode 和 ErrorMessage,我目前使用的是最新版0.8.1.0,没有返回值,所以用try…catch来接收异常

try
{plc.Open();
}
catch(Exception)
{Console.WriteLine($"连接到PLC设备失败:IsConnect = {plc.IsConnected},IsAvailable={plc.IsAvailable}");return;
}

连接是否成功,可以用IsConnected去判断一下。

访问数据块

连接成功后,我们就可以去访问PLC的数据块了,访问数据块,我们先尝试一下读取数据块

读取单个数据–Read

这里主要用到了DBX,DBW,DBD读取数据,其他的各位可以在查一下PLC的资料

/*
方法:public object Read(string variable)
入参:读取数据地址
出参:Object类型数据,可强制类型转换
*/
var db1Bool1 = plc.Read("DB1.DBX0.0");
Console.WriteLine("DB1.DBX0.0:" + db1Bool1);bool db1Bool2 = (bool)plc.Read("DB1.DBX0.1");
Console.WriteLine("DB1.DBX0.1:" + db1Bool2);int IntVariable = (ushort)plc.Read("DB1.DBW2.0");
Console.WriteLine("DB1.DBW2.0:" + IntVariable);float RealVariable = ((uint)plc.Read("DB1.DBD4.0")).ConvertToFloat();
Console.WriteLine("DB1.DBD4.0:" + RealVariable);var dIntVariable = (uint)plc.Read("DB1.DBD8.0");
Console.WriteLine("DB1.DBD8.0: " + dIntVariable);var dWordVariable = (uint)plc.Read("DB1.DBD12.0");
Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));var wordVariable = (ushort)plc.Read("DB1.DBW16.0");
Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable,16));

读取批量数据块–ReadBytes
/*
方法:public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
入参:1、DataType数据类型,可选择从DB块或者Memory中读取;2、db:1:DataBlock=1,Memory=0;3、startByteAdr:起始地址,即DB块的起始偏移量;4、count:读取大小,该大小由读取的DB块的最后一个数据的偏移量和大小决定,这里最后一个字节WordVariable偏移量为16,数据类型为word,2个字节,因此此次读取为16+2=18个字节。
出参:Byte[],这里Byte[]的大小必然和count的大小是相同的,
*/
//读取数据选择从DB块中读取,db设置为1,起始地址为0,读取18个字节
var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 18);
//取字节0中的第0位
var db1Bool1 = bytes[0].SelectBit(0);
Console.WriteLine("DB1.DBX0.0:" + db1Bool1);
//取字节0中的第1位
bool db1Bool2 = bytes[0].SelectBit(1); ;
Console.WriteLine("DB1.DBX0.1:" + db1Bool2);
//跳到字节2并连续取两个字节数据
int IntVariable = S7.Net.Types.Int.FromByteArray(bytes.Skip(2).Take(2).ToArray());
Console.WriteLine("DB1.DBW2.0:" + IntVariable);
//...
double RealVariable = S7.Net.Types.Real.FromByteArray(bytes.Skip(4).Take(4).ToArray());
Console.WriteLine("DB1.DBD4.0:" + RealVariable);
//...
int dIntVariable = S7.Net.Types.DInt.FromByteArray(bytes.Skip(8).Take(4).ToArray());
Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
//...
uint dWordVariable = S7.Net.Types.DWord.FromByteArray(bytes.Skip(12).Take(4).ToArray());
Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));
//...
ushort wordVariable = S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray());
Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable, 16));

写入单个数据–Write
/*
方法:public void Write(string variable, object value)
入参:1、string variable:写入地址2、object value,写入数据
*/
plc.Write("DB1.DBX0.0", true);
plc.Write("DB1.DBD12.0", 123457);

写入多个数据–WriteBytes
/*
public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
用法如同ReadBytes,这里就不在写例程了,有兴趣的可以自己研究一下
*/
读写字符串–String与S7String

有人问到用S7.net读写字符串,大概试验了一下,两种方法基本一致

读字符串分两步操作:
1、获取字符串的长度;
2、从指定地址开始,读取字符串长度;

//String读取
var count = (byte) plc.Read(dataType, dbNumber, address, VarType.Byte, 1);//获取字符串长度
val = (string) plc.Read(dataType, dbNumber, address + 1, VarType.String, count);//获取对应长度的字符串
//S7String读取
var reservedLength = (byte) plc.Read(dataType, dbNumber, address, VarType.Byte, 1);//获取字符串长度
val = (string) plc.Read(dataType, dbNumber, address, VarType.S7String, reservedLength);//获取对应长度的字符串

写入与读取是反向操作,同样的也是要先写入要写入数据的长度,然后在写入数据

//Write写入
plc.Write(dataType, dbNumber, address, val.Length);    //写入长度
plc.Write(dataType, dbNumber, address + 1, val);       //写入字符串
//使用S7String方法构建,需要先构建S7String对应的字节数组,然后将数组写入。
var temp = Encoding.ASCII.GetBytes(val);   //将val字符串转换为字符数组
var bytes = S7.Net.Types.S7String.ToByteArray(val, temp.Length);
plc.WriteBytes(dataType, dbNumber, address, bytes);

关闭连接

在通讯完之后,千万不要忘了关闭通讯链路哈,这里使用Close来关闭。

 plc.Close();

以上内容都是在学习中,中间有很多内容还不完善,后续的内容在学习过程中会不断增加,如有更好的解决方案,欢迎留言一起探讨。

C#中使用S7.net与西门子PLC通讯相关推荐

  1. jetson nano上编译与使用西门子PLC通讯库snap7

    文章目录 一.西门子snap7介绍 二.西门子S7通讯介绍 三.jetson nano编译snap7库 四.Qt Cmake导入snap7库 五.snap7主要函数说明 1.与PLC建立连接 2.读写 ...

  2. 上位机与PLC 通讯源码 上位机与三菱PLC,西门子PLC通讯 同时一起通讯,单独控制,三菱采用官方MX 通讯,支持三菱FX系列,

    上位机与PLC 通讯源码 上位机与三菱PLC,西门子PLC通讯 同时一起通讯,单独控制,三菱采用官方MX 通讯,支持三菱FX系列,A系列,Q系列,L系列,R系列,全系系列,各种串口和各种网口通讯,, ...

  3. 上位机与PLC 通讯源码DEMO 上位机与三菱PLC,西门子PLC通讯 同时一起通讯,单独控制

    上位机与PLC 通讯源码DEMO 上位机与三菱PLC,西门子PLC通讯 同时一起通讯,单独控制,三菱采用官方MX 通讯,支持三菱FX系列,A系列,Q系列,L系列,R系列,全系系列,各种串口和各种网口通 ...

  4. C#与西门子plc通讯上位机 c#软件 工控软件

    C#与西门子plc通讯上位机 c#软件 工控软件 1.该程可以实现CSharp与西门子全系列plc(200,200smart,300,1200,1500)的以太网s7通讯,通讯传输快稳定. 2.该程序 ...

  5. PC与西门子PLC通讯免费软件Libnodave

    软件介绍:PC与西门子PLC通讯免费软件Libnodave Introduction: Libnodave is a free communication library for Siemens S7 ...

  6. 上位机与PLC 通讯源码 上位机与三菱PLC,西门子PLC通讯

    上位机与PLC 通讯源码 上位机与三菱PLC,西门子PLC通讯 同时一起通讯,单独控制,三菱采用官方MX 通讯,支持三菱FX系列,A系列,Q系列,L系列,R系列,全系系列,各种串口和各种网口通讯,, ...

  7. python与西门子PLC通讯

    python与西门子PLC通讯 安装Python-snap7 win+R打开"运行",输入cmd,确定后,进入DOS命令行终端,输入下面的命令: pip install pytho ...

  8. .net通过S7.net读写西门子PLC中,字符串,bool,整数,小数及byte型

    注:.net中通过TCP/IP方式通过S7.net.dll动态库,连接到西门子PLC,西门子程序中许勾选优化块,程序读取需要 db块号+偏移量 一.使用VS项目,在项目中添加S7.net动态库 代码中 ...

  9. 威纶和s7200通讯线_PLC通讯,西门子plc通讯知识汇总学习

    (一)西门子 200 plc 使用 MPI 协议与组态王进行通讯时需要哪些设置? 1)在运行组态王的机器上需要安装西门子公司提供的 STEP7 Microwin 3.2 的编程软件,我们的驱动需要调用 ...

最新文章

  1. python扫雷代码_室友扫雷通关来炫耀!我用Python做出自动扫雷十秒通关!
  2. Keras学习代码—github官网examples
  3. Python(字符串,列表,元组,字典)
  4. 深入学习SAP UI5框架代码系列之七:控件数据绑定的三种模式 - One Way, Two Way和OneTime实现原理比较
  5. 灯泡四个闪烁c语言程序设计教程课后答案,c语言编程题及答案4.doc
  6. 老生常谈session,cookie的区别,安全性
  7. pc计算机中ram的编址单位,字母编址
  8. 【转载】pyinstaller的使用和几个坑
  9. 统计学——单(双)因素方差分析
  10. oracle 10个表循环10次,oracle10g for 循环 嵌套
  11. WinRAR去除广告
  12. python银行管理系统框架_基于Python的网上银行综合管理系统的设计与实现
  13. unity LineRender结合多点触摸 实现拖拽 重复画线
  14. 如何把png/jpg文件生成为字体图标(css icon-font)
  15. 宝塔Linux面板搭建网站(超简单)
  16. Android自定义控件----继承ViewGroup侧滑菜单5,抽屉式侧滑,QQ5.0效果(完结)
  17. 下载、编译官方Android 4.1.2 源码
  18. 驼峰式与下划线命名规则
  19. 【Ajax】异步通信
  20. docker安装elasticesearch

热门文章

  1. 注册163VIP邮箱如何登陆?我邮件注册的163VIP邮箱不知道怎么登陆
  2. oracle第三章、第四章作业
  3. 基于人工智能的地球物理参数反演范式理论及判定条件
  4. boonton 功率测试软件,教你使用功率计及功率分析仪测试
  5. 如何下载 International Conference on Machine Learning(ICML)顶会的论文?从哪找ICML顶会论文?如何判断会议和期刊级别?
  6. 如何快速干净彻底的卸载Oracle11g
  7. 1.基于51单片机的蓝牙手机遥控小车
  8. 记一次图片压缩内存溢出的问题
  9. python安装cfgrib读取grib数据
  10. iOS——SDWebImage解读