zoukankan      html  css  js  c++  java
  • C#读写 AB PLC 直接通过节点来读写数据 读写 AllenBradley PLC

    本文将使用一个Github开源的组件库技术来读写AB PLC,使用的是基于以太网的实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作

    官网:http://www.hslcommunication.cn/     官网包含了详细的API文档

    联系作者及加群方式(激活码在群里发放):http://www.hslcommunication.cn/Cooperation 

    本类库绝对是ab最强的通讯库

    nuget地址:https://www.nuget.org/packages/HslCommunication/       nuget     下载

    github地址:https://github.com/dathlin/HslCommunication      fork      star                     如果喜欢可以star或是fork,还可以打赏支持。打赏请认准源代码项目。

    从NUGET安装


    Install-Package HslCommunication
    

    准备


    本文将展示怎样使用代码来访问PLC数据,希望给有需要的人解决一些实际问题。主要对AB PLC的节点数据进行读写,您在应用工业生产使用之前,应该应该详细的测试,以免造成不必要的损失

    此处使用到了2个命名空间:

    using HslCommunication.Profinet.AllenBradley;
    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端,包括三菱,西门子,欧姆龙,AB以及Modbus Tcp客户端的访问器上,都支持两种模式,短连接模式和长连接模式,现在就来解释下什么原理。

    短连接:每次读写都是一个单独的请求,请求完毕也就关闭了,如果服务器的端口仅仅支持单连接,那么关闭后这个端口可以被其他连接复用,但是在频繁的网络请求下,容易发生异常,会有其他的请求不成功,尤其是多线程的情况下。

    长连接:创建一个公用的连接通道,所有的读写请求都利用这个通道来完成,这样的话,读写性能更快速,即时多线程调用也不会影响,内部有同步机制。如果服务器的端口仅仅支持单连接,那么这个端口就被占用了,比如三菱的端口机制,西门子的Modbus tcp端口机制也是这样的。以下代码默认使用长连接,性能更高,还支持多线程同步。

    在短连接的模式下,每次请求都是单独的访问,所以没有重连的困扰,在长连接的模式下,如果本次请求失败了,在下次请求的时候,会自动重新连接服务器,直到请求成功为止。另外,尽量所有的读写都对结果的成功进行判断。

    关于日志记录


    不管是三菱的数据访问类,还是西门子的,还是Modbus tcp访问类,都有一个LogNet属性用来记录日志,该属性是一个接口类,ILogNet,凡事继承该接口的都可以用来记录日志,该日志会在访问失败时,尤其是因为网络的原因导致访问失败时会进行日志记录(如果你为这个 LogNet 属性配置了真实的日志记录器的话):如果你想使用该记录日志的功能,请参照如下的博客进行实例化:

    http://www.cnblogs.com/dathlin/p/7691693.html

    访问测试项目


    下面的一个项目是这个组件的访问测试项目,您可以进行初步的访问的测试,免去了您写测试程序的麻烦,三菱的界面和西门子的界面几乎是一致的。可以同时参考。该项目位于本篇文章开始处的Gitbub源代码里面的

    下载地址为:HslCommunicationDemo.zip 

    演示项目,和本项目的信息无关,示例为采集西门子PLC数据


    下面演示了具体如何去访问PLC的数据,我们在访问完成后,通常需要进行处理,以下的示例项目就演示了后台从PLC读取数据后,前台显示并推送给所有在线客户端的功能,客户端并进行图形化显示,具有一定的参考意义,并且推送给网页前端,项目地址为:

    https://github.com/dathlin/RemoteMonitor

    它应该和PLC直接连接并接入局域网,然后把数据推送给客户端显示。注意:一个复杂高级的程序就应该把处理逻辑程序和界面程序分开,比如这里的服务器程序实现数据采集,推送,存储。让客户端程序去实现数据的整理,分析,显示,这样即使客户端程序因为BUG奔溃,服务器端仍然可以正常的工作。

    初始化访问PLC对象

    如果想使用本组件的数据读取功能,必须先初始化数据访问对象,根据实际情况进行数据的填入。 下面仅仅是测试中的数据

    private AllenBradleyNet allenBradleyNet  = new AllenBradleyNet( "192.168.0.110" );
    

      

    连接PLC信息

    实例化之后应该启动PLC的连接操作。

    OperateResult connect = allenBradleyNet.ConnectServer( );
                    if (connect.IsSuccess)
                    {
                        MessageBox.Show( "连接成功!" );
                    }
                    else
                    {
                        MessageBox.Show( "连接失败!" + connect.ToMessageShowString( ) );
                    }
    

    断开PLC连接

    allenBradleyNet.ConnectClose( );
    

      

    读取PLC信息

    需要参照设备的节点信息来查看:

    需要注意的是,我们在读取一个节点名称之前,需要先查看该节点在PLC的数据类型,比如上面图片里的,B2是 REAL 类型,那么我们就需要使用float读取,当你的类型选择错误时,有可能会读取不到正确的信息。

    float value = allenBradleyNet.ReadFloat( "B2" ).Content
    

    类型选择的对应关系如下: bool 类型对应 bool    byte类型 对应  byte   DINT类型代表int等等。

    批量读取PLC信息

    将读取的节点变成一个数组信息传入进去

    public OperateResult<byte[]> Read( string[] address )
    

    结果提取稍微麻烦一点,多个节点的数据拼接结果。例如下面:

    OperateResult<byte[]> read = allenBradleyNet.Read( new string[] { "B1", "B2" } );
                if (read.IsSuccess)
                {
                    int B1 = allenBradleyNet.ByteTransform.TransInt32( read.Content, 0 );
                    float B2 = allenBradleyNet.ByteTransform.TransSingle( read.Content, 4 );
                }
    

      

    写入PLC信息

    写入操作的类型也是要和PLC进行对应的,当类型不正确的时候,是不能写入操作的。

    OperateResult write = allenBradleyNet.Write("B2", 123.456f);
    if(write.IsSuccess)
    {
         // 成功  
    }
    else
    {
        // 失败
    }
    

      

    自定义写入方法:

    /// <summary>
            /// 使用指定的类型写入指定的节点数据
            /// </summary>
            /// <param name="address">节点地址数据</param>
            /// <param name="typeCode">类型代码,详细参见<see cref="AllenBradleyHelper"/>上的常用字段</param>
            /// <param name="value">实际的数据值</param>
            /// <returns>是否写入成功</returns>
            public OperateResult WriteTag( string address, ushort typeCode, byte[] value )
    

      

    如果你清楚类型代码及数据内容可以实现更复杂的数据写入功能。

    针对数组的数据读取:

    比如图片中的 Array 数组,是一个short的数组数据,长度为6,如果想要读取这6个数据

    OperateResult<short[]> readResult = allenBradleyNet.ReadInt16( "Array", 6 );

    当然也支持读取指定索引的数据

    OperateResult<short> readResult = allenBradleyNet.ReadInt16( "Array[1]" );

    写入也是支持的

    本方法是组件 5.5.2及之后开始支持,其中,后面的6可以写成0-6的任意数字。你写多少,就读多少长度的数组。读取的类型也要和实际的匹配,才能完美的读取。 

     针对数组的写入操作:

                    OperateResult write = allenBradleyNet.Write( "Array", new short[] { 101, 102, 103, 104, 105, 106 } );

    结果如下:

    更多的操作和细节可以参照DEMO项目和源代码项目

  • 相关阅读:
    POJ 1426 Find The Multiple(数论——中国同余定理)
    POJ 2253 Frogger(Dijkstra变形——最短路径最大权值)
    POJ 3790 最短路径问题(Dijkstra变形——最短路径双重最小权值)
    POJ 3278 Catch That Cow(模板——BFS)
    HDU 1071 The area
    HDU 1213 How Many Tables(模板——并查集)
    POJ 1611 The Suspects
    light oj 1214 Large Division
    POJ 1258 Agri-Net(Prim算法求解MST)
    POJ 2387 Til the Cows Come Home(模板——Dijkstra算法)
  • 原文地址:https://www.cnblogs.com/dathlin/p/9607929.html
Copyright © 2011-2022 走看看