C#上位机与欧姆龙PLC的通信07----使用第3方通讯库读写数据

news/2024/5/17 16:57:09 标签: tcp/ip, PLC, c#, 网络协议, TCP, 通讯库, 欧姆龙

1、介绍 

       FINS (factory interface network service)通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令/响应系统。运用FINS指令可实现各种网络间的无缝通信,通过编程发送FINS指令,上位机或PLC就能够读写另一个PLC数据区的内容,甚至控制其运行状态,从而简化了用户程序。FINS协议支持工业以太网,这就为OMRONPLC与上位机以太网通信的实现提供了途径。
       在上节内容C#上位机与欧姆龙PLC的通信06---- HostLink协议(FINS版),我们熟悉了协议报文结构,知道了如何发送命令,接收命令,但是那是为了了解它的报文组成部分,在应用层开发中,我们是不可能直接发送报文来获取数据的,应该使用第3方的通讯库来与PLC通信或者自己写通讯库,这节介绍一个与欧姆龙PLC进行FINS通信的通讯库,也就是说别人写好的代码,只要拿来用就可以了,当然超人,高手需要封装自己的通讯库,下节来写自己的通讯库,这节先熟悉别人的通讯库怎么用,以丰满自己的肌肉。不管是别人写的通讯库还是自己写的通讯库,里面通信的过程和报文都是上节讲的那些结构,只是你看不到。

      开发环境采用vs2022,编写控制台程序,通讯库的名称叫“omronfinstcp.net” ,必须先安装好vs2022。

2、开始干

1、创建项目OmronFinsConsoleApp

2、添加引用

3、连接PLC

编写代码:

 static void Main(string[] args)
 {
     Console.WriteLine("Hello World!");
     //创建实例
     OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
     //连接plc,5000是超时时间
    var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
     Console.WriteLine("连接成功!");

     Console.ReadKey();

 }

可以看到是不是很简单,这是使用通讯库的好处,不要拼什么报文

4、 读取和写入CIO区的2进制数据

1、读取CIO0.0开始的6个数据

程序代码:

 static void Main(string[] args)
 {
     Console.WriteLine("Hello World!");
     //创建实例
     OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
     //连接plc,5000是超时时间
    var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
     Console.WriteLine("连接成功!");

     Console.WriteLine("读取bool一个");
     short bvalue = 0;
     etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.0", out bvalue);
     Console.WriteLine("CIO区0.0:" + bvalue);
     etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.3", out bvalue);
     Console.WriteLine("CIO区0.3:" + bvalue);

     Console.WriteLine("读取bool多个");
     short bvalue1 = 0;
     for (int i = 0; i < 6; i++)
     {
         etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), out bvalue1);
         Console.WriteLine("CIO区0中的" + (i).ToString() + "=" + bvalue1);
     }  
     Console.ReadKey(); 
 }

注意:这个通讯库有不完善的地方,读取多个bool时,他没有提供对应的方法,他只能读取一个,读取多个,自然要使用循环,所以说别人的库有不完善的地方,下节我自己写的通讯库,比这个强大。

查看报文

 2、 写入指令,写入CIO区0.0开始的6个bool数据true, true, true, true, true,true

程序代码

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    //创建实例
    OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
    //连接plc,5000是超时时间
   var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
    Console.WriteLine("连接成功!");

    //Console.WriteLine("读取bool一个");
    //short bvalue = 0;
    //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.0", out bvalue);
    //Console.WriteLine("CIO区0.0:" + bvalue);
    //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.3", out bvalue);
    //Console.WriteLine("CIO区0.3:" + bvalue);

    //Console.WriteLine("读取bool多个");
    //short bvalue1 = 0;
    //for (int i = 0; i < 6; i++)
    //{
    //    etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), out bvalue1);
    //    Console.WriteLine("CIO区0中的" + (i).ToString() + "=" + bvalue1);
    //}  

    Console.WriteLine("写入bool一个");
    etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.0", OmronFinsTCP.Net.BitState.OFF);
    etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.3", OmronFinsTCP.Net.BitState.ON); 
    Console.WriteLine("写入bool多个");
    for (int i = 0; i < 6; i++)
    {
        etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), OmronFinsTCP.Net.BitState.ON);
    }
    Console.WriteLine("ok");

    Console.ReadKey(); 
}

同样,他的通讯库不支持写入多个bool类型的数据,必须循环方式写入一个个的。查看PLC内存区,写入成功。

 

通讯报文

 

5、读取和写入D区的ushort类型数据

首先设置内存区D区100的4个数据,注意D区设置的数据类型为10进制无符号的整数,对应C#中就是ushort类型。

1、读取D区100开始的4个数据

程序代码

 static void Main(string[] args)
 {
     Console.WriteLine("Hello World!");
     //创建实例
     OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
     //连接plc,5000是超时时间
    var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
     Console.WriteLine("连接成功!");

     //Console.WriteLine("读取bool一个");
     //short bvalue = 0;
     //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.0", out bvalue);
     //Console.WriteLine("CIO区0.0:" + bvalue);
     //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.3", out bvalue);
     //Console.WriteLine("CIO区0.3:" + bvalue);

     //Console.WriteLine("读取bool多个");
     //short bvalue1 = 0;
     //for (int i = 0; i < 6; i++)
     //{
     //    etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), out bvalue1);
     //    Console.WriteLine("CIO区0中的" + (i).ToString() + "=" + bvalue1);
     //}  

     //Console.WriteLine("写入bool一个");
     //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.0", OmronFinsTCP.Net.BitState.OFF);
     //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.3", OmronFinsTCP.Net.BitState.ON); 
     //Console.WriteLine("写入bool多个");
     //for (int i = 0; i < 6; i++)
     //{
     //    etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), OmronFinsTCP.Net.BitState.ON);
     //}
     //Console.WriteLine("ok");

     Console.WriteLine("读取ushort一个");
     short svalue = 0;
     etherNetPLC.ReadWord(OmronFinsTCP.Net.PlcMemory.DM, 100, out svalue);
     Console.WriteLine("d区100:" + svalue);

     Console.WriteLine("读取ushort多个");
     short[] shortarray = new short[] { };
     etherNetPLC.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 100, 4, out shortarray);
     for (int i = 0; i < shortarray.Length; i++)
     {
         Console.WriteLine("d区100中的" + (i).ToString() + "=" + shortarray[i]);
     }
     Console.WriteLine("ok");



     Console.ReadKey(); 
 }

可以看到,支持读取多个ushort类型的数据,通讯报文

 2、向D区200的地址写入4个ushort数据170, 171, 172, 173,174

程序代码

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    //创建实例
    OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
    //连接plc,5000是超时时间
   var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
    Console.WriteLine("连接成功!");

    //Console.WriteLine("读取bool一个");
    //short bvalue = 0;
    //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.0", out bvalue);
    //Console.WriteLine("CIO区0.0:" + bvalue);
    //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.3", out bvalue);
    //Console.WriteLine("CIO区0.3:" + bvalue);

    //Console.WriteLine("读取bool多个");
    //short bvalue1 = 0;
    //for (int i = 0; i < 6; i++)
    //{
    //    etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), out bvalue1);
    //    Console.WriteLine("CIO区0中的" + (i).ToString() + "=" + bvalue1);
    //}  

    //Console.WriteLine("写入bool一个");
    //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.0", OmronFinsTCP.Net.BitState.OFF);
    //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.3", OmronFinsTCP.Net.BitState.ON); 
    //Console.WriteLine("写入bool多个");
    //for (int i = 0; i < 6; i++)
    //{
    //    etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), OmronFinsTCP.Net.BitState.ON);
    //}
    //Console.WriteLine("ok");

    //Console.WriteLine("读取ushort一个");
    //short svalue = 0;
    //etherNetPLC.ReadWord(OmronFinsTCP.Net.PlcMemory.DM, 100, out svalue);
    //Console.WriteLine("d区100:" + svalue);

    //Console.WriteLine("读取ushort多个");
    //short[] shortarray = new short[] { };
    //etherNetPLC.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 100, 4, out shortarray);
    //for (int i = 0; i < shortarray.Length; i++)
    //{
    //    Console.WriteLine("d区100中的" + (i).ToString() + "=" + shortarray[i]);
    //}
    //Console.WriteLine("ok"); 

    Console.WriteLine("写入ushort一个");
    var myresult = etherNetPLC.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 200, 148);
    Console.WriteLine("ok");
    Console.WriteLine("写入ushort多个");
    for (int i = 0; i < 5; i++)
    {
        etherNetPLC.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, (short)(200 + i), (short)(170 + i));
    }
    Console.WriteLine("ok");


    Console.ReadKey(); 
}

写入成功

通讯报文

 

6、读取和写入H区的short类型数据

 设置H区的4个数据

很遗憾,通讯库不支持H区的读写

很遗憾,通讯库不支持H区的读写

 7、读取和写入W区的float类型数据

设置W区的5个数据

1、读取W区100开始的5个float数据 

程序代码

  static void Main(string[] args)
  {
      Console.WriteLine("Hello World!");
      //创建实例
      OmronFinsTCP.Net.EtherNetPLC etherNetPLC = new OmronFinsTCP.Net.EtherNetPLC();
      //连接plc,5000是超时时间
     var rt=  etherNetPLC.Link("192.168.1.4", 7788, (short)5000);
      Console.WriteLine("连接成功!");

      //Console.WriteLine("读取bool一个");
      //short bvalue = 0;
      //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.0", out bvalue);
      //Console.WriteLine("CIO区0.0:" + bvalue);
      //etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0.3", out bvalue);
      //Console.WriteLine("CIO区0.3:" + bvalue);

      //Console.WriteLine("读取bool多个");
      //short bvalue1 = 0;
      //for (int i = 0; i < 6; i++)
      //{
      //    etherNetPLC.GetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), out bvalue1);
      //    Console.WriteLine("CIO区0中的" + (i).ToString() + "=" + bvalue1);
      //}  

      //Console.WriteLine("写入bool一个");
      //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.0", OmronFinsTCP.Net.BitState.OFF);
      //etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "00.3", OmronFinsTCP.Net.BitState.ON); 
      //Console.WriteLine("写入bool多个");
      //for (int i = 0; i < 6; i++)
      //{
      //    etherNetPLC.SetBitState(OmronFinsTCP.Net.PlcMemory.CIO, "0." + i.ToString(), OmronFinsTCP.Net.BitState.ON);
      //}
      //Console.WriteLine("ok");

      //Console.WriteLine("读取ushort一个");
      //short svalue = 0;
      //etherNetPLC.ReadWord(OmronFinsTCP.Net.PlcMemory.DM, 100, out svalue);
      //Console.WriteLine("d区100:" + svalue);

      //Console.WriteLine("读取ushort多个");
      //short[] shortarray = new short[] { };
      //etherNetPLC.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 100, 4, out shortarray);
      //for (int i = 0; i < shortarray.Length; i++)
      //{
      //    Console.WriteLine("d区100中的" + (i).ToString() + "=" + shortarray[i]);
      //}
      //Console.WriteLine("ok"); 

      //Console.WriteLine("写入ushort一个");
      //var myresult = etherNetPLC.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 200, 148);
      //Console.WriteLine("ok");
      //Console.WriteLine("写入ushort多个");
      //for (int i = 0; i < 5; i++)
      //{
      //    etherNetPLC.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, (short)(200 + i), (short)(170 + i));
      //}
      //Console.WriteLine("ok");

      //Console.WriteLine("读取short多个");
      //short[] shortarray = new short[] { };
      //etherNetPLC.ReadWords(OmronFinsTCP.Net.PlcMemory., 100, 4, out shortarray);
      //for (int i = 0; i < shortarray.Length; i++)
      //{
      //    Console.WriteLine("H区100中的" + (i).ToString() + "=" + shortarray[i]);
      //}
      //Console.WriteLine("ok");

      Console.WriteLine("读取float一个");
      float fvalue = 0.0f;
      etherNetPLC.ReadReal(OmronFinsTCP.Net.PlcMemory.WR, 100, out fvalue);
      Console.WriteLine("w区100:" + fvalue);

      Console.WriteLine("读取float多个"); 
      float fvalue2 = 0.0f;
      for (int i = 0; i < 5; i++)
      {
          etherNetPLC.ReadReal(OmronFinsTCP.Net.PlcMemory.WR, (short)(100 + i * 2), out fvalue2);
          Console.WriteLine("w区200中的" + (i).ToString() + "=" + fvalue2);
      }


      Console.ReadKey(); 
  }

通讯报文

 

2、向W区30的地址写入5个数据720, -730, -740,75.6f,-79.4f 

很遗憾,没有提供写入浮点数的方法

 

3、小结
 

下节,我们写自己的通讯库,非常强大,非常凶猛。

   FINS协议是一种基于TCP/IP网络通信的实时通信协议.能够实现欧姆龙工业设备之间的数据交换和控制指令传输。它采用了客户端/服务器模型,客户端发送请求,服务器返回响应,通过建立连接、传输数据包来实现设备之间的通信。
  FINS协议的核心是消息和指令的传输。消息格式包括消息头、命令和数据区。消息头定义了消息的类型、长度和地址等信息。命令部分包含了具体的指令内容,如读取数据、写入数据或执行其他操作。数据区则是存储实际的数据信息。


 


http://www.niftyadmin.cn/n/5290525.html

相关文章

EasyExcel 通过模板 导入、导出、下载模板

EasyExcel 通过模板 导入、导出、下载模板 import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; import java.io.…

2024 年 11 款最佳 Android 数据恢复软件应用

Android 设备上的数据丢失可能是一种令人痛苦的经历&#xff0c;通常会导致不可替代的信息瞬间消失。 意外删除、系统崩溃或格式错误都可能发生&#xff0c;重要数据的丢失可能会扰乱日常工作并影响您的工作效率。 幸运的是&#xff0c;技术进步带来了多种恢复解决方案&…

MySQL Too many connections报错

MySQL 时不时出现Too many connections报错&#xff0c;重启MySQL就好了 但是过段时间又出现 一、解决方案&#xff1a; 1.修改mysql最大连接数 set global max_connections500; 以上是修改立即生效的&#xff0c;重启MySQL就会还原回去 在MySQL配置文件修改 max_connection…

uniapp开发---Android打包发行(避坑指南四)

android离线打包&#xff0c;原生打包。参考官网 应用配置 | uni小程序SDK 【彩带- 避坑知识点】&#xff1a; 安卓离线打包&#xff0c;功能都正常&#xff0c;版本更新无法实现下载后自动安装。 但uniapp云打包则下载更新安装都正常。猜测可能是因为安卓离线打包缺少aar包导…

Docker自建私人云盘系统

Docker自建私人云盘系统。 有个人云盘需求的人&#xff0c;主要需求有这几类&#xff1a; 文件同步、分享需要。 照片、视频同步需要&#xff0c;尤其是全家人都是用的同步。 影视观看需要&#xff08;分为家庭内部、家庭外部&#xff09; 搭建个人网站/博客 云端OFFICE需…

Python初学者必须吃透的69个内置函数!

所谓内置函数&#xff0c;就是Python提供的, 可以直接拿来直接用的函数&#xff0c;比如大家熟悉的print&#xff0c;range、input等&#xff0c;也有不是很熟&#xff0c;但是很重要的&#xff0c;如enumerate、zip、join等&#xff0c;Python内置的这些函数非常精巧且强大的&…

EMR集群迁移自建Hadoop(元数据及HDFS数据)

1.背景 老集群采用的腾讯emr集群&#xff0c;使用过程中磁盘扩容成本费用高且开源组件兼容性存在问题&#xff0c;因此决定采用自建hadoop集群&#xff0c;需要将emr的元数据和hdfs基础数据迁移过来。 EMR版本&#xff1a;3.1.2 自建Hadoop版本&#xff1a;3.1.3 2.集群迁移步…

虎克:蓝牙定位设备分哪几类,在蓝牙设备开发对接时需要注意什么?

市场上的蓝牙定位设备可以分为四类&#xff1a; 第一类&#xff1a;蓝牙网关房间级定位 核心设备是蓝牙网关&#xff0c;通过蓝牙网关&#xff0c;结合RSSI对做到房间级别的定位&#xff0c;这个方案非常适合资产管理场景。 因为一般的企业库存或者重要的资产管理只需要做到…