<.Net>VisaulStudio2022下用VB.net实现socket与汇川PLC进行通讯案例(Eazy521)

前言
此前,我写过一个VB.net环境下与西门子PLC通讯案例的博文:
VisaulStudio2022下用VB.net实现socket与西门子PLC进行通讯案例(优化版)
最近项目上会用到汇川PLC比较多,正好有个项目有上位机通讯需求,于是就自己这边先测试了一下汇川PLC和上位机通过socket进行数据通讯。

配置:
平台:windows
工具:visual studio 2022
语言:VB.net
通讯协议:socket
PLC型号:汇川Eazy521系列
固件版本:6.1.2.0
PLC软件:汇川Autoshop V4.8.2.4

其实,与PLC进行通讯来说,上位机侧的程序几乎不用改变,主要是PLC端的使用有些不同,像西门子、信捷的PLC,在进行socket通讯时,虽然使用协议都是一样的,但不同厂家,其编程指令和PLC程序写出来是不一致的,其中还涉及数据类型的转换。

本篇将侧重于介绍汇川PLC这边的设置及编程,上位机将在之前的基础上稍作修改。

一、PLC侧设置

汇川PLC进行socket协议通讯的指令,在它的工具箱-通讯指令-以太网指令下:
在这里插入图片描述
大致介绍下指令:
1、TCP_listen:PLC作为服务器端时,监听客户端指令
2、TCP_accept:PLC作为服务器端时,在开启了监听模式后,用于监测客户端的连接指令。如果检测到有客户端请求连接,则会产生一个connected_socket,并存储在队列里,这个connected_socket就是客户端的请求,后面的收发数据,都用它进行。
3、TCP_connect:PLC作为客户端时,与服务器连接的指令。
4、TCP_receive:当连接成功建立后,使用此指令从远程设备接收数据。
5、TCP_send:同上,发送数据。
6、TCP_close:用于关闭监听或者连接。

下面,以PLC作为服务器端为例,来说明一下指令具体如何使用:

1、TCP_listen:

在这里插入图片描述
如上图,这个指令的触发位Execute,其实使用上升沿脉冲即可,当触发后,Active位会变成ON。
其中,左侧的socket接口,根据汇川官方文档,是应该填写sSocekt数据类型的,详细如下:
在这里插入图片描述
但是目前Autoshop软件中目前还不支持自定义这种数据类型,所以要用INT[20]数组来代替,实例中如下:
在这里插入图片描述
port接口是填写本地端口后,可以直接填写常数,如2000,在PLC中表示为K2000,即十进制2000。也可以使用变量,只要将数据类型设置为DINT即可。但官方文档有提示,尽量不要使用特殊端口号,如502。
至于右侧的其他状态位如buzyerrorerrorid,只要监控指令运行状态的,按照数据类型,分配个变量就行了,后面的其他指令,都会有这些变量,就不再多做说明。

2、TCP_accept:

在这里插入图片描述
当监听开启后,就需要用accept来监测客户端的连接请求。
如上图,这个指令左侧有一个ListeningSocket参数,这里填写和TCP_listen指令一样的数据即可。
其右侧有一个Connected位,如果客户端发起了连接请求,且无故障,那么这个位将会变为ON。同时,右侧还有一个Connected_socket参数,这个参数也是sSocket类型,此处也是用INT[20]数组来代替。但要注意,这个和TCP_listen不能是同一个,这个相当于是服务器端监听到了客户端,产生的客户端反馈。
accept指令可以多次使用,以接收多个客户端的连接。本例只按照一个客户端连说明。

3、TCP_receive:

在这里插入图片描述
此指令用于接收远程设备(本例中就是客户端)发送的数据,其左侧接口有一个Socket参数,此处填写前面accept指令右侧的Connected_socket一样的数据即可。
接着是Buffer,即数据接收过来,存放在哪里?
你可以自己新建一个buffer区,buffer区是一个连续数组,汇川PLC支持两种数据类型:
INT[0…n]或者Byte[0…n],使用哪种看自己需要,一般常用byte即可。
接下来是Size参数,因为我们不一定需要所有发送过来的数据,所以可设置接收数据长度,但要注意,Size的值不能超过buffer区的大小。
右侧参数,done代表指令接收完成,可以使用这个状态位来编写一些逻辑程序,如数据传送等。
还有一个ReceivedSize参数,表示实际接收的数据长度,虽然设置了数据接收长度,但发过来的数据可能小于设置值,比如设置了10字节,但发送过来的只有2个字节,这个长度就是实际长度,会显示在ReceivedSize中。

4、TCP_send:

在这里插入图片描述
此指令用于发送数据,与TCP_receive指令类似,其左侧的Socket参数,填写accept指令右侧的Connected_socket一样的参数。
buffer填写自定义的发送数据缓冲区,Size为发送长度,右侧的sentsize标识实际发送的数据长度。

5、TCP_close:

在这里插入图片描述
关闭指令非常简单,用于关闭socket连接,但要注意,本例是将PLC作为服务器端,所以关闭连接时,除了要关闭服务器的监听socket,还需要关闭客户端的请求socket(假如已成功建立连接)。

以上就是汇川PLC端的程序编写,汇川的官方文档也给了示例,但实际使用时,会涉及数据转换问题,这里提一个注意点:
我这边使用时,需要在PLC这边将浮点数(32位)发送到上位机,但我们在前面说了,TCP_send的buffer区只能是Byte[]或者INT[]这两种,所以,就需要将浮点数先转为整数类型或者字节类型。
但是,如果你直接使用汇川的INT或者DINT这个指令,它会将浮点数转换为四舍五入后的整数,并不是真正的无损转换。
我在指令文档找了半天,才发现汇川要实现将浮点数完全转换为字节,需要使用MCPY这个指令。
官方解释:

该指令是较为高阶的应用,需谨慎使用!
该指令是数据复制操作,数据本身无变化,可以实现内存复制拷贝;如果使用巧妙,可以实现类型变换的操
作。
n是待复制的数据的长度,以字节为单位,比如,两个16位数据赋值给一个32位数据,n=4;把两个32位整
数,复制给同样大小的结构体或16位整数数组,n=8;
当操作数S或D为位元件时,位元件的地址必须按字节对齐,否则会发生寻址错误;例如,MCPY M1 M15
K1,会报“无效变量地址,访问的变量不存在”错误。

实际应用:
在这里插入图片描述
这样转换后的数据,在通过socket发送到上位机后,上位机端使用字节转浮点指令,如python中可以使用:

data_float=struct.unpack('f',datarecv[0:4])[0] 

转换后和PLC发送的数据是一致的。

二、上位机侧程序

在这里插入图片描述
上位机侧采用的是VB.net语言编写,其中socket通讯方面使用的是System.Net.Sockets库,直接导入即可:

Imports System.Net.Sockets  

说一下几个关键步骤:
1、socket连接

   Private Sub socket_client_connect()        Tryip = IPAddress.Parse(TextBox1.Text)port = Integer.Parse(TextBox2.Text)ipe = New IPEndPoint(ip, port)soc_client.Connect(ipe)Console.WriteLine("connect ok")If soc_client.Connected Then'如果连接成功,状态变为绿色huayuan(PictureBox1, Color.LimeGreen)'如果连接成功,则启动数据接收,为了防止阻塞线程,采用新线程Dim th1 As New Thread(AddressOf socket_client_recvievedata)  '多线程th1.Start()                               '线程启动,防止socket阻塞End IfCatch ex As ExceptionConsole.WriteLine(ex.Message)MsgBox(ex.Message + vbCrLf +"请检查IP设置或目标PLC是否保持通讯正常?",MsgBoxStyle.OkOnly, "tips!")End TryEnd Sub

使用socket.connect()函数向服务器发送连接请求,可以使用socket.connected状态位来判断连接是否成功。

2、socket接收

 Private Sub socket_client_recvievedata()  '定义接收区字节数组Dim recbyt(1024) As Byte'循环接收While TrueTryDim reclength = soc_client.Receive(recbyt, 200, SocketFlags.None)'recvdata = Encoding.GetEncoding("gb2312").GetString(recbyt)Dim tt1 As Test_data'recvdata = Encoding.ASCII.GetString(recbyt, 0, 30)'以下是对所接收的所有数据进行解析,可以根据实际情况变化'下面的仅作为参考'ax1.axis_status = BitConverter.ToInt16(recbyt, 0)'ax1.axis_xunhuanmoshi = BitConverter.ToInt16(recbyt, 2)'ax1.axis_runing = BitConverter.ToInt16(recbyt, 4)'ax1.axis_error = BitConverter.ToInt16(recbyt, 6)Console.WriteLine(reclength.ToString())'tt1.test1 = Encoding.GetEncoding("utf-8").GetString(recbyt)'tt1.test2 = Encoding.GetEncoding("utf-8").GetString(recbyt)tt1.temp_float1 = BitConverter.ToSingle(recbyt, 0)'Console.WriteLine(recdata1)'将解析的数据通过委托的方式传递给主线程,以更新主线程的UIDim socket_invoke_1 As New socket_invoke(AddressOf socket_recv_data_invoke)Me.Invoke(socket_invoke_1, tt1)Catch ex As ExceptionExit SubMsgBox(ex.Message, MsgBoxStyle.OkOnly, "tips!")End TryEnd WhileEnd Sub

接收数据使用socket.receive(),为了循环接收,可以使用while指令,但是如果直接使用,会阻塞主线程即UI,所以最好在新线程中使用。注意上述代码中的后面几行:

'将解析的数据通过委托的方式传递给主线程,以更新主线程的UI
Dim socket_invoke_1 As New socket_invoke(AddressOf socket_recv_data_invoke) Me.Invoke(socket_invoke_1, tt1)

此处采用的是.Net中的委托,即为了不阻塞主线程,我们采用委托的形式,将socket循环接收的数据发送给UI,这样既可以传送数据,又不会阻塞线程。

3、socket发送数据
发送数据则非常简单,使用socket.send()即可。

  Private Sub socket_client_senddata()   TryIf soc_client.Connected Thensoc_client.Send(sendbytes_client, 200, SocketFlags.None)End IfCatch ex As ExceptionMsgBox(ex.Message, MsgBoxStyle.YesNoCancel, "tips!")End TryEnd Sub

视频演示

汇川PLC与上位机通讯演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InnoDB对MVCC的实现

MVCC是啥? (Multiversion Concurrency Control) 多版本并发控制 是个方法,是个思想。 解决多并发事务操作同一数据库数据,数据保持一致的问题。 怎么做:每个数据行上维护多个版本 当一个事务要对数据进行修改,为该事…

mysql转达梦的python脚本

mysql_ddl: CREATE TABLE ops_app_import (id char(32) NOT NULL COMMENT 主键ID,pkg_name varchar(255) NOT NULL DEFAULT COMMENT 导入包名称,pkg_md5 varchar(32) NOT NULL COMMENT 导入包md5值,backup_pkg_name varchar(255) DEFAULT COMMENT 备份包名称,bac…

[剪藏] - 由哇哈哈和农夫山泉所想到的

哇哈哈和农夫山泉的缠斗最近冒出来一个有趣的点:营销大于内容的胜利。 具体来说是这样的:农夫山泉很多年前做广告,说纯净水没有矿物质,长期喝是不利于人体健康的。农夫还做了个营销的对比实验,大概是用矿泉水养水仙花&…

龙芯杯赛道-学习过程记录

Preface&免责声明: 由于参赛资料企业并未开源,所以我不能开放出有关参赛的资料 但是我会在这里记录参赛时看不懂的一系列知识补充 ------------------------------------------------------------------------------------------------------- TSEN…

音视频开发之旅(75)- AI数字人进阶--GeneFace++

目录 1.效果展示和玩法场景 2.GeneFace原理学习 3.数据集准备以及训练的过程 5.遇到的问题与解决方案 6.参考资料 一、效果展示 AI数字人进阶--GeneFace(1) AI数字人进阶--GeneFace(2) 想象一下,一个专为你打造的…

前端算法 - 查找

1 二分查找 /*** param {number[]} nums* param {number} target* return {number}*/ var search function (nums, target) {let left 0, right nums.length - 1while (left < right) {let mid Math.floor((left right) / 2)if (target < nums[mid]) {right mid -…

为什么 VSCode 不用 Qt 而要用 Electron?

为什么 VSCode 不用 Qt 而要用 Electron? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&am…

Python基础课堂最后一课23——正则对象

文章目录 前言一、正则对象是什么&#xff1f;二、正则表达式基本分类1.普通字符2.元字符 总结 前言 很开心能和你们一些学习进步&#xff0c;在这一个多月的时间中&#xff0c;是你们让我坚持了下来&#xff0c;完成了python基础课堂编写&#xff0c;不管如何&#xff0c;我们…

C语言学习(第二十课)初识函数5(函数递归2)

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> //编写函数&#xff0c;不允许创建临时变量&#xff0c;求字符串长度 ///1、可以使用临时变量的写法&#xff1a; //int my_strlen(char* str) //{ // int count 0; // while (*s…

安卓Java面试题 121- 130

131. Android垃圾回收机制和程序优化System.gc( ) ?垃圾收集算法的核心思想:对虚拟机的可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,则称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。 JVM进行次GC的频率很高…

Linux系统——Nginx脚本拦截拓展

可能会有些无聊的人对服务器的Nginx服务进行恶意访问网站、API接口&#xff0c;会影响到用户的体验&#xff0c;我们可以做一个简单的脚本对恶意访问的IP做一个有效的拦截&#xff0c;揪出这些IP地址&#xff0c;然后将其进行禁用。 在Nginx的conf目录下新建一个blockip.conf文…

Python(C_Cpp)分析模拟Arduino和Raspberry Pi(单板机)CAN总线和车载单元测试

要点 CAN总线释义&#xff1a;物理层结构&#xff0c;数据帧&#xff0c;数据交换&#xff0c;总线接口物理模块。一对Arduino CAN &#xff08;Arduino C 处理&#xff09;总线项目&#xff1a; 发送端发送随机数据&#xff0c;接收端接收并计算。发送端点动信号&#xff0c;…

certificate has expired or is not yet valid:npm和node证书过期问题

在 1 月 22 日&#xff0c;淘宝原镜像域名&#xff08;registry.npm.taobao.org&#xff09;的 HTTPS 证书正式到期。如果想要继续使用&#xff0c;需要将 npm 源切换到新的源&#xff08;registry.npmmirror.com&#xff09;&#xff0c;否则会报错。 解决方案切换到新的源&a…

HTML表单

本文章属于学习笔记&#xff0c;在https://www.freecodecamp.org/chinese/learn/2022/responsive-web-design/中练习 四、HTML表单 CSS 1、vh单位表示视口高度&#xff0c;等于视口高度的1%。这使得它相对于视口高度。height:100vh; 2、设置 body 的默认 margin 为 0 来重置…

【掌握版本控制:Git 入门与实践指南】远程操作|标签管理

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;泥中に咲く—ウォルピスカーター 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶…

汽车IVI中控开发入门及进阶(十三):语音识别

前言: IVI中控上的语音识别,在目前市场上也是非常显眼的一个创新,大幅改变了传统IVI的操作习惯。 语音识别Speech recognition,也称为自动语音识别(ASR)、计算机语音识别或语音到文本,是一种使程序能够将人类语音处理成书面格式的能力。 语音识别Speech recognition是计…

数码管的静态显示(二)

1.原理 要按照上图的顺序传递位选和段选的数据。 因为q0是最高位&#xff0c;共阳极数码管结构是dp....a&#xff0c;所以应该先传入低位a&#xff0c;而a在上图中的8段2进制编码中是seg[7]&#xff0c;所以段选信号的顺序是seg[0],...seg[7]。 因为输出信号是两个时钟&#x…

Docker入门笔记(1)

Docker入门笔记&#xff08;1&#xff09; 容器技术入门 之前我的WIT问卷管理系统在阿里云上部署需要好多配置&#xff0c;各个环境耦合的比较紧密&#xff0c;花了不少时间去做部署和调配。 现在有了Docker以后&#xff0c;我们可以把各种组件配置好&#xff0c;然后打包成…

使用ScottPlot库在.NET WinForms中快速实现大型数据集的交互式显示

前言 在.NET应用开发中数据集的交互式显示是一个非常常见的功能&#xff0c;如需要创建折线图、柱状图、饼图、散点图等不同类型的图表将数据呈现出来&#xff0c;帮助人们更好地理解数据、发现规律&#xff0c;并支持决策和沟通。本文我们将一起来学习一下如何使用ScottPlot库…

C语言snprintf():将格式化字符串输出到数组中

snprintf() 是 C语言的一个标准库函数&#xff0c;定义在<stdio.h>头文件中。 snprintf() 函数的功能是格式化字符串&#xff0c;并将结果存储在指定的字符数组中。该函数的原型如下&#xff1a; int snprintf(char *str, size_t size, const char *format[,argument...…