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

本文主要是介绍C#上位机与欧姆龙PLC的通信07----使用第3方通讯库读写数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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协议的核心是消息和指令的传输。消息格式包括消息头、命令和数据区。消息头定义了消息的类型、长度和地址等信息。命令部分包含了具体的指令内容,如读取数据、写入数据或执行其他操作。数据区则是存储实际的数据信息。


 

这篇关于C#上位机与欧姆龙PLC的通信07----使用第3方通讯库读写数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/546882

相关文章

Rust中的注释使用解读

《Rust中的注释使用解读》本文介绍了Rust中的行注释、块注释和文档注释的使用方法,通过示例展示了如何在实际代码中应用这些注释,以提高代码的可读性和可维护性... 目录Rust 中的注释使用指南1. 行注释示例:行注释2. 块注释示例:块注释3. 文档注释示例:文档注释4. 综合示例总结Rust 中的注释

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化

Linux使用cut进行文本提取的操作方法

《Linux使用cut进行文本提取的操作方法》Linux中的cut命令是一个命令行实用程序,用于从文件或标准输入中提取文本行的部分,本文给大家介绍了Linux使用cut进行文本提取的操作方法,文中有详... 目录简介基础语法常用选项范围选择示例用法-f:字段选择-d:分隔符-c:字符选择-b:字节选择--c

Rust中的BoxT之堆上的数据与递归类型详解

《Rust中的BoxT之堆上的数据与递归类型详解》本文介绍了Rust中的BoxT类型,包括其在堆与栈之间的内存分配,性能优势,以及如何利用BoxT来实现递归类型和处理大小未知类型,通过BoxT,Rus... 目录1. Box<T> 的基础知识1.1 堆与栈的分工1.2 性能优势2.1 递归类型的问题2.2

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

springboot的调度服务与异步服务使用详解

《springboot的调度服务与异步服务使用详解》本文主要介绍了Java的ScheduledExecutorService接口和SpringBoot中如何使用调度线程池,包括核心参数、创建方式、自定... 目录1.调度服务1.1.JDK之ScheduledExecutorService1.2.spring

Java使用Tesseract-OCR实战教程

《Java使用Tesseract-OCR实战教程》本文介绍了如何在Java中使用Tesseract-OCR进行文本提取,包括Tesseract-OCR的安装、中文训练库的配置、依赖库的引入以及具体的代... 目录Java使用Tesseract-OCRTesseract-OCR安装配置中文训练库引入依赖代码实

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在