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

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

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

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

github地址:https://github.com/dathlin/HslCommunication                                 如果喜欢可以star或是fork,还可以打赏支持。

从NUGET安装


Install-Package HslCommunication

  

准备


本文将展示如何配置网络参数及怎样使用代码来访问PLC数据,希望给有需要的人解决一些实际问题。主要对三菱Fx系列PLC的X,Y,M,S,C,T,D区域的数据读写

此处使用了串口直接的方式

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

using HslCommunication.Profinet.Melsec;
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对象

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

MelsecFxSerial melsecFx = new MelsecFxSerial( );
melsecFx.SerialPortInni( sp =>{sp.PortName = "COM1";sp.BaudRate = 9600;sp.DataBits = 7;sp.StopBits = System.IO.Ports.StopBits.One;sp.Parity = System.IO.Ports.Parity.Even;} );melsecFx.Open( );

  串口的初始化操作一定要正确

关于地址的表示方式

使用字符串表示,这个组件里所有的读写操作提供字符串表示的重载方法,所有的支持访问的类型对应如下,字符串的表示方式存在十进制和八进制的区别:

  • 输入继电器:"X10", "X17"               // 字符串为八进制机制
  • 输出继电器:"Y10" , "Y17"              // 字符串为八进制机制
  • 内部继电器:"M100", "M200"          // 字符串为十进制
  • 步进继电器:"S100" , "S200"          // 字符串为十进制
  • 数据寄存器:"D100", "D200"           // 字符串为十进制
  • 计数寄存器:"C100" , "C200"          // 字符串为十进制
  • 定时寄存器:"T100" , "T200"           // 字符串为十进制

展示一些简单实用基础数据读写,这些数据的读写没有进行严格的是否成功判断(判断方法参照后面的代码),一般网络良好的情况下都会成功,但不排除失败,以下代码仅作测试,所有没有严格判断是否成功:

            // 此处以D寄存器作为示例short short_D1000 = melsecFx.ReadInt16( "D100" ).Content;         // 读取D1000的short值 ushort ushort_D1000 = melsecFx.ReadUInt16( "D100" ).Content;      // 读取D1000的ushort值int int_D1000 = melsecFx.ReadInt32( "D100" ).Content;             // 读取D1000-D1001组成的int数据uint uint_D1000 = melsecFx.ReadUInt32( "D100" ).Content;          // 读取D1000-D1001组成的uint数据float float_D1000 = melsecFx.ReadFloat( "D100" ).Content;         // 读取D1000-D1001组成的float数据long long_D1000 = melsecFx.ReadInt64( "D100" ).Content;           // 读取D1000-D1003组成的long数据ulong ulong_D1000 = melsecFx.ReadUInt64( "D100" ).Content;        // 读取D1000-D1003组成的long数据double double_D1000 = melsecFx.ReadDouble( "D100" ).Content;      // 读取D1000-D1003组成的double数据string str_D1000 = melsecFx.ReadString( "D100", 10 ).Content;     // 读取D1000-D1009组成的条码数据// 读取数组short[] short_D1000_array = melsecFx.ReadInt16( "D100", 10 ).Content;         // 读取D1000的short值 ushort[] ushort_D1000_array = melsecFx.ReadUInt16( "D100", 10 ).Content;      // 读取D1000的ushort值int[] int_D1000_array = melsecFx.ReadInt32( "D100", 10 ).Content;             // 读取D1000-D1001组成的int数据uint[] uint_D1000_array = melsecFx.ReadUInt32( "D100", 10 ).Content;          // 读取D1000-D1001组成的uint数据float[] float_D1000_array = melsecFx.ReadFloat( "D100", 10 ).Content;         // 读取D1000-D1001组成的float数据long[] long_D1000_array = melsecFx.ReadInt64( "D100", 10 ).Content;           // 读取D1000-D1003组成的long数据ulong[] ulong_D1000_array = melsecFx.ReadUInt64( "D100", 10 ).Content;        // 读取D1000-D1003组成的long数据double[] double_D1000_array = melsecFx.ReadDouble( "D100", 10 ).Content;      // 读取D1000-D1003组成的double数据

  写入操作

            // 此处以D寄存器作为示例melsecFx.Write( "D100", (short)1234 );                // 写入D1000  short值  ,W3C0,R3C0 效果是一样的melsecFx.Write( "D100", (ushort)45678 );              // 写入D1000  ushort值melsecFx.Write( "D100", 1234566 );                    // 写入D1000  int值melsecFx.Write( "D100", (uint)1234566 );               // 写入D1000  uint值melsecFx.Write( "D100", 123.456f );                    // 写入D1000  float值melsecFx.Write( "D100", 123.456d );                    // 写入D1000  double值melsecFx.Write( "D100", 123456661235123534L );          // 写入D1000  long值melsecFx.Write( "D100", 523456661235123534UL );          // 写入D1000  ulong值melsecFx.Write( "D100", "K123456789" );                // 写入D1000  string值// 读取数组melsecFx.Write( "D100", new short[] { 123, 3566, -123 } );                // 写入D1000  short值  ,W3C0,R3C0 效果是一样的melsecFx.Write( "D100", new ushort[] { 12242, 42321, 12323 } );              // 写入D1000  ushort值melsecFx.Write( "D100", new int[] { 1234312312, 12312312, -1237213 } );                    // 写入D1000  int值melsecFx.Write( "D100", new uint[] { 523123212, 213, 13123 } );               // 写入D1000  uint值melsecFx.Write( "D100", new float[] { 123.456f, 35.3f, -675.2f } );                    // 写入D1000  float值melsecFx.Write( "D100", new double[] { 12343.542312d, 213123.123d, -231232.53432d } );                    // 写入D1000  double值melsecFx.Write( "D100", new long[] { 1231231242312, 34312312323214, -1283862312631823 } );          // 写入D1000  long值melsecFx.Write( "D100", new ulong[] { 1231231242312, 34312312323214, 9731283862312631823 } );          // 写入D1000  ulong值

  

读取Bool示例:

            // 以下是简单的读取,没有仔细校验的方式bool X1 = melsecFx.ReadBool( "X1" ).Content;bool[] X1_10 = melsecFx.ReadBool( "X1", 10 ).Content;// 如果需要判断是否读取成功OperateResult<bool> R_X1 = melsecFx.ReadBool( "X1" );if (R_X1.IsSuccess){// successbool value = R_X1.Content;}else{// failed}OperateResult<bool[]> R_X1_10 = melsecFx.ReadBool( "X1", 10 );if (R_X1_10.IsSuccess){// successbool x1 = R_X1_10.Content[0];bool x2 = R_X1_10.Content[1];bool x3 = R_X1_10.Content[2];bool x4 = R_X1_10.Content[3];bool x5 = R_X1_10.Content[4];bool x6 = R_X1_10.Content[5];bool x7 = R_X1_10.Content[6];bool x8 = R_X1_10.Content[7];bool x9 = R_X1_10.Content[8];bool xa = R_X1_10.Content[9];}else{// failed}

  

写入单个的bool,不支持批量写入

            // 以下是简单的写入,没有仔细校验的方式melsecFx.Write( "M100", true );// 如果需要判断是否读取成功OperateResult write1 = melsecFx.Write( "M100", true );if (write1.IsSuccess){// success}else{// failed}

  

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

转载于:https://www.cnblogs.com/dathlin/p/9536467.html

C#读写三菱Fx PLC 使用Fx 串口协议 读写Fx3U设备相关推荐

  1. 串口调试助手读写三菱fx3u数据_C#读写三菱Fx PLC 使用Fx 串口协议 读写Fx3U设备

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

  2. python三菱_python 读写三菱PLC数据,使用以太网读写Q系列,L系列,Fx系列的PLC数据...

    本文将使用一个gitHub开源的组件技术来读写三菱的plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 里面 ...

  3. rt-thread怎么使用数码管_三菱FX PLC功能指令,怎么学?

    很多小伙伴问学完编程入门后又应该学习什么内容呢?我的回答是,学完三菱编程入门后应该学习三菱FX PLC功能指令,包括功能指令的预备知识.三菱FX系列PLC的编程元件.寻址方式等,以及三菱FX PLC的 ...

  4. PLC编程安卓版 兼容三菱FX PLC编程指令 软件在线仿真 硬件PLC工控板蓝牙与手机蓝牙在线下载程序 在线仿真

    1 APP功能描述 2 APP下载与安装注册 3 APP介面操作 3.1 主介面介绍 3.2 状态栏 3.3 工件区 3.4 工具栏 3.5 转换成上位机GX Works2文件 1 APP功能描述 F ...

  5. 三菱FX PLC 数据采集 【MD8口】

    一:使用stm32f103的串口1采集三菱PLC的MD8口: 波特率设置:9600    bit 7 stop 1 偶校验: 我使用 USB转MD8(里面是RS422)调通了电脑端到FX3U的通讯. ...

  6. 通过电脑给继电器发送指令_三菱FX PLC学习之通信指令(上)

    点击上方蓝字关注我们 [免费抽奖]电气人不能错过的PLC书籍与软件! 通信指令本身不难,难的是对通信的理解.在学习PLC通信指令之前,我曾尝试去看通信相关的课程,然后告诉自己:算了,不必勉强自己,学不 ...

  7. for循环10000次花多长时间_我的三菱FX PLC学习之子程序调用与循环

    戳上方蓝字 "技成电工课堂" 关注我们哦! 上次,我们学习了程序流程转移中的条件跳转CJ,这次,我们接着向子程序调用CALL和FOR循环发起进攻吧! 显然,子程序调用CALL和FO ...

  8. fx系列微型可编程控制器 通信_电气人,三菱Q系列和FX PLC系列之间的区别你都知道吗?...

    三菱Q系列和FX系列作为三菱旗下的两大PLC系列,在日常的作业中小伙伴们都会接触到,因此本文将三菱可编程控制器中使用的内置的输入输出继电器.辅助继电器.状态.计数器.数据寄存器等各种软元件的作用和功能 ...

  9. 子程序入口参数是什么_三菱FX PLC | 什么是中断服务?没事多看几遍

    戳上方蓝字 "技成电工课堂" 关注我们哦! "前面我先是分享了PLC程序流程转移中的条件跳转CJ,然后紧接着进攻了子程序调用CALL和循环FOR,这次,我要向" ...

  10. 三菱plc与计算机无协议通讯,三菱FX系列PLC与计算机无协议通讯.doc

    三菱FX系列PLC与计算机无协议通讯 一.FX系列与计算机通信所用到的命令码: 命令命令码目标设备元件读取CMD??0X,Y,M,S,T,C,D元件写入CMD???1X,Y,M,S,T,C,D强迫ON ...

最新文章

  1. 百度万亿级图检索引擎发布!四大预训练模型开源,还“发糖”15亿元
  2. 《团队开发一(求一个数组的连续的子数组之和的最大值)》
  3. Aggregate可以做字符串累加、数值累加、最大最小值
  4. 数据结构源码笔记(C语言):二分查找
  5. MySQL使用Amoeba作为Proxy时的注意事项
  6. Go 语言范围(Range)
  7. Ubuntu 18.04下命令安装VMware Tools
  8. 2020年日历_2020年《故宫日历》发布:浓缩紫禁城600年沧桑
  9. [总结]FFMPEG视音频编解码零基础学习方法--转
  10. 剑指offer22-链表中倒数第k个结点
  11. 【OpenCV】绘制简单图形
  12. fatal error LNK1104: cannot open file 'libboost_regex-vc100-mt-gd-1_48.lib'
  13. win8.1 64位安装oracle10g客户端心得
  14. 37.go struct 结构
  15. 阿米巴经营之软件经营-写得不错留作记念
  16. c语言选猴王链表,C语言程序设计-猴子选大王[链表应用]
  17. 7-6 红包 (20 分)
  18. QT开发之老板无法拒绝的辞职信
  19. 安装caffe依赖库时,出现“您希望继续执行吗? [Y/n] y 中止。”的解决办法
  20. CSDN之每日IT冷知识答案大全

热门文章

  1. 游戏开发之拷贝构造函数,即复制构造函数(explicit关键字及拷贝构造函数的调用时机)(C++基础)
  2. Git工具项目管理的基础使用方式(GitHub同步方式)
  3. SQL语句详解(二)——select基本查询操作
  4. OSPFv3中LSA详解(五)——Intra-Area-Prefix LSA详解
  5. BGP联邦原理及配置实例
  6. springboot读取properties(yml)的几种常用方式
  7. [ CSS ] animation 快速参考
  8. sqlite3在Python2.7下对于中文路径的支持
  9. AsnycTask的内部的实现机制
  10. KMP + 求最小循环节 --- HDU 1358 Period