<.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()        

       Try
           ip = 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 If

       Catch ex As Exception

           Console.WriteLine(ex.Message)
           MsgBox(ex.Message + vbCrLf +
                  "请检查IP设置或目标PLC是否保持通讯正常?",
                  MsgBoxStyle.OkOnly, "tips!")

       End Try

   End Sub

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

2、socket接收

 Private Sub socket_client_recvievedata()  

     '定义接收区字节数组
     Dim recbyt(1024) As Byte

     '循环接收
     While True

         Try
             Dim 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)

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

             Me.Invoke(socket_invoke_1, tt1)

         Catch ex As Exception
             Exit Sub
             MsgBox(ex.Message, MsgBoxStyle.OkOnly, "tips!")

         End Try


     End While

 End 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()   

      Try

          If soc_client.Connected Then

              soc_client.Send(sendbytes_client, 200, SocketFlags.None)

          End If
      Catch ex As Exception

          MsgBox(ex.Message, MsgBoxStyle.YesNoCancel, "tips!")

      End Try

  End Sub

视频演示
待上传

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux - 多线程

1、Linux线程概念 1.1、什么是线程 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是 “一个进程内部的控制序列”一切进程至少都有一个执行线程;线程在进程内部运行,本质是在进程地址空间内运…

娃哈哈大广赛命题内容详解,优胜作品分享!

2024第16届全国大学生广告艺术大赛正在火热进行中,你参加了吗!大广赛是中国最大的高校广告创意竞赛活动。它由教育部高等教育司指导,中国传媒大学、大广赛文化传播(北京)有限公司共同举办,至今已经发布了多…

1679.K和数对的最大数目

题目:给你一个整数数组nums和一个整数k。 每一步操作中,你需要从数组中选出和为 k 的两个整数,并将他们移出数组。 返回你可以对数组执行的最大操作数。 解题思路:排序+双指针 class Solution{public int maxOperat…

第 5 章 TF坐标变换(自学二刷笔记)

重要参考: 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 5.1.6 TF坐标变换实操 需求描述: 程序启动之初:产生两只乌龟,中间的乌龟…

Docker部署系列之Docker Compose安装Redis三主三从集群

在日常开发或者编程当中,经常需要用到redis集群,若是按照传统的方式,一个机器一个机器搭建,难免过于繁琐,故而可以通过dock er-compose编排方式,快速搭建。我在搭建过程当中,将操作记录下来&…

『运维备忘录』之 iptables 防火墙使用指南

前言 iptables 是一个配置 Linux 内核防火墙的命令行工具,它是用来设置、维护和检查Linux内核的IP包过滤规则的。本文将介绍 iptables 的基础知识和使用示例。 注意:红帽/红旗/CentOS等 7 版本以上已改为使用 firewalld 作为防火墙替换iptables。 一、基…

sqllab第三关通关笔记

知识点: 通过回显的信息判断原始语句的组成猜测该语句为 select 1,2,3 from 表名 where id (输入) limit 0,1 首先通过测试判断存在什么类型的sql注入 构造id1/0 发现正常输出;说明是字符型的sql注入 好了,下面就测试有什么限制条件 构造…

4、设计模式之建造者模式

一、什么是建造者模式 建造者模式是一种创建型设计模式,也叫生成器模式。 定义:封装一个复杂对象构造过程,并允许按步骤构造。 解释:就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来…

大路灯有必要买吗?测评师推荐五大大路灯品牌!

不知道各位家长有没有发现,近几年来小小年纪就戴眼镜的孩子真的越来越多了! 根据专家数据统计,在全国青少年近视率中小学生就占其40%比重,也代表了10个学生中就有4、5个是戴眼镜的。造成这个趋势的原因也不难理解,一是…

Prometheus 安装部署

文章目录 1.部署Prometheus1.1.修改配置文件1.2.配置告警规则1.3.运行Docker 2.部署Alertmanager2.1.修改配置文件2.2.Prometheus监控配置2.3.运行Docker 3.部署Grafana3.1.运行Docker3.2. 配置数据源3.3. 配置dashboard 开源中间件 # Prometheushttps://iothub.org.cn/docs/m…

MATLAB中格式化文本处理

目录 格式化操作符的字段 转换字符 子类型 精度 字段宽度 标志 值标识符 特殊字符 设置字段宽度和精度 精度和字段宽度的格式化规则 在格式设定符外部指定字段宽度和精度 在宽度和精度字段中指定带编号的标识符 使用标识符的限制 要将数据转换为文本并控制其格式&…

【AnaConda/MiniConda/Linux】使用sudo python或切换root管理员conda环境被绕过解决方案

写在前面 部分机型修改环境变量存在风险,可能用于被覆盖而出现大量命令无法找到的情况 可以输入这个解决 export PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin往期相关内容 探索Miniconda3:简单、灵活的Python环境和…

【线代基础】张量、向量、标量、矩阵的区别

1、标量(Scalar) 纯数字,无方向性、无维度概念。因此也叫 标量张量、零维张量、0D张量 例如,x18,x21.34 x1、x2即为标量 2、张量(tensor) 具有方向性,可以理解为一个多维数组&a…

相机模型Omnidirectional Camera(全方位摄像机)

1. 背景 大多数商用相机都可以描述为针孔相机,通过透视投影进行建模。然而,有些投影系统的几何结构无法使用传统针孔模型来描述,因为成像设备引入了非常高的失真。其中一些系统就是全方位摄像机。 有几种方法可以制作全向相机。屈光照相机(D…

《手把手教你》系列技巧篇(三十二)-java+ selenium自动化测试-select 下拉框(详解教程)

1.简介 在实际自动化测试过程中,我们也避免不了会遇到下拉选择的测试,因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助。 2.select 下拉框 2.1Select类 1.在Selenium中,针对html的标签sel…

工科硕士研究生毕业论文撰写总结

工科硕士研究生毕业论文撰写总结 最近一段看了十几篇研究生毕业论文,发现不少问题。结合最近几年当评委及审论文的经验来总结下工科硕士研究生毕业论文撰写毕业论文问题与经验。 一.科技论文的总要求 论文是写给同行看的,注意读者对象。&a…

细粒度IP定位参文27(HGNN):Identifying user geolocation(2022年)

[27] F. Zhou, T. Wang, T. Zhong, and G. Trajcevski, “Identifying user geolocation with hierarchical graph neural networks and explainable fusion,” Inf. Fusion, vol. 81, pp. 1–13, 2022. (用层次图、神经网络和可解释的融合来识别用户的地理定位) 论文地址:…

十四、软考-系统架构设计师笔记-云原生架构设计理论与实践

1、云原生架构背景 云原生架构定义 从技术的角度,云原生架构是基于云原生技术的一组架构原则和设计模式的集合,旨在将云应用中的非业务代码部分进行最大化的剥离,从而让云设施接管应用中原有的大量非功能特性(如弹性、韧性、安全、可观测性、…

趣学前端 | JavaScript标准库

背景 最近睡前习惯翻会书,重温了《JavaScript权威指南》这本书。这本书,文字小,内容多。两年了,我才翻到第十章。因为书太厚,平时都充当电脑支架。 JavaScript标准库 今天阅读的章节是JavaScript标准库,…

【Kimi帮我看论文(四)】TransE:Translating Embeddings for Modeling Multi-relational Data

一、论文信息 1 标题 Translating Embeddings for Modeling Multi-relational Data 2 作者 Antoine Bordes, Nicolas Usunier, Alberto Garcia-Durn, Jason Weston, Oksana Yakhnenko 3 研究机构 Universit de Technologie de Compigne – CNRS Heudiasyc UMR 7253 Compi…