jjzjj

西门子PLC与Unity3D通讯丨PROFINET通讯

辰似五味 2023-06-07 原文

Unity3D 与西门子PLC通讯

前言

想做这样的通讯太久了,从21年二月份陆陆续续到十一月份才正式做好,最开始想西门子1200系列与unity如果可以进行通讯,那么很多实验都可以做到虚拟仿真,未来做上位机的界面也会比传统的更丰富些。如今工控行业与IT行业密不可分,相似度也越来越高,零零散散试了几个通讯方式,最后还是在老师的帮助下找到了最为妥帖的通讯方式。
本文是做实体PLC和Unity 的通讯,如果没有实体PLC可以参考我之前的博文上位机与西门子博途TIA的PROFINET通讯仿真(虚拟通讯),这篇博文写了如何对PLCsim进行配置,使用PlCsim代替实体PLC进行通讯。

特别要说明的一点是,下文所介绍的通讯方式在本人的计算机上调试成功,如果遇到特殊情况请特殊处理,欢迎大家联系我,我们一起进步学习。

通讯协议

PLC与Unity之间的通讯协议,选用的是ModbusTCP通讯,
在西门子端需要做到大致两点

  1. 将项目的通讯保护等选项勾选掉
  2. 编写一部分ModbusTCP的代码,我认为这样的目的是允许外部访问。

在Unity端是需要引入一个C#的Dll库——S7.Net,这个库是编写Winform应用的,因为都是C#写的,所以导入Unity也是可以直接使用。

通讯建立的细节

注意!!!运行博途的计算机、运行Unity的计算机、西门子PLC这三者需要在一网段,即IP地址的前三位相同。
一、西门子博途方的设置

  1. 根据S7.Net官方文档进行配置应有属性
    官方文档中提到(下面为了避免我描述的不够清楚,将原文放置下面,设置一共有三点,第一点是只有需要访问DB块是才会用到,访问M寄存器时不需要这样做。之后两点是必须要做的。)
S7 1200/1500 Notes
An external equipment can access to S71200/1500 CPU using the S7 “base” 
protocol, only working as an HMI, i.e. only basic data transfer are allowed.
All other PG operations (control/directory/etc..) must follow the extended protocol, 
not (yet) covered by Snap7.
Particularly to access a DB in S71500 some additional setting plc-side are needed.
1. Only global DBs can be accessed.
2. The optimized block access must be turned off.
3. The access level must be “full” and the “connection mechanism” must allow 
GET/PUT.
Let’s see these settings in TIA Portal V12
DB property
Select the DB in the left pane under “Program blocks” and press Alt-Enter (or in 
the contextual menu select “Properties…”)
Uncheck Optimized block access, by default it’s checked

(这里需要将要访问的数据块关闭优化块访问这个选项。)

Protection
Select the CPU project in the left pane and press Alt-Enter (or in the contextual 
menu select “Properties…”)
In the item Protection, select “Full access” and Check “Permit access with PUT/GET 
….” as in figure.

(这里有两点设置,一是将保护中的访问等级调至:Full access;二是允许PUT/GET连接)
2. 编写通讯代码
在右侧通讯-其他-ModbusTCP中选择MB_Server块

放入后进行编写即可,具体细节如下两图。(具体参数含义在此不再赘述,如有疑问请参照博途信息系统。)
二、Unity方的通讯设置

  1. 在Unity项目文件Assets文件夹下新建一个Plugins文件夹,并将S7.Net.dll及其他文件放入
    S7.net的Dll库及说明书已经上传有需要的可以自取

    这里要注意的两点是,一是我也不清楚,这个文件是否会对项目有影响,所以是一起放入的。(.meta文件是导入Unity后自动生成的,可以通过这个来确认是否能在项目中使用。)

    第二点是网上的S7.Net的库是一个文件夹,但是有三个版本的S7.Net库,只需要保存一个即可,不然Unity会识别混乱。
    当然,要是拿到的只有
    这样两个文件就没有以上需要注意的两点。
  2. 导入Dll库后就可以在项目中新建C#脚本进行代码编写了。
    下面是我的源代码,其中重要的点我会以注释的形式标出。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using S7.Net; 					 //首先一定是using
using System;
using UnityEngine.UI;
using System.Threading;

public class PLC : MonoBehaviour
{
    Plc PLC1 = new Plc(CpuType.S71200, "192.168.0.1", 0, 1);		
    //在这里对Plc这类进行新建,public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot),这个函数是对连接的Plc进行一个访问初始化
    //需要的参数有PLC类型、IP地址、插槽号、机架号。其中后两项在博途CPU属性中可以查到。

    public InputField InputIP;
    public Text InputSet;

    Thread PLCLink;

    public Text Error;

    public GameObject FluidC;
    public byte HighSet;

    public byte result;
    public double RealSet;
    public byte ReadValve;

    public ushort intValve;

    float UnityHigh;
    // Start is called before the first frame update
    void Start()
    {
    }

    public void BtnOpen()
    {
        
        try
        {
            PLC1 = new Plc(CpuType.S71200, InputIP.text, 0, 1);  //这里的是做了一个外部设置IP地址的操作
            PLC1.Open();
            //打开与PLC的连接是有两种方式,一个是Open();另一个是OpenAsync(),两者之间的功能是一样的,前者可以返回错误信息,比较适合初学者。

            if (PLC1.IsConnected)   //判断是否连接
            {

                Debug.Log("Plc is Connected");
                Error.text = "Plc is Connected";

                PLCLink = new Thread(LinkThread);
                PLCLink.Start();                    //这里我是想做一个阶段性的中断,所以选用另起线程,将查询和写入PLC的功能放入新的线程,数据处理在主线程。用来防止线程卡死。
            }
            else
            {
                Error.text = "PLC 连接不成功,请检查IP地址、机架、插槽等是否正确";
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }

    public void BtnClose()
    {
        try
        {
            PLC1.Close();     //关闭与PLC的连接
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }

    public void BtnRead()
    {
        //复位按键
        try
        {
            PLC1.Write("M0.0", true);  //我做的是Unity上的仿真PID所以需要一个复位按键。
            PLC1.Write("M0.0", false);
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }
    
    public void LinkThread()
    {
        while (true)
        {
            if (PLC1.IsConnected)
            {
                RealSet = Convert.ToDouble(PLC1.Read("DB3.DBD0"));  
                //读取PLC的值,这边我还没有做的很满意,大家可以根据S7.Net的说明书和自己的意图来写合适的代码
                result = (byte)PLC1.Read("MB103");
                intValve = (ushort)PLC1.Read("DB3.DBW12");
                Debug.Log(intValve);
                Thread.Sleep(100);
            }
        }
    }

    private void OnApplicationQuit()
    {
        BtnClose();
    }

    // Update is called once per frame
    void Update()
    {
        UnityHigh = FluidC.GetComponent<FluidControl>().OutPutHigh;
        InputSet.text = result + "";
    }
}

到这里,双方通讯已经完成,剩下的就是数据处理。等下次做的满意后,单写一篇文章给大家看。

期间遇到的两个主要问题

  1. S7.Net.PlcException: 无法将数据写入传输连接: 远程主机强迫关闭了一个现有的连接。

  2. 索引超出数组界限。
    我的这两个问题都是发生在连接成功后无法进行读取和写入操作。
    大致总结了一下检查步骤

  3. Ping一下PLC的IP地址,ping不通的话有很多种可能,不在同一网段、PLC没有正确设置对外部访问还有保护(请参照 一、西门子博途方的设置)等。

  4. 如果可以Ping的通,请检查一下PLC的通讯代码是否有错。一般第一个问题会出现在这里。

  5. 第二个问题,有可能是访问的块不存在或者是地址没定义数。

总结

这篇仅写了我一家之言,问题遇到的不算多,所以不会是最全面的,希望大家遇到的稀奇古怪问题可以找我一起讨论。

有关西门子PLC与Unity3D通讯丨PROFINET通讯的更多相关文章

  1. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  2. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  3. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  4. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  5. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  6. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  7. python - Ruby 或 Python 的 3d 游戏引擎? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion是否有适用于这些的3d游戏引擎?

  8. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  9. 三分钟集成 TapTap 防沉迷 SDK(Unity 版) - 2

    三分钟集成Tap防沉迷SDK(Unity版)一、SDK介绍基于国家对上线所有游戏必须增加防沉迷功能的政策下,TapTap推出防沉迷SDK,供游戏开发者进行接入;允许未成年用户在周五、六、日以及法定节假日晚上8:00-9:00进行游戏,防沉谜时间段进入游戏会弹窗进行提示!开发环境要求:Unity2019.4或更高版本iOS10或更高版本Android5.0(APIlevel21)或更高版本🔗Unity集成Demo参考链接🔗UnityTapSDK功能体验APK下载链接二、集成前准备1.创建应用进入开发者后台,按照提示开始创建应用;2.开通服务在使用TDS实名认证和防沉迷服务之前,需要在上面创建的应

  10. 【Unity大气散射】GAMES104:3A中如何实现大气散射 - 2

    写在前面前两天学习并整理的大气散射基础知识:【Unity大气渲染】关于单次大气散射的理论知识,收获了很多,但不得不承认的是,这其实已经是最早的、90年代的非常古老的方法了,后来也出现了一些优化性的计算思路和方法。因此,我打算先不急着跟各种教程在Unity中实现大气散射,而是再花时间来看看最近的游戏是如何去实现大气渲染的:06.游戏中地形大气和云的渲染(下)|GAMES104-现代游戏引擎:从入门到实践接下来就跟着GAMES104讲地形大气和云渲染的部分学习并做简单的记录,涉及到之前没提到的Mie散射也只选择直接截图PPT的方式记录啦!毕竟对于做作品来说,之后实现出来才是重要的~当然,May佬的

随机推荐