C# 读写倍福plc beckhoff , 使用ADS协议实现读取plc
本文将使用库技术来读写倍福PLC数据,使用的是基于以太网的ADS实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作
github地址:https://github.com/dathlin/HslCommunication 如果喜欢可以star或是fork,还可以打赏支持,打赏请认准源代码项目。
联系作者及加群方式:http://www.hslcommunication.cn/Cooperation
在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台输入下面的指令安装:
Install-Package HslCommunication
如果需要教程:Nuget安装教程:http://www.cnblogs.com/dathlin/p/7705014.html
组件的完整信息和API介绍参照:http://www.cnblogs.com/dathlin/p/7703805.html 组件的使用限制,更新日志,都在该页面里面。
如果你需要在读取PLC数据之后,还要群发客户端来实现远程办公室同步监视,可以参考如下的项目(基于该组件扩展起来的,带有账户验证,版本控制,数据群发,公告管理等等功能)
https://github.com/dathlin/ClientServerProject
本文将展示如何配置网络参数及怎样使用代码来访问PLC数据,希望给有需要的人解决一些实际问题。主要对基恩士的数据进行读写操作,具体的参照下面的地址信息
此处使用了网线直接的方式,如果PLC接进了局域网,就可以进行远程读写了^_^
此处使用到了2个命名空间:
|
1
2
|
using HslCommunication.Profinet.Beckhoff;using HslCommunication; |
随便聊聊
当我们一个上位机需要读取100台西门子PLC设备(此处只是举个例子,凡是都是使用Modbus tcp的都是一样的)的时候,你采用服务器主动去请求100台设备的机制对性能来说是个极大的考验,如果开100个线程去轮询100台设备,那么性能损失将是非常大的,更不用说再增加设备,如果搭建Modbus tcp服务器,就可以完美的解决性能问题,因为连接的压力将会平均分摊给每一台PLC,服务器端只要新增一个时间戳就可以知道客户端有没有连接上。
我们在100台PLC里都增加发送Modbus tcp方法,将数据发送到服务器的ip和端口上去,服务器根据站号来区分设备。这样就可以搭建一个高性能总站。 本组件支持快速搭建一个高性能的Modbus tcp总站。
http://www.cnblogs.com/dathlin/p/7782315.html
关于两种模式
在PLC端,包括三菱,西门子,欧姆龙以及Modbus Tcp客户端的访问器上,都支持两种模式,短连接模式和长连接模式,现在就来解释下什么原理。
短连接:每次读写都是一个单独的请求,请求完毕也就关闭了,如果服务器的端口仅仅支持单连接,那么关闭后这个端口可以被其他连接复用,但是在频繁的网络请求下,容易发生异常,会有其他的请求不成功,尤其是多线程的情况下。
长连接:创建一个公用的连接通道,所有的读写请求都利用这个通道来完成,这样的话,读写性能更快速,即时多线程调用也不会影响,内部有同步机制。如果服务器的端口仅仅支持单连接,那么这个端口就被占用了,比如三菱的端口机制,西门子的Modbus tcp端口机制也是这样的。以下代码默认使用长连接,性能更高,还支持多线程同步。
在短连接的模式下,每次请求都是单独的访问,所以没有重连的困扰,在长连接的模式下,如果本次请求失败了,在下次请求的时候,会自动重新连接服务器,直到请求成功为止。另外,尽量所有的读写都对结果的成功进行判断。
关于日志记录
不管是基恩士的,三菱的数据访问类,还是西门子的,还是Modbus tcp访问类,都有一个LogNet属性用来记录日志,该属性是一个接口类,ILogNet,凡事继承该接口的都可以用来记录日志,该日志会在访问失败时,尤其是因为网络的原因导致访问失败时会进行日志记录(如果你为这个 LogNet 属性配置了真实的日志记录器的话):如果你想使用该记录日志的功能,请参照如下的博客进行实例化:
http://www.cnblogs.com/dathlin/p/7691693.html
访问测试项目
下面的一个项目是这个组件的访问测试项目,您可以进行初步的访问的测试,免去了您写测试程序的麻烦,三菱的界面和西门子的界面几乎是一致的。可以同时参考。该项目位于本篇文章开始处的Gitbub源代码里面的
下载地址为:HslCommunicationDemo.zip

演示项目
下面的三篇演示了具体如何去访问PLC的数据,我们在访问完成后,通常需要进行处理,以下的示例项目就演示了后台从PLC读取数据后,前台显示并推送给所有在线客户端的功能,客户端并进行图形化显示,具有一定的参考意义,并且推送给网页前端,项目地址为:
https://github.com/dathlin/RemoteMonitor
下面的图片示例中的左边程序就是服务器程序,它应该和PLC直接连接并接入局域网,然后把数据推送给客户端显示。注意:一个复杂高级的程序就应该把处理逻辑程序和界面程序分开,比如这里的服务器程序实现数据采集,推送,存储。让客户端程序去实现数据的整理,分析,显示,这样即使客户端程序因为BUG奔溃,服务器端仍然可以正常的工作。

配置篇
倍福的配置
在使用组件和倍福plc通讯之前,需要进行相关的配置,
SETP2选择 choose




输入用户名和密码后点击OK添加完成
连接ADS时必须要填密码
如果没有请去创建一个


可以看到本机的AMSnet 和路由状况

注意,plc的IP地址,不是ams net id
电脑的ip地址,也不是ams net id。
读写数据篇
初始化访问PLC对象
如果想使用本组件的数据读取功能,必须先初始化数据访问对象,根据实际情况进行数据的填入。 下面仅仅是测试中的数据:
BeckhoffAdsNet beckhoffAdsNet = new BeckhoffAdsNet( "192.168.182.131", 48898 );
beckhoffAdsNet.SetTargetAMSNetId( "192.168.182.131.1.1:801" );
beckhoffAdsNet.SetSenderAMSNetId( "192.168.235.128.1.1" );
打开连接,并可以判断是否连接上
beckhoffAdsNet.ConnectServer( );
如果需要判断,那么按照如下的操作
OperateResult connect = beckhoffAdsNet.ConnectServer( );
if (connect.IsSuccess)
{
// connect success
}
else
{
// failed
}
那么现在可以读写数据了,数据分为三种类型
1. I.Q.M地址,这三个是同理的
OperateResult<bool> read = beckhoffAdsNet.ReadBool( "M100" );
bool value = read.Content;
此时的100是第100个位的数据
当然了,也可以读取字数据
OperateResult<short> read = beckhoffAdsNet.ReadInt16( "M10" );
short value = read.Content;
此时的10的地址,就是指第10个字节的数据
2. 绝对地址
OperateResult<short> read = beckhoffAdsNet.ReadInt16( "i=100002" );
short value = read.Content;
绝对地址以i=开头的,后面的是数据的绝对地址,在内存里的绝对地址信息。
3, 标签地址
OperateResult<short> read = beckhoffAdsNet.ReadInt16( "s=MAIN.int1" );
short value = read.Content;
无论读取什么地址,都是必须知道类型的,然后就可以读写操作了。
关于标签读取的方式的情况下的加速操作。
标签读取的本质分成两步,第一个根据标签获取到变量的绝对地址,然后根据绝对地址获取到值。
现在只需要将 UseTagCache 设置为True , 就可以实现缓存功能,加速标签的读写速度。
C# 读写倍福plc beckhoff , 使用ADS协议实现读取plc的更多相关文章
- 倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码
倍福TwinCAT3上位机与PLC通信测试(ADS通信) 包含C#和C++代码 本次测试需要环境: VS2013,TwinCAT3(本人版本TC31-Full-Setup.3.1.4018.16) 代 ...
- 倍福TwinCAT(贝福Beckhoff)应用教程12.3 TwinCAT控制松下伺服 NC进阶
在前面一节,我们简单介绍了通过PLC+HMI实现完整控制松下伺服的上使能-运动,采集位置,速度等功能,这里我们会大量简化用到的贝福功能块(为了更加实用).首先依然是对单个轴的封装,我们之前的做法,例如 ...
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-为什么无法打开官方范例的项目,打开tszip文件时提示尝试越过结尾怎么办
打开新的解决方案,找到tszip文件 提示错误Advanced Setting时越过结尾 到这里一般VS会卡死 但是我们已经可以得到解压出来的文件夹,其中包含PLC的完整项目文件夹,可以新 ...
- 倍福CX5120嵌入式控制器使用教程
1.新建工程 新建TwinCAT XAE Project 2.连接设备 点击SYSTEM,再点击"Change Target..." 在弹出的"choose Targt ...
- C#读写基恩士PLC 使用TCP/IP 协议 MC协议
本文将使用一个Github开源的组件库技术来读写基恩士PLC数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 g ...
- python 读写三菱PLC数据,使用以太网读写Q系列,L系列,Fx系列的PLC数据
本文将使用一个gitHub开源的组件技术来读写三菱的plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...
- ADS协议变量配置界面
ADS协议是倍福产品的通信协议,在双击ADS协议图标后打开如下图的配置窗口. 变量配置表中各列的含义: 报警类型: 脚本: 当设置了报类型时,在运行时如果变量值引发报警时将执行一次脚本.例如 大于报警 ...
- c#基于TCP/IP、CIP协议的欧姆龙PLC通信
一.关于CIP协议 CIP通信是Common Industrial Protocl(CIP)的简称,它是一个点到点的面向对象协议,能够实现工业器件(传感器,执行器)之间的连接,和高等级的控制器之间的连 ...
- 西门子PLC开发笔记(一):PLC介绍,西门子S1200系列接线、编程、下载和仿真
前言 西门西PLC.台达触摸屏.法兰克机床等等多年以前玩得比较多,改造机床.维修机床.给机床编程等等,没事还能扯个零件啥的,之前也没总结过,有时间就重新整理下. 本章后面以西门1200实物为例, ...
随机推荐
- Yii2 负载均衡找不到JS,CSS
在部署项目的时候,用了2台服务器.请求的时候用了负载均衡,导致 YII2 的静态文件(js,css...)报 404 ,原因是: 请求一个页面时 A服务器 去处理,但是静态资源缺请求到了 B服务器 , ...
- pod install/update速度慢或失败的解决方案实践
本文基于 https://www.cnblogs.com/dabaomo/p/9634727.html 声明 坚决拥护党的领导,本文章所用技术乃出于工作需要,敬请谅解. 正文 可以先过去快速浏览一遍再 ...
- Java并发编程学习随笔 (一) 使用run() 和 start()的差别
java多线程run()和start()的区别 当你启动线程,使用start(),系统会把run()方法当成线程执行体来处理,这是正常的,也是正确的情况.但是,当你启动线程时,调用run()方法,系统 ...
- 15 个优秀开源的 Spring Boot 学习项目,一网打尽!
Spring Boot 算是目前 Java 领域最火的技术栈了,松哥年初出版的 <Spring Boot + Vue 全栈开发实战>迄今为止已经加印了 8 次,Spring Boot 的受 ...
- RocketMQ 主题扩分片后遇到的坑
目录 1.案情回顾 1.1 集群现状 1.2.RocketMQ 在线扩容队列 1.3 消息发送 2.问题暴露 3.问题分析 4.问题复盘 消息组接到某项目组反馈,topic 在扩容后出现部分队列无法被 ...
- C#开发安卓自学笔记1
今天开始研究了下C#开发安卓,刚开始什么都不懂,学过安卓的同学们也是用Java开发的,虽然两者开发差别不大,但是还是有差别的 // Set our view from the "main&q ...
- Java修炼——插入排列,选择排列
话不多说,直接上代码: package com.bjsxt.Array; import java.util.Arrays; public class TestSort { //选择排序 //插入排列 ...
- JVM内运行时数据区
JVM的基本区域: 类加载子系统 运行时数据区(内存区域) 执行引擎 运行时数据区域 方法区(Method Area) 类的所有字和方法字节码,以及一些特殊方法如构造函数,接口代码也在这里定义.简单来 ...
- Linq 常用操作(增删改)
增加 using(var db = new Entities()) { //数据操作 UserInfo user = new UserInfo() { UserName = "zhangsa ...
- rails gem ransack 之模糊搜索
gem 'ransack' eq: "等于" eq_any: "等于任意值" eq_all: "等于所有值" not_eq: "不 ...